diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp index 12795f0468fd..23765da1b46f 100644 --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp @@ -230,7 +230,7 @@ void ExpandModularHeadersPPCallbacks::HasInclude(SourceLocation Loc, StringRef, void ExpandModularHeadersPPCallbacks::PragmaOpenCLExtension( SourceLocation NameLoc, const IdentifierInfo *, SourceLocation StateLoc, unsigned) { - // FIME: Figure out whether it's the right location to parse to. + // FIXME: Figure out whether it's the right location to parse to. parseToLocation(NameLoc); } void ExpandModularHeadersPPCallbacks::PragmaWarning(SourceLocation Loc, @@ -256,7 +256,7 @@ void ExpandModularHeadersPPCallbacks::MacroExpands(const Token &MacroNameTok, const MacroDefinition &, SourceRange Range, const MacroArgs *) { - // FIME: Figure out whether it's the right location to parse to. + // FIXME: Figure out whether it's the right location to parse to. parseToLocation(Range.getBegin()); } void ExpandModularHeadersPPCallbacks::MacroDefined(const Token &MacroNameTok, @@ -271,12 +271,12 @@ void ExpandModularHeadersPPCallbacks::MacroUndefined( void ExpandModularHeadersPPCallbacks::Defined(const Token &MacroNameTok, const MacroDefinition &, SourceRange Range) { - // FIME: Figure out whether it's the right location to parse to. + // FIXME: Figure out whether it's the right location to parse to. parseToLocation(Range.getBegin()); } void ExpandModularHeadersPPCallbacks::SourceRangeSkipped( SourceRange Range, SourceLocation EndifLoc) { - // FIME: Figure out whether it's the right location to parse to. + // FIXME: Figure out whether it's the right location to parse to. parseToLocation(EndifLoc); } void ExpandModularHeadersPPCallbacks::If(SourceLocation Loc, SourceRange, diff --git a/clang-tools-extra/clang-tidy/GlobList.cpp b/clang-tools-extra/clang-tidy/GlobList.cpp index 43945fcdc074..863bb4672852 100644 --- a/clang-tools-extra/clang-tidy/GlobList.cpp +++ b/clang-tools-extra/clang-tidy/GlobList.cpp @@ -15,7 +15,7 @@ using namespace tidy; // Returns true if GlobList starts with the negative indicator ('-'), removes it // from the GlobList. static bool consumeNegativeIndicator(StringRef &GlobList) { - GlobList = GlobList.trim(" \r\n"); + GlobList = GlobList.trim(); if (GlobList.startswith("-")) { GlobList = GlobList.substr(1); return true; @@ -27,7 +27,7 @@ static bool consumeNegativeIndicator(StringRef &GlobList) { // removes it and the trailing comma from the GlobList. static llvm::Regex consumeGlob(StringRef &GlobList) { StringRef UntrimmedGlob = GlobList.substr(0, GlobList.find(',')); - StringRef Glob = UntrimmedGlob.trim(' '); + StringRef Glob = UntrimmedGlob.trim(); GlobList = GlobList.substr(UntrimmedGlob.size() + 1); SmallString<128> RegexText("^"); StringRef MetaChars("()^$|*+?.[]\\{}"); diff --git a/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp b/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp index a328f05da5d0..a6c29e03f7aa 100644 --- a/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp @@ -12,6 +12,7 @@ #include "KernelNameRestrictionCheck.h" #include "SingleWorkItemBarrierCheck.h" #include "StructPackAlignCheck.h" +#include "UnrollLoopsCheck.h" using namespace clang::ast_matchers; @@ -28,6 +29,7 @@ class AlteraModule : public ClangTidyModule { "altera-single-work-item-barrier"); CheckFactories.registerCheck( "altera-struct-pack-align"); + CheckFactories.registerCheck("altera-unroll-loops"); } }; diff --git a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt index 0765b9735cf9..c8a883d0750c 100644 --- a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt @@ -8,6 +8,7 @@ add_clang_library(clangTidyAlteraModule KernelNameRestrictionCheck.cpp SingleWorkItemBarrierCheck.cpp StructPackAlignCheck.cpp + UnrollLoopsCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp new file mode 100644 index 000000000000..40ba3913467f --- /dev/null +++ b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp @@ -0,0 +1,277 @@ +//===--- UnrollLoopsCheck.cpp - clang-tidy --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "UnrollLoopsCheck.h" +#include "clang/AST/APValue.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/OperationKinds.h" +#include "clang/AST/ParentMapContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace altera { + +UnrollLoopsCheck::UnrollLoopsCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + MaxLoopIterations(Options.get("MaxLoopIterations", 100U)) {} + +void UnrollLoopsCheck::registerMatchers(MatchFinder *Finder) { + const auto HasLoopBound = hasDescendant( + varDecl(allOf(matchesName("__end*"), + hasDescendant(integerLiteral().bind("cxx_loop_bound"))))); + const auto CXXForRangeLoop = + cxxForRangeStmt(anyOf(HasLoopBound, unless(HasLoopBound))); + const auto AnyLoop = anyOf(forStmt(), whileStmt(), doStmt(), CXXForRangeLoop); + Finder->addMatcher( + stmt(allOf(AnyLoop, unless(hasDescendant(stmt(AnyLoop))))).bind("loop"), + this); +} + +void UnrollLoopsCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Loop = Result.Nodes.getNodeAs("loop"); + const auto *CXXLoopBound = + Result.Nodes.getNodeAs("cxx_loop_bound"); + const ASTContext *Context = Result.Context; + switch (unrollType(Loop, Result.Context)) { + case NotUnrolled: + diag(Loop->getBeginLoc(), + "kernel performance could be improved by unrolling this loop with a " + "'#pragma unroll' directive"); + break; + case PartiallyUnrolled: + // Loop already partially unrolled, do nothing. + break; + case FullyUnrolled: + if (hasKnownBounds(Loop, CXXLoopBound, Context)) { + if (hasLargeNumIterations(Loop, CXXLoopBound, Context)) { + diag(Loop->getBeginLoc(), + "loop likely has a large number of iterations and thus " + "cannot be fully unrolled; to partially unroll this loop, use " + "the '#pragma unroll ' directive"); + return; + } + return; + } + if (isa(Loop)) { + diag(Loop->getBeginLoc(), + "full unrolling requested, but loop bounds may not be known; to " + "partially unroll this loop, use the '#pragma unroll ' " + "directive", + DiagnosticIDs::Note); + break; + } + diag(Loop->getBeginLoc(), + "full unrolling requested, but loop bounds are not known; to " + "partially unroll this loop, use the '#pragma unroll ' " + "directive"); + break; + } +} + +enum UnrollLoopsCheck::UnrollType +UnrollLoopsCheck::unrollType(const Stmt *Statement, ASTContext *Context) { + const DynTypedNodeList Parents = Context->getParents(*Statement); + for (const DynTypedNode &Parent : Parents) { + const auto *ParentStmt = Parent.get(); + if (!ParentStmt) + continue; + for (const Attr *Attribute : ParentStmt->getAttrs()) { + const auto *LoopHint = dyn_cast(Attribute); + if (!LoopHint) + continue; + switch (LoopHint->getState()) { + case LoopHintAttr::Numeric: + return PartiallyUnrolled; + case LoopHintAttr::Disable: + return NotUnrolled; + case LoopHintAttr::Full: + return FullyUnrolled; + case LoopHintAttr::Enable: + return FullyUnrolled; + case LoopHintAttr::AssumeSafety: + return NotUnrolled; + case LoopHintAttr::FixedWidth: + return NotUnrolled; + case LoopHintAttr::ScalableWidth: + return NotUnrolled; + } + } + } + return NotUnrolled; +} + +bool UnrollLoopsCheck::hasKnownBounds(const Stmt *Statement, + const IntegerLiteral *CXXLoopBound, + const ASTContext *Context) { + if (isa(Statement)) + return CXXLoopBound != nullptr; + // Too many possibilities in a while statement, so always recommend partial + // unrolling for these. + if (isa(Statement)) + return false; + // The last loop type is a for loop. + const auto *ForLoop = dyn_cast(Statement); + if (!ForLoop) + llvm_unreachable("Unknown loop"); + const Stmt *Initializer = ForLoop->getInit(); + const Expr *Conditional = ForLoop->getCond(); + const Expr *Increment = ForLoop->getInc(); + if (!Initializer || !Conditional || !Increment) + return false; + // If the loop variable value isn't known, loop bounds are unknown. + if (const auto *InitDeclStatement = dyn_cast(Initializer)) { + if (const auto *VariableDecl = + dyn_cast(InitDeclStatement->getSingleDecl())) { + APValue *Evaluation = VariableDecl->evaluateValue(); + if (!Evaluation || !Evaluation->hasValue()) + return false; + } + } + // If increment is unary and not one of ++ and --, loop bounds are unknown. + if (const auto *Op = dyn_cast(Increment)) + if (!Op->isIncrementDecrementOp()) + return false; + + if (isa(Conditional)) { + const auto *BinaryOp = dyn_cast(Conditional); + const Expr *LHS = BinaryOp->getLHS(); + const Expr *RHS = BinaryOp->getRHS(); + // If both sides are value dependent or constant, loop bounds are unknown. + return LHS->isEvaluatable(*Context) != RHS->isEvaluatable(*Context); + } + return false; // If it's not a binary operator, loop bounds are unknown. +} + +const Expr *UnrollLoopsCheck::getCondExpr(const Stmt *Statement) { + if (const auto *ForLoop = dyn_cast(Statement)) + return ForLoop->getCond(); + if (const auto *WhileLoop = dyn_cast(Statement)) + return WhileLoop->getCond(); + if (const auto *DoWhileLoop = dyn_cast(Statement)) + return DoWhileLoop->getCond(); + if (const auto *CXXRangeLoop = dyn_cast(Statement)) + return CXXRangeLoop->getCond(); + llvm_unreachable("Unknown loop"); +} + +bool UnrollLoopsCheck::hasLargeNumIterations(const Stmt *Statement, + const IntegerLiteral *CXXLoopBound, + const ASTContext *Context) { + // Because hasKnownBounds is called before this, if this is true, then + // CXXLoopBound is also matched. + if (isa(Statement)) { + assert(CXXLoopBound && "CXX ranged for loop has no loop bound"); + return exprHasLargeNumIterations(CXXLoopBound, Context); + } + const auto *ForLoop = dyn_cast(Statement); + assert(ForLoop && "Unknown loop"); + const Stmt *Initializer = ForLoop->getInit(); + const Expr *Conditional = ForLoop->getCond(); + const Expr *Increment = ForLoop->getInc(); + int InitValue; + // If the loop variable value isn't known, we can't know the loop bounds. + if (const auto *InitDeclStatement = dyn_cast(Initializer)) { + if (const auto *VariableDecl = + dyn_cast(InitDeclStatement->getSingleDecl())) { + APValue *Evaluation = VariableDecl->evaluateValue(); + if (!Evaluation || !Evaluation->isInt()) + return true; + InitValue = Evaluation->getInt().getExtValue(); + } + } + assert(isa(Conditional) && + "Conditional is not a binary operator"); + int EndValue; + const auto *BinaryOp = dyn_cast(Conditional); + if (!extractValue(EndValue, BinaryOp, Context)) + return true; + + double Iterations; + + // If increment is unary and not one of ++, --, we can't know the loop bounds. + if (const auto *Op = dyn_cast(Increment)) { + if (Op->isIncrementOp()) + Iterations = EndValue - InitValue; + else if (Op->isDecrementOp()) + Iterations = InitValue - EndValue; + else + llvm_unreachable("Unary operator neither increment nor decrement"); + } + + // If increment is binary and not one of +, -, *, /, we can't know the loop + // bounds. + if (const auto *Op = dyn_cast(Increment)) { + int ConstantValue; + if (!extractValue(ConstantValue, Op, Context)) + return true; + switch (Op->getOpcode()) { + case (BO_AddAssign): + Iterations = ceil(float(EndValue - InitValue) / ConstantValue); + break; + case (BO_SubAssign): + Iterations = ceil(float(InitValue - EndValue) / ConstantValue); + break; + case (BO_MulAssign): + Iterations = 1 + (log(EndValue) - log(InitValue)) / log(ConstantValue); + break; + case (BO_DivAssign): + Iterations = 1 + (log(InitValue) - log(EndValue)) / log(ConstantValue); + break; + default: + // All other operators are not handled; assume large bounds. + return true; + } + } + return Iterations > MaxLoopIterations; +} + +bool UnrollLoopsCheck::extractValue(int &Value, const BinaryOperator *Op, + const ASTContext *Context) { + const Expr *LHS = Op->getLHS(); + const Expr *RHS = Op->getRHS(); + Expr::EvalResult Result; + if (LHS->isEvaluatable(*Context)) + LHS->EvaluateAsRValue(Result, *Context); + else if (RHS->isEvaluatable(*Context)) + RHS->EvaluateAsRValue(Result, *Context); + else + return false; // Cannot evalue either side. + if (!Result.Val.isInt()) + return false; // Cannot check number of iterations, return false to be + // safe. + Value = Result.Val.getInt().getExtValue(); + return true; +} + +bool UnrollLoopsCheck::exprHasLargeNumIterations(const Expr *Expression, + const ASTContext *Context) { + Expr::EvalResult Result; + if (Expression->EvaluateAsRValue(Result, *Context)) { + if (!Result.Val.isInt()) + return false; // Cannot check number of iterations, return false to be + // safe. + // The following assumes values go from 0 to Val in increments of 1. + return Result.Val.getInt() > MaxLoopIterations; + } + // Cannot evaluate Expression as an r-value, so cannot check number of + // iterations. + return false; +} + +void UnrollLoopsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "MaxLoopIterations", MaxLoopIterations); +} + +} // namespace altera +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h new file mode 100644 index 000000000000..8a63e9173e0a --- /dev/null +++ b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h @@ -0,0 +1,78 @@ +//===--- UnrollLoopsCheck.h - clang-tidy ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_UNROLLLOOPSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_UNROLLLOOPSCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang { +namespace tidy { +namespace altera { + +/// Finds inner loops that have not been unrolled, as well as fully unrolled +/// loops with unknown loop bounds or a large number of iterations. +/// +/// Unrolling inner loops could improve the performance of OpenCL kernels. +/// However, if they have unknown loop bounds or a large number of iterations, +/// they cannot be fully unrolled, and should be partially unrolled. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/altera-unroll-loops.html +class UnrollLoopsCheck : public ClangTidyCheck { +public: + UnrollLoopsCheck(StringRef Name, ClangTidyContext *Context); + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + /// Recommend partial unrolling if number of loop iterations is greater than + /// MaxLoopIterations. + const unsigned MaxLoopIterations; + /// The kind of unrolling, if any, applied to a given loop. + enum UnrollType { + // This loop has no #pragma unroll directive associated with it. + NotUnrolled, + // This loop has a #pragma unroll directive associated with it. + FullyUnrolled, + // This loop has a #pragma unroll directive associated with it. + PartiallyUnrolled + }; + /// Attempts to extract an integer value from either side of the + /// BinaryOperator. Returns true and saves the result to &value if successful, + /// returns false otherwise. + bool extractValue(int &Value, const BinaryOperator *Op, + const ASTContext *Context); + /// Returns true if the given loop statement has a large number of iterations, + /// as determined by the integer value in the loop's condition expression, + /// if one exists. + bool hasLargeNumIterations(const Stmt *Statement, + const IntegerLiteral *CXXLoopBound, + const ASTContext *Context); + /// Checks one hand side of the binary operator to ascertain if the upper + /// bound on the number of loops is greater than max_loop_iterations or not. + /// If the expression is not evaluatable or not an integer, returns false. + bool exprHasLargeNumIterations(const Expr *Expression, + const ASTContext *Context); + /// Returns the type of unrolling, if any, associated with the given + /// statement. + enum UnrollType unrollType(const Stmt *Statement, ASTContext *Context); + /// Returns the condition expression within a given for statement. If there is + /// none, or if the Statement is not a loop, then returns a NULL pointer. + const Expr *getCondExpr(const Stmt *Statement); + /// Returns True if the loop statement has known bounds. + bool hasKnownBounds(const Stmt *Statement, const IntegerLiteral *CXXLoopBound, + const ASTContext *Context); + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; +}; + +} // namespace altera +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_UNROLLLOOPSCHECK_H diff --git a/clang-tools-extra/clang-tidy/bugprone/TerminatingContinueCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/TerminatingContinueCheck.cpp index 43402a221218..65da4c325de4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/TerminatingContinueCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/TerminatingContinueCheck.cpp @@ -26,10 +26,11 @@ void TerminatingContinueCheck::registerMatchers(MatchFinder *Finder) { equalsBoundNode("closestLoop")); Finder->addMatcher( - continueStmt(hasAncestor(stmt(anyOf(forStmt(), whileStmt(), - cxxForRangeStmt(), doStmt())) - .bind("closestLoop")), - hasAncestor(DoWithFalse)) + continueStmt( + hasAncestor(stmt(anyOf(forStmt(), whileStmt(), cxxForRangeStmt(), + doStmt(), switchStmt())) + .bind("closestLoop")), + hasAncestor(DoWithFalse)) .bind("continue"), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp index 4f56df0b4ff7..a6f6ca4c1abd 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp @@ -47,6 +47,8 @@ class MacroUsageCallbacks : public PPCallbacks { return; StringRef MacroName = MacroNameTok.getIdentifierInfo()->getName(); + if (MacroName == "__GCC_HAVE_DWARF2_CFI_ASM") + return; if (!CheckCapsOnly && !RegExp.match(MacroName)) Check->warnMacro(MD, MacroName); diff --git a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp index 83c3fac949ba..e55b260060ce 100644 --- a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp @@ -82,9 +82,6 @@ void ConcatNestedNamespacesCheck::check( if (!locationsInSameFile(Sources, ND.getBeginLoc(), ND.getRBraceLoc())) return; - if (!Sources.isInMainFile(ND.getBeginLoc())) - return; - if (anonymousOrInlineNamespace(ND)) return; diff --git a/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.cpp b/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.cpp index b108f75fbc7a..ebe9658d8b2b 100644 --- a/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.cpp +++ b/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.cpp @@ -9,7 +9,6 @@ #include "BufferDerefCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h" #include "clang/Tooling/FixIt.h" using namespace clang::ast_matchers; @@ -23,13 +22,15 @@ void BufferDerefCheck::registerMatchers(MatchFinder *Finder) { } void BufferDerefCheck::check(const MatchFinder::MatchResult &Result) { - static ento::mpi::MPIFunctionClassifier FuncClassifier(*Result.Context); const auto *CE = Result.Nodes.getNodeAs("CE"); if (!CE->getDirectCallee()) return; + if (!FuncClassifier) + FuncClassifier.emplace(*Result.Context); + const IdentifierInfo *Identifier = CE->getDirectCallee()->getIdentifier(); - if (!Identifier || !FuncClassifier.isMPIType(Identifier)) + if (!Identifier || !FuncClassifier->isMPIType(Identifier)) return; // These containers are used, to capture the type and expression of a buffer. @@ -60,18 +61,18 @@ void BufferDerefCheck::check(const MatchFinder::MatchResult &Result) { // Collect buffer types and argument expressions for all buffers used in the // MPI call expression. The number passed to the lambda corresponds to the // argument index of the currently verified MPI function call. - if (FuncClassifier.isPointToPointType(Identifier)) { + if (FuncClassifier->isPointToPointType(Identifier)) { AddBuffer(0); - } else if (FuncClassifier.isCollectiveType(Identifier)) { - if (FuncClassifier.isReduceType(Identifier)) { + } else if (FuncClassifier->isCollectiveType(Identifier)) { + if (FuncClassifier->isReduceType(Identifier)) { AddBuffer(0); AddBuffer(1); - } else if (FuncClassifier.isScatterType(Identifier) || - FuncClassifier.isGatherType(Identifier) || - FuncClassifier.isAlltoallType(Identifier)) { + } else if (FuncClassifier->isScatterType(Identifier) || + FuncClassifier->isGatherType(Identifier) || + FuncClassifier->isAlltoallType(Identifier)) { AddBuffer(0); AddBuffer(3); - } else if (FuncClassifier.isBcastType(Identifier)) { + } else if (FuncClassifier->isBcastType(Identifier)) { AddBuffer(0); } } @@ -126,6 +127,7 @@ void BufferDerefCheck::checkBuffers(ArrayRef BufferTypes, } } +void BufferDerefCheck::onEndOfTranslationUnit() { FuncClassifier.reset(); } } // namespace mpi } // namespace tidy } // namespace clang diff --git a/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.h b/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.h index 040e3f790e61..a3be5a8224e0 100644 --- a/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.h +++ b/clang-tools-extra/clang-tidy/mpi/BufferDerefCheck.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MPI_BUFFER_DEREF_H #include "../ClangTidyCheck.h" +#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h" namespace clang { namespace tidy { @@ -30,6 +31,7 @@ class BufferDerefCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void onEndOfTranslationUnit() override; private: /// Checks for all buffers in an MPI call if they are sufficiently @@ -41,6 +43,8 @@ class BufferDerefCheck : public ClangTidyCheck { ArrayRef BufferExprs); enum class IndirectionType : unsigned char { Pointer, Array }; + + Optional FuncClassifier; }; } // namespace mpi diff --git a/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.cpp b/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.cpp index cc60ea365c2f..fb96ce77a13d 100644 --- a/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.cpp +++ b/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.cpp @@ -8,7 +8,6 @@ #include "TypeMismatchCheck.h" #include "clang/Lex/Lexer.h" -#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h" #include "clang/Tooling/FixIt.h" #include #include @@ -241,13 +240,15 @@ void TypeMismatchCheck::registerMatchers(MatchFinder *Finder) { } void TypeMismatchCheck::check(const MatchFinder::MatchResult &Result) { - static ento::mpi::MPIFunctionClassifier FuncClassifier(*Result.Context); const auto *const CE = Result.Nodes.getNodeAs("CE"); if (!CE->getDirectCallee()) return; + if (!FuncClassifier) + FuncClassifier.emplace(*Result.Context); + const IdentifierInfo *Identifier = CE->getDirectCallee()->getIdentifier(); - if (!Identifier || !FuncClassifier.isMPIType(Identifier)) + if (!Identifier || !FuncClassifier->isMPIType(Identifier)) return; // These containers are used, to capture buffer, MPI datatype pairs. @@ -281,18 +282,18 @@ void TypeMismatchCheck::check(const MatchFinder::MatchResult &Result) { }; // Collect all buffer, MPI datatype pairs for the inspected call expression. - if (FuncClassifier.isPointToPointType(Identifier)) { + if (FuncClassifier->isPointToPointType(Identifier)) { AddPair(0, 2); - } else if (FuncClassifier.isCollectiveType(Identifier)) { - if (FuncClassifier.isReduceType(Identifier)) { + } else if (FuncClassifier->isCollectiveType(Identifier)) { + if (FuncClassifier->isReduceType(Identifier)) { AddPair(0, 3); AddPair(1, 3); - } else if (FuncClassifier.isScatterType(Identifier) || - FuncClassifier.isGatherType(Identifier) || - FuncClassifier.isAlltoallType(Identifier)) { + } else if (FuncClassifier->isScatterType(Identifier) || + FuncClassifier->isGatherType(Identifier) || + FuncClassifier->isAlltoallType(Identifier)) { AddPair(0, 2); AddPair(3, 5); - } else if (FuncClassifier.isBcastType(Identifier)) { + } else if (FuncClassifier->isBcastType(Identifier)) { AddPair(0, 2); } } @@ -331,6 +332,7 @@ void TypeMismatchCheck::checkArguments(ArrayRef BufferTypes, } } +void TypeMismatchCheck::onEndOfTranslationUnit() { FuncClassifier.reset(); } } // namespace mpi } // namespace tidy } // namespace clang diff --git a/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.h b/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.h index a563e295c7b7..d09ba270495b 100644 --- a/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.h +++ b/clang-tools-extra/clang-tidy/mpi/TypeMismatchCheck.h @@ -11,6 +11,7 @@ #include "../ClangTidyCheck.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h" namespace clang { namespace tidy { @@ -31,6 +32,8 @@ class TypeMismatchCheck : public ClangTidyCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void onEndOfTranslationUnit() override; + private: /// Check if the buffer type MPI datatype pairs match. /// @@ -41,6 +44,8 @@ class TypeMismatchCheck : public ClangTidyCheck { void checkArguments(ArrayRef BufferTypes, ArrayRef BufferExprs, ArrayRef MPIDatatypes, const LangOptions &LO); + + Optional FuncClassifier; }; } // namespace mpi diff --git a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp index 1123238c186b..fe25f7a7ccbc 100644 --- a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "BracesAroundStatementsCheck.h" +#include "../utils/LexerUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Lex/Lexer.h" @@ -16,10 +17,9 @@ using namespace clang::ast_matchers; namespace clang { namespace tidy { namespace readability { -namespace { -tok::TokenKind getTokenKind(SourceLocation Loc, const SourceManager &SM, - const ASTContext *Context) { +static tok::TokenKind getTokenKind(SourceLocation Loc, const SourceManager &SM, + const ASTContext *Context) { Token Tok; SourceLocation Beginning = Lexer::GetBeginningOfToken(Loc, SM, Context->getLangOpts()); @@ -33,9 +33,9 @@ tok::TokenKind getTokenKind(SourceLocation Loc, const SourceManager &SM, return Tok.getKind(); } -SourceLocation forwardSkipWhitespaceAndComments(SourceLocation Loc, - const SourceManager &SM, - const ASTContext *Context) { +static SourceLocation +forwardSkipWhitespaceAndComments(SourceLocation Loc, const SourceManager &SM, + const ASTContext *Context) { assert(Loc.isValid()); for (;;) { while (isWhitespace(*SM.getCharacterData(Loc))) @@ -50,31 +50,15 @@ SourceLocation forwardSkipWhitespaceAndComments(SourceLocation Loc, } } -SourceLocation findEndLocation(SourceLocation LastTokenLoc, - const SourceManager &SM, - const ASTContext *Context) { +static SourceLocation findEndLocation(const Stmt &S, const SourceManager &SM, + const ASTContext *Context) { SourceLocation Loc = - Lexer::GetBeginningOfToken(LastTokenLoc, SM, Context->getLangOpts()); - // Loc points to the beginning of the last (non-comment non-ws) token - // before end or ';'. - assert(Loc.isValid()); - bool SkipEndWhitespaceAndComments = true; - tok::TokenKind TokKind = getTokenKind(Loc, SM, Context); - if (TokKind == tok::NUM_TOKENS || TokKind == tok::semi || - TokKind == tok::r_brace) { - // If we are at ";" or "}", we found the last token. We could use as well - // `if (isa(S))`, but it wouldn't work for nested statements. - SkipEndWhitespaceAndComments = false; - } + utils::lexer::getUnifiedEndLoc(S, SM, Context->getLangOpts()); + if (!Loc.isValid()) + return Loc; - Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, Context->getLangOpts()); - // Loc points past the last token before end or after ';'. - if (SkipEndWhitespaceAndComments) { - Loc = forwardSkipWhitespaceAndComments(Loc, SM, Context); - tok::TokenKind TokKind = getTokenKind(Loc, SM, Context); - if (TokKind == tok::semi) - Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, Context->getLangOpts()); - } + // Start searching right after S. + Loc = Loc.getLocWithOffset(1); for (;;) { assert(Loc.isValid()); @@ -109,8 +93,6 @@ SourceLocation findEndLocation(SourceLocation LastTokenLoc, return Loc; } -} // namespace - BracesAroundStatementsCheck::BracesAroundStatementsCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -123,10 +105,7 @@ void BracesAroundStatementsCheck::storeOptions( } void BracesAroundStatementsCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher( - ifStmt(unless(allOf(isConstexpr(), isInTemplateInstantiation()))) - .bind("if"), - this); + Finder->addMatcher(ifStmt().bind("if"), this); Finder->addMatcher(whileStmt().bind("while"), this); Finder->addMatcher(doStmt().bind("do"), this); Finder->addMatcher(forStmt().bind("for"), this); @@ -224,13 +203,6 @@ bool BracesAroundStatementsCheck::checkStmt( const SourceManager &SM = *Result.SourceManager; const ASTContext *Context = Result.Context; - // Treat macros. - CharSourceRange FileRange = Lexer::makeFileCharRange( - CharSourceRange::getTokenRange(S->getSourceRange()), SM, - Context->getLangOpts()); - if (FileRange.isInvalid()) - return false; - // Convert InitialLoc to file location, if it's on the same macro expansion // level as the start of the statement. We also need file locations for // Lexer::getLocForEndOfToken working properly. @@ -250,13 +222,12 @@ bool BracesAroundStatementsCheck::checkStmt( EndLoc = EndLocHint; ClosingInsertion = "} "; } else { - const auto FREnd = FileRange.getEnd().getLocWithOffset(-1); - EndLoc = findEndLocation(FREnd, SM, Context); + EndLoc = findEndLocation(*S, SM, Context); ClosingInsertion = "\n}"; } assert(StartLoc.isValid()); - assert(EndLoc.isValid()); + // Don't require braces for statements spanning less than certain number of // lines. if (ShortStatementLines && !ForceBracesStmts.erase(S)) { @@ -267,6 +238,20 @@ bool BracesAroundStatementsCheck::checkStmt( } auto Diag = diag(StartLoc, "statement should be inside braces"); + + // Change only if StartLoc and EndLoc are on the same macro expansion level. + // This will also catch invalid EndLoc. + // Example: LLVM_DEBUG( for(...) do_something() ); + // In this case fix-it cannot be provided as the semicolon which is not + // visible here is part of the macro. Adding braces here would require adding + // another semicolon. + if (Lexer::makeFileCharRange( + CharSourceRange::getTokenRange(SourceRange( + SM.getSpellingLoc(StartLoc), SM.getSpellingLoc(EndLoc))), + SM, Context->getLangOpts()) + .isInvalid()) + return false; + Diag << FixItHint::CreateInsertion(StartLoc, " {") << FixItHint::CreateInsertion(EndLoc, ClosingInsertion); return true; diff --git a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.h b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.h index 7c019c6cb552..1270cfe10d19 100644 --- a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.h +++ b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.h @@ -55,6 +55,9 @@ class BracesAroundStatementsCheck : public ClangTidyCheck { template SourceLocation findRParenLoc(const IfOrWhileStmt *S, const SourceManager &SM, const ASTContext *Context); + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: std::set ForceBracesStmts; diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index ecf37b5b9157..78a3851f66be 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -10,7 +10,6 @@ add_clang_library(clangTidyReadabilityModule ContainerSizeEmptyCheck.cpp ConvertMemberFunctionsToStatic.cpp DeleteNullPointerCheck.cpp - DeletedDefaultCheck.cpp ElseAfterReturnCheck.cpp FunctionCognitiveComplexityCheck.cpp FunctionSizeCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/DeletedDefaultCheck.cpp b/clang-tools-extra/clang-tidy/readability/DeletedDefaultCheck.cpp deleted file mode 100644 index ff2f00b94e36..000000000000 --- a/clang-tools-extra/clang-tidy/readability/DeletedDefaultCheck.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//===--- DeletedDefaultCheck.cpp - clang-tidy------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "DeletedDefaultCheck.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" - -using namespace clang::ast_matchers; - -namespace clang { -namespace tidy { -namespace readability { - -void DeletedDefaultCheck::registerMatchers(MatchFinder *Finder) { - // We match constructors/assignment operators that are: - // - explicitly marked '= default' - // - actually deleted - // - not in template instantiation. - // We bind the declaration to "method-decl" and also to "constructor" when - // it is a constructor. - - Finder->addMatcher( - cxxMethodDecl(anyOf(cxxConstructorDecl().bind("constructor"), - isCopyAssignmentOperator(), - isMoveAssignmentOperator()), - isDefaulted(), unless(isImplicit()), isDeleted(), - unless(isInstantiated())) - .bind("method-decl"), - this); -} - -void DeletedDefaultCheck::check(const MatchFinder::MatchResult &Result) { - const StringRef Message = "%0 is explicitly defaulted but implicitly " - "deleted, probably because %1; definition can " - "either be removed or explicitly deleted"; - if (const auto *Constructor = - Result.Nodes.getNodeAs("constructor")) { - auto Diag = diag(Constructor->getBeginLoc(), Message); - if (Constructor->isDefaultConstructor()) { - Diag << "default constructor" - << "a non-static data member or a base class is lacking a default " - "constructor"; - } else if (Constructor->isCopyConstructor()) { - Diag << "copy constructor" - << "a non-static data member or a base class is not copyable"; - } else if (Constructor->isMoveConstructor()) { - Diag << "move constructor" - << "a non-static data member or a base class is neither copyable " - "nor movable"; - } - } else if (const auto *Assignment = - Result.Nodes.getNodeAs("method-decl")) { - diag(Assignment->getBeginLoc(), Message) - << (Assignment->isCopyAssignmentOperator() ? "copy assignment operator" - : "move assignment operator") - << "a base class or a non-static data member is not assignable, e.g. " - "because the latter is marked 'const'"; - } -} - -} // namespace readability -} // namespace tidy -} // namespace clang diff --git a/clang-tools-extra/clang-tidy/readability/DeletedDefaultCheck.h b/clang-tools-extra/clang-tidy/readability/DeletedDefaultCheck.h deleted file mode 100644 index ab7f141417d0..000000000000 --- a/clang-tools-extra/clang-tidy/readability/DeletedDefaultCheck.h +++ /dev/null @@ -1,35 +0,0 @@ -//===--- DeletedDefaultCheck.h - clang-tidy----------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETED_DEFAULT_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETED_DEFAULT_H - -#include "../ClangTidyCheck.h" - -namespace clang { -namespace tidy { -namespace readability { - -/// Checks when a constructor or an assignment operator is marked as '= default' -/// but is actually deleted by the compiler. -/// -/// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/readability-deleted-default.html -class DeletedDefaultCheck : public ClangTidyCheck { -public: - DeletedDefaultCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} - void registerMatchers(ast_matchers::MatchFinder *Finder) override; - void check(const ast_matchers::MatchFinder::MatchResult &Result) override; -}; - -} // namespace readability -} // namespace tidy -} // namespace clang - -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETED_DEFAULT_H diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp index 89bb02e78cc6..0558b4101637 100644 --- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -171,8 +171,7 @@ void ElseAfterReturnCheck::registerPPCallbacks(const SourceManager &SM, void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { const auto InterruptsControlFlow = stmt(anyOf( returnStmt().bind(InterruptingStr), continueStmt().bind(InterruptingStr), - breakStmt().bind(InterruptingStr), - expr(ignoringImplicit(cxxThrowExpr().bind(InterruptingStr))))); + breakStmt().bind(InterruptingStr), cxxThrowExpr().bind(InterruptingStr))); Finder->addMatcher( compoundStmt( forEach(ifStmt(unless(isConstexpr()), diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h index 440cf4b637b7..d3fbc0ac0abe 100644 --- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h +++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h @@ -28,6 +28,9 @@ class ElseAfterReturnCheck : public ClangTidyCheck { Preprocessor *ModuleExpanderPP) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } using ConditionalBranchMap = llvm::DenseMap>; diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 09b3cc25678c..12853fa14823 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -407,6 +407,8 @@ static bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl, static std::string fixupWithStyle(StringRef Name, const IdentifierNamingCheck::NamingStyle &Style) { + Name.consume_front(Style.Prefix); + Name.consume_back(Style.Suffix); const std::string Fixed = fixupWithCase( Name, Style.Case.getValueOr(IdentifierNamingCheck::CaseType::CT_AnyCase)); StringRef Mid = StringRef(Fixed).trim("_"); diff --git a/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp b/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp index c28424b11f27..b3945b5a932f 100644 --- a/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp @@ -294,8 +294,7 @@ void InconsistentDeclarationParameterNameCheck::storeOptions( void InconsistentDeclarationParameterNameCheck::registerMatchers( MatchFinder *Finder) { - Finder->addMatcher(functionDecl(unless(isImplicit()), hasOtherDeclarations()) - .bind("functionDecl"), + Finder->addMatcher(functionDecl(hasOtherDeclarations()).bind("functionDecl"), this); } diff --git a/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h b/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h index aac2f5060aa9..ca9640fc5a60 100644 --- a/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h +++ b/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h @@ -33,6 +33,9 @@ class InconsistentDeclarationParameterNameCheck : public ClangTidyCheck { void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: void markRedeclarationsAsVisited(const FunctionDecl *FunctionDeclaration); diff --git a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp index 77f93f1999a9..7b5a22f449c4 100644 --- a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp @@ -106,11 +106,7 @@ void MisleadingIndentationCheck::missingBracesCheck(const SourceManager &SM, } void MisleadingIndentationCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher( - ifStmt(allOf(hasElse(stmt()), - unless(allOf(isConstexpr(), isInTemplateInstantiation())))) - .bind("if"), - this); + Finder->addMatcher(ifStmt(hasElse(stmt())).bind("if"), this); Finder->addMatcher( compoundStmt(has(stmt(anyOf(ifStmt(), forStmt(), whileStmt())))) .bind("compound"), diff --git a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h index ed5ba5bad120..a9067032fa94 100644 --- a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h +++ b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h @@ -27,6 +27,9 @@ class MisleadingIndentationCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: void danglingElseCheck(const SourceManager &SM, ASTContext *Context, diff --git a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp index 5e018ce6172c..4f81dc49ded7 100644 --- a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp @@ -18,7 +18,7 @@ namespace tidy { namespace readability { void NamedParameterCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { - Finder->addMatcher(functionDecl(unless(isInstantiated())).bind("decl"), this); + Finder->addMatcher(functionDecl().bind("decl"), this); } void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) { @@ -26,10 +26,6 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) { const auto *Function = Result.Nodes.getNodeAs("decl"); SmallVector, 4> UnnamedParams; - // Ignore implicitly generated members. - if (Function->isImplicit()) - return; - // Ignore declarations without a definition if we're not dealing with an // overriden method. const FunctionDecl *Definition = nullptr; diff --git a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h index 33a51b4c8dc9..f946e00a0044 100644 --- a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h +++ b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h @@ -32,6 +32,9 @@ class NamedParameterCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } }; } // namespace readability diff --git a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp index 1044df0032d8..c9ebf7b6f8ce 100644 --- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp @@ -18,7 +18,7 @@ namespace readability { void NonConstParameterCheck::registerMatchers(MatchFinder *Finder) { // Add parameters to Parameters. - Finder->addMatcher(parmVarDecl(unless(isInstantiated())).bind("Parm"), this); + Finder->addMatcher(parmVarDecl().bind("Parm"), this); // C++ constructor. Finder->addMatcher(cxxConstructorDecl().bind("Ctor"), this); @@ -28,13 +28,11 @@ void NonConstParameterCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(declRefExpr().bind("Ref"), this); // Analyse parameter usage in function. - Finder->addMatcher( - traverse(TK_AsIs, - stmt(anyOf(unaryOperator(hasAnyOperatorName("++", "--")), - binaryOperator(), callExpr(), returnStmt(), - cxxConstructExpr())) - .bind("Mark")), - this); + Finder->addMatcher(stmt(anyOf(unaryOperator(hasAnyOperatorName("++", "--")), + binaryOperator(), callExpr(), returnStmt(), + cxxConstructExpr())) + .bind("Mark"), + this); Finder->addMatcher(varDecl(hasInitializer(anything())).bind("Mark"), this); } diff --git a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.h b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.h index 39959e619096..a6179d6aa1e8 100644 --- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.h +++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.h @@ -26,6 +26,9 @@ class NonConstParameterCheck : public ClangTidyCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void onEndOfTranslationUnit() override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: /// Parameter info. diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index bbd2e24e503b..088b9f09082e 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -15,7 +15,6 @@ #include "ContainerSizeEmptyCheck.h" #include "ConvertMemberFunctionsToStatic.h" #include "DeleteNullPointerCheck.h" -#include "DeletedDefaultCheck.h" #include "ElseAfterReturnCheck.h" #include "FunctionCognitiveComplexityCheck.h" #include "FunctionSizeCheck.h" @@ -67,8 +66,6 @@ class ReadabilityModule : public ClangTidyModule { "readability-convert-member-functions-to-static"); CheckFactories.registerCheck( "readability-delete-null-pointer"); - CheckFactories.registerCheck( - "readability-deleted-default"); CheckFactories.registerCheck( "readability-else-after-return"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp index 9e336cb4cf15..6af77635aa2b 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp @@ -32,10 +32,10 @@ bool isLocationInMacroExpansion(const SourceManager &SM, SourceLocation Loc) { void RedundantControlFlowCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - functionDecl( - isDefinition(), returns(voidType()), - has(compoundStmt(hasAnySubstatement(returnStmt(unless(has(expr()))))) - .bind("return"))), + functionDecl(isDefinition(), returns(voidType()), + hasBody(compoundStmt(hasAnySubstatement( + returnStmt(unless(has(expr()))))) + .bind("return"))), this); Finder->addMatcher( mapAnyOf(forStmt, cxxForRangeStmt, whileStmt, doStmt) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.h index d4513e6f49a7..6d91c208587f 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.h @@ -29,6 +29,10 @@ class RedundantControlFlowCheck : public ClangTidyCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } + private: void checkRedundantReturn(const ast_matchers::MatchFinder::MatchResult &Result, diff --git a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp index 2d14b49e0eea..36294cd0e9b8 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp @@ -32,7 +32,7 @@ void SimplifySubscriptExprCheck::registerMatchers(MatchFinder *Finder) { llvm::SmallVector(Types.begin(), Types.end())))))); Finder->addMatcher( - arraySubscriptExpr(hasBase(ignoringParenImpCasts( + arraySubscriptExpr(hasBase( cxxMemberCallExpr( has(memberExpr().bind("member")), on(hasType(qualType( @@ -40,7 +40,7 @@ void SimplifySubscriptExprCheck::registerMatchers(MatchFinder *Finder) { hasDescendant(substTemplateTypeParmType()))), anyOf(TypesMatcher, pointerType(pointee(TypesMatcher)))))), callee(namedDecl(hasName("data")))) - .bind("call")))), + .bind("call"))), this); } diff --git a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h index 4f43cdb726df..6caaf49de2a3 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h +++ b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h @@ -28,6 +28,9 @@ class SimplifySubscriptExprCheck : public ClangTidyCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap& Opts) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: const std::vector Types; diff --git a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp index e7d70f06bdb4..df4a39e11ce4 100644 --- a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp @@ -39,8 +39,7 @@ void StaticAccessedThroughInstanceCheck::storeOptions( void StaticAccessedThroughInstanceCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( memberExpr(hasDeclaration(anyOf(cxxMethodDecl(isStaticStorageClass()), - varDecl(hasStaticStorageDuration()))), - unless(isInTemplateInstantiation())) + varDecl(hasStaticStorageDuration())))) .bind("memberExpression"), this); } diff --git a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h index d12e8211651f..f80f3605a01f 100644 --- a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h +++ b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h @@ -30,6 +30,9 @@ class StaticAccessedThroughInstanceCheck : public ClangTidyCheck { void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: const unsigned NameSpecifierNestingThreshold; diff --git a/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp b/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp index 45194a8e3d97..23f8dbbacb68 100644 --- a/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp @@ -39,17 +39,14 @@ void UniqueptrDeleteReleaseCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxDeleteExpr( unless(isInTemplateInstantiation()), - has(expr(ignoringParenImpCasts( - cxxMemberCallExpr( - callee( - memberExpr(hasObjectExpression(allOf( - unless(isTypeDependent()), - anyOf(hasType(UniquePtrWithDefaultDelete), - hasType(pointsTo( - UniquePtrWithDefaultDelete))))), - member(cxxMethodDecl(hasName("release")))) - .bind("release_expr"))) - .bind("release_call"))))) + has(cxxMemberCallExpr( + callee(memberExpr(hasObjectExpression(anyOf( + hasType(UniquePtrWithDefaultDelete), + hasType(pointsTo( + UniquePtrWithDefaultDelete)))), + member(cxxMethodDecl(hasName("release")))) + .bind("release_expr"))) + .bind("release_call"))) .bind("delete"), this); } diff --git a/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h b/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h index 88bb82539ac5..a840ac722d19 100644 --- a/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h +++ b/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h @@ -26,6 +26,9 @@ class UniqueptrDeleteReleaseCheck : public ClangTidyCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: const bool PreferResetCall; diff --git a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp index c4fbeeb4777a..827711e92e87 100644 --- a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp @@ -196,12 +196,11 @@ void UppercaseLiteralSuffixCheck::registerMatchers(MatchFinder *Finder) { // Sadly, we can't check whether the literal has suffix or not. // E.g. i32 suffix still results in 'BuiltinType::Kind::Int'. // And such an info is not stored in the *Literal itself. - Finder->addMatcher(traverse(TK_AsIs, + Finder->addMatcher( stmt(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name), floatLiteral().bind(FloatingLiteralCheck::Name)), unless(anyOf(hasParent(userDefinedLiteral()), - hasAncestor(isImplicit()), - hasAncestor(substNonTypeTemplateParmExpr()))))), + hasAncestor(substNonTypeTemplateParmExpr())))), this); } diff --git a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.h b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.h index c31fc06cb4a9..1f6e6e6fd572 100644 --- a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.h +++ b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.h @@ -28,6 +28,9 @@ class UppercaseLiteralSuffixCheck : public ClangTidyCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: template diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp index ca8b1b59f89e..88828f72e6bb 100644 --- a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "LexerUtils.h" +#include "clang/AST/AST.h" #include "clang/Basic/SourceManager.h" namespace clang { @@ -148,6 +149,70 @@ llvm::Optional getQualifyingToken(tok::TokenKind TK, return LastMatchAfterTemplate != None ? LastMatchAfterTemplate : LastMatchBeforeTemplate; } + +static bool breakAndReturnEnd(const Stmt &S) { + return isa(S); +} + +static bool breakAndReturnEndPlus1Token(const Stmt &S) { + return isa(S); +} + +// Given a Stmt which does not include it's semicolon this method returns the +// SourceLocation of the semicolon. +static SourceLocation getSemicolonAfterStmtEndLoc(const SourceLocation &EndLoc, + const SourceManager &SM, + const LangOptions &LangOpts) { + + if (EndLoc.isMacroID()) { + // Assuming EndLoc points to a function call foo within macro F. + // This method is supposed to return location of the semicolon within + // those macro arguments: + // F ( foo() ; ) + // ^ EndLoc ^ SpellingLoc ^ next token of SpellingLoc + const SourceLocation SpellingLoc = SM.getSpellingLoc(EndLoc); + Optional NextTok = + findNextTokenSkippingComments(SpellingLoc, SM, LangOpts); + + // Was the next token found successfully? + // All macro issues are simply resolved by ensuring it's a semicolon. + if (NextTok && NextTok->is(tok::TokenKind::semi)) { + // Ideally this would return `F` with spelling location `;` (NextTok) + // following the examle above. For now simply return NextTok location. + return NextTok->getLocation(); + } + + // Fallthrough to 'normal handling'. + // F ( foo() ) ; + // ^ EndLoc ^ SpellingLoc ) ^ next token of EndLoc + } + + Optional NextTok = findNextTokenSkippingComments(EndLoc, SM, LangOpts); + + // Testing for semicolon again avoids some issues with macros. + if (NextTok && NextTok->is(tok::TokenKind::semi)) + return NextTok->getLocation(); + + return SourceLocation(); +} + +SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM, + const LangOptions &LangOpts) { + + const Stmt *LastChild = &S; + while (!LastChild->children().empty() && !breakAndReturnEnd(*LastChild) && + !breakAndReturnEndPlus1Token(*LastChild)) { + for (const Stmt *Child : LastChild->children()) + LastChild = Child; + } + + if (!breakAndReturnEnd(*LastChild) && + breakAndReturnEndPlus1Token(*LastChild)) + return getSemicolonAfterStmtEndLoc(S.getEndLoc(), SM, LangOpts); + + return S.getEndLoc(); +} + } // namespace lexer } // namespace utils } // namespace tidy diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.h b/clang-tools-extra/clang-tidy/utils/LexerUtils.h index 8781b0571e7a..79ba16ded968 100644 --- a/clang-tools-extra/clang-tidy/utils/LexerUtils.h +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.h @@ -14,6 +14,9 @@ #include "clang/Lex/Lexer.h" namespace clang { + +class Stmt; + namespace tidy { namespace utils { namespace lexer { @@ -104,6 +107,11 @@ llvm::Optional getQualifyingToken(tok::TokenKind TK, const ASTContext &Context, const SourceManager &SM); +/// Stmt->getEndLoc does not always behave the same way depending on Token type. +/// See implementation for exceptions. +SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM, + const LangOptions &LangOpts); + } // namespace lexer } // namespace utils } // namespace tidy diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt index a6229a229002..11b8c7eadd1d 100644 --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -19,6 +19,7 @@ option(CLANGD_MALLOC_TRIM "Call malloc_trim(3) periodically in Clangd. (only tak llvm_canonicalize_cmake_booleans( CLANGD_BUILD_XPC CLANGD_ENABLE_REMOTE + ENABLE_GRPC_REFLECTION CLANGD_MALLOC_TRIM LLVM_ENABLE_ZLIB ) diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index df5377d77f2b..aef849d8d8d9 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -467,11 +467,10 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, if (Server) return Reply(llvm::make_error("server already initialized", ErrorCode::InvalidRequest)); - if (const auto &Dir = Params.initializationOptions.compilationDatabasePath) - Opts.CompileCommandsDir = Dir; if (Opts.UseDirBasedCDB) { DirectoryBasedGlobalCompilationDatabase::Options CDBOpts(TFS); - CDBOpts.CompileCommandsDir = Opts.CompileCommandsDir; + if (const auto &Dir = Params.initializationOptions.compilationDatabasePath) + CDBOpts.CompileCommandsDir = Dir; CDBOpts.ContextProvider = Opts.ContextProvider; BaseCDB = std::make_unique(CDBOpts); @@ -519,6 +518,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, if (Params.capabilities.WorkDoneProgress) BackgroundIndexProgressState = BackgroundIndexProgress::Empty; BackgroundIndexSkipCreate = Params.capabilities.ImplicitProgressCreation; + Opts.ImplicitCancellation = !Params.capabilities.CancelsStaleRequests; llvm::json::Object ServerCaps{ {"textDocumentSync", @@ -666,8 +666,9 @@ void ClangdLSPServer::onDocumentDidChange( log("Trying to incrementally change non-added document: {0}", File); return; } + std::string NewCode(*Code); for (const auto &Change : Params.contentChanges) { - if (auto Err = applyChange(*Code, Change)) { + if (auto Err = applyChange(NewCode, Change)) { // If this fails, we are most likely going to be not in sync anymore with // the client. It is better to remove the draft and let further // operations fail rather than giving wrong results. @@ -676,7 +677,7 @@ void ClangdLSPServer::onDocumentDidChange( return; } } - Server->addDocument(File, *Code, encodeVersion(Params.textDocument.version), + Server->addDocument(File, NewCode, encodeVersion(Params.textDocument.version), WantDiags, Params.forceRebuild); } @@ -779,7 +780,7 @@ void ClangdLSPServer::onWorkspaceSymbol( const WorkspaceSymbolParams &Params, Callback> Reply) { Server->workspaceSymbols( - Params.query, Opts.CodeComplete.Limit, + Params.query, Params.limit.getValueOr(Opts.CodeComplete.Limit), [Reply = std::move(Reply), this](llvm::Expected> Items) mutable { if (!Items) @@ -1030,21 +1031,24 @@ void ClangdLSPServer::onCompletion(const CompletionParams &Params, vlog("ignored auto-triggered completion, preceding char did not match"); return Reply(CompletionList()); } - Server->codeComplete( - Params.textDocument.uri.file(), Params.position, Opts.CodeComplete, - [Reply = std::move(Reply), - this](llvm::Expected List) mutable { - if (!List) - return Reply(List.takeError()); - CompletionList LSPList; - LSPList.isIncomplete = List->HasMore; - for (const auto &R : List->Completions) { - CompletionItem C = R.render(Opts.CodeComplete); - C.kind = adjustKindToCapability(C.kind, SupportedCompletionItemKinds); - LSPList.items.push_back(std::move(C)); - } - return Reply(std::move(LSPList)); - }); + auto Opts = this->Opts.CodeComplete; + if (Params.limit && *Params.limit >= 0) + Opts.Limit = *Params.limit; + Server->codeComplete(Params.textDocument.uri.file(), Params.position, Opts, + [Reply = std::move(Reply), Opts, + this](llvm::Expected List) mutable { + if (!List) + return Reply(List.takeError()); + CompletionList LSPList; + LSPList.isIncomplete = List->HasMore; + for (const auto &R : List->Completions) { + CompletionItem C = R.render(Opts); + C.kind = adjustKindToCapability( + C.kind, SupportedCompletionItemKinds); + LSPList.items.push_back(std::move(C)); + } + return Reply(std::move(LSPList)); + }); } void ClangdLSPServer::onSignatureHelp(const TextDocumentPositionParams &Params, diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 01d0ec20f098..fc13c6257ee6 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -48,9 +48,6 @@ class ClangdLSPServer : private ClangdServer::Callbacks, /// Look for compilation databases, rather than using compile commands /// set via LSP (extensions) only. bool UseDirBasedCDB = true; - /// A fixed directory to search for a compilation database in. - /// If not set, we search upward from the source file. - llvm::Optional CompileCommandsDir; /// The offset-encoding to use, or None to negotiate it over LSP. llvm::Optional Encoding; /// If set, periodically called to release memory. diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index cbd9677f340c..557689774b14 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -9,6 +9,7 @@ #include "ClangdServer.h" #include "CodeComplete.h" #include "Config.h" +#include "Diagnostics.h" #include "DumpAST.h" #include "FindSymbols.h" #include "Format.h" @@ -81,7 +82,9 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { if (FIndex) FIndex->updateMain(Path, AST); - std::vector Diagnostics = AST.getDiagnostics(); + assert(AST.getDiagnostics().hasValue() && + "We issue callback only with fresh preambles"); + std::vector Diagnostics = *AST.getDiagnostics(); if (ServerCallbacks) Publish([&]() { ServerCallbacks->onDiagnosticsReady(Path, AST.version(), @@ -106,6 +109,23 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { ClangdServer::Callbacks *ServerCallbacks; }; +class DraftStoreFS : public ThreadsafeFS { +public: + DraftStoreFS(const ThreadsafeFS &Base, const DraftStore &Drafts) + : Base(Base), DirtyFiles(Drafts) {} + +private: + llvm::IntrusiveRefCntPtr viewImpl() const override { + auto OFS = llvm::makeIntrusiveRefCnt( + Base.view(llvm::None)); + OFS->pushOverlay(DirtyFiles.asVFS()); + return OFS; + } + + const ThreadsafeFS &Base; + const DraftStore &DirtyFiles; +}; + } // namespace ClangdServer::Options ClangdServer::optsForTest() { @@ -132,7 +152,10 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, : FeatureModules(Opts.FeatureModules), CDB(CDB), TFS(TFS), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr), ClangTidyProvider(Opts.ClangTidyProvider), - WorkspaceRoot(Opts.WorkspaceRoot) { + WorkspaceRoot(Opts.WorkspaceRoot), + Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate + : TUScheduler::NoInvalidation), + DirtyFS(std::make_unique(TFS, DraftMgr)) { // Pass a callback into `WorkScheduler` to extract symbols from a newly // parsed file and rebuild the file index synchronously each time an AST // is parsed. @@ -220,14 +243,14 @@ void ClangdServer::reparseOpenFilesIfNeeded( for (const Path &FilePath : DraftMgr.getActiveFiles()) if (Filter(FilePath)) if (auto Draft = DraftMgr.getDraft(FilePath)) // else disappeared in race? - addDocument(FilePath, std::move(Draft->Contents), Draft->Version, + addDocument(FilePath, *Draft->Contents, Draft->Version, WantDiagnostics::Auto); } -llvm::Optional ClangdServer::getDraft(PathRef File) const { +std::shared_ptr ClangdServer::getDraft(PathRef File) const { auto Draft = DraftMgr.getDraft(File); if (!Draft) - return llvm::None; + return nullptr; return std::move(Draft->Contents); } @@ -344,6 +367,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos, ParseInput.Index = Index; CodeCompleteOpts.MainFileSignals = IP->Signals; + CodeCompleteOpts.AllScopes = Config::current().Completion.AllScopes; // FIXME(ibiryukov): even if Preamble is non-null, we may want to check // both the old and the new version in case only one of them matches. CodeCompleteResult Result = clangd::codeComplete( @@ -472,9 +496,10 @@ void ClangdServer::prepareRename(PathRef File, Position Pos, return CB(InpAST.takeError()); // prepareRename is latency-sensitive: we don't query the index, as we // only need main-file references - auto Results = clangd::rename( - {Pos, NewName.getValueOr("__clangd_rename_dummy"), InpAST->AST, File, - /*Index=*/nullptr, RenameOpts}); + auto Results = + clangd::rename({Pos, NewName.getValueOr("__clangd_rename_placeholder"), + InpAST->AST, File, /*FS=*/nullptr, + /*Index=*/nullptr, RenameOpts}); if (!Results) { // LSP says to return null on failure, but that will result in a generic // failure message. If we send an LSP error response, clients can surface @@ -489,25 +514,16 @@ void ClangdServer::prepareRename(PathRef File, Position Pos, void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName, const RenameOptions &Opts, Callback CB) { - // A snapshot of all file dirty buffers. - llvm::StringMap Snapshot = WorkScheduler->getAllFileContents(); auto Action = [File = File.str(), NewName = NewName.str(), Pos, Opts, - CB = std::move(CB), Snapshot = std::move(Snapshot), + CB = std::move(CB), this](llvm::Expected InpAST) mutable { // Tracks number of files edited per invocation. static constexpr trace::Metric RenameFiles("rename_files", trace::Metric::Distribution); if (!InpAST) return CB(InpAST.takeError()); - auto GetDirtyBuffer = - [&Snapshot](PathRef AbsPath) -> llvm::Optional { - auto It = Snapshot.find(AbsPath); - if (It == Snapshot.end()) - return llvm::None; - return It->second; - }; - auto R = clangd::rename( - {Pos, NewName, InpAST->AST, File, Index, Opts, GetDirtyBuffer}); + auto R = clangd::rename({Pos, NewName, InpAST->AST, File, + DirtyFS->view(llvm::None), Index, Opts}); if (!R) return CB(R.takeError()); @@ -582,7 +598,7 @@ void ClangdServer::enumerateTweaks( }; WorkScheduler->runWithAST("EnumerateTweaks", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, @@ -672,8 +688,7 @@ void ClangdServer::findDocumentHighlights( CB(clangd::findDocumentHighlights(InpAST->AST, Pos)); }; - WorkScheduler->runWithAST("Highlights", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + WorkScheduler->runWithAST("Highlights", File, std::move(Action), Transient); } void ClangdServer::findHover(PathRef File, Position Pos, @@ -687,8 +702,7 @@ void ClangdServer::findHover(PathRef File, Position Pos, CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index)); }; - WorkScheduler->runWithAST("Hover", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + WorkScheduler->runWithAST("Hover", File, std::move(Action), Transient); } void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve, @@ -760,7 +774,7 @@ void ClangdServer::documentSymbols(llvm::StringRef File, CB(clangd::getDocumentSymbols(InpAST->AST)); }; WorkScheduler->runWithAST("DocumentSymbols", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::foldingRanges(llvm::StringRef File, @@ -772,7 +786,7 @@ void ClangdServer::foldingRanges(llvm::StringRef File, CB(clangd::getFoldingRanges(InpAST->AST)); }; WorkScheduler->runWithAST("FoldingRanges", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::findImplementations( @@ -839,7 +853,7 @@ void ClangdServer::documentLinks(PathRef File, CB(clangd::getDocumentLinks(InpAST->AST)); }; WorkScheduler->runWithAST("DocumentLinks", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::semanticHighlights( @@ -851,7 +865,7 @@ void ClangdServer::semanticHighlights( CB(clangd::getSemanticHighlightings(InpAST->AST)); }; WorkScheduler->runWithAST("SemanticHighlights", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::getAST(PathRef File, Range R, @@ -891,6 +905,21 @@ void ClangdServer::customAction(PathRef File, llvm::StringRef Name, WorkScheduler->runWithAST(Name, File, std::move(Action)); } +void ClangdServer::diagnostics(PathRef File, Callback> CB) { + auto Action = + [CB = std::move(CB)](llvm::Expected InpAST) mutable { + if (!InpAST) + return CB(InpAST.takeError()); + if (auto Diags = InpAST->AST.getDiagnostics()) + return CB(*Diags); + // FIXME: Use ServerCancelled error once it is settled in LSP-3.17. + return CB(llvm::make_error("server is busy parsing includes", + ErrorCode::InternalError)); + }; + + WorkScheduler->runWithAST("Diagnostics", File, std::move(Action)); +} + llvm::StringMap ClangdServer::fileStats() const { return WorkScheduler->fileStats(); } diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 5254bfe78b71..37ac30f70cb4 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -12,6 +12,7 @@ #include "../clang-tidy/ClangTidyOptions.h" #include "CodeComplete.h" #include "ConfigProvider.h" +#include "Diagnostics.h" #include "DraftStore.h" #include "FeatureModule.h" #include "GlobalCompilationDatabase.h" @@ -40,6 +41,7 @@ #include #include #include +#include namespace clang { namespace clangd { @@ -64,6 +66,8 @@ class ClangdServer { virtual ~Callbacks() = default; /// Called by ClangdServer when \p Diagnostics for \p File are ready. + /// These pushed diagnostics might correspond to an older version of the + /// file, they do not interfere with "pull-based" ClangdServer::diagnostics. /// May be called concurrently for separate files, not for a single file. virtual void onDiagnosticsReady(PathRef File, llvm::StringRef Version, std::vector Diagnostics) {} @@ -146,6 +150,12 @@ class ClangdServer { /*RebuildRatio=*/1, }; + /// Cancel certain requests if the file changes before they begin running. + /// This is useful for "transient" actions like enumerateTweaks that were + /// likely implicitly generated, and avoids redundant work if clients forget + /// to cancel. Clients that always cancel stale requests should clear this. + bool ImplicitCancellation = true; + /// Clangd will execute compiler drivers matching one of these globs to /// fetch system include path. std::vector QueryDriverGlobs; @@ -339,6 +349,14 @@ class ClangdServer { void customAction(PathRef File, llvm::StringRef Name, Callback Action); + /// Fetches diagnostics for current version of the \p File. This might fail if + /// server is busy (building a preamble) and would require a long time to + /// prepare diagnostics. If it fails, clients should wait for + /// onSemanticsMaybeChanged and then retry. + /// These 'pulled' diagnostics do not interfere with the diagnostics 'pushed' + /// to Callbacks::onDiagnosticsReady, and clients may use either or both. + void diagnostics(PathRef File, Callback> CB); + /// Returns estimated memory usage and other statistics for each of the /// currently open files. /// Overall memory usage of clangd may be significantly more than reported @@ -348,7 +366,9 @@ class ClangdServer { /// FIXME: those metrics might be useful too, we should add them. llvm::StringMap fileStats() const; - llvm::Optional getDraft(PathRef File) const; + /// Gets the contents of a currently tracked file. Returns nullptr if the file + /// isn't being tracked. + std::shared_ptr getDraft(PathRef File) const; // Blocks the main thread until the server is idle. Only for use in tests. // Returns false if the timeout expires. @@ -389,11 +409,14 @@ class ClangdServer { llvm::Optional WorkspaceRoot; llvm::Optional WorkScheduler; + // Invalidation policy used for actions that we assume are "transient". + TUScheduler::ASTActionInvalidation Transient; // Store of the current versions of the open documents. // Only written from the main thread (despite being threadsafe). - // FIXME: TUScheduler also keeps these, unify? DraftStore DraftMgr; + + std::unique_ptr DirtyFS; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp index b55d1b03dee6..7966b7dfa8a3 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -96,9 +96,9 @@ std::string detectClangPath() { if (auto PathCC = llvm::sys::findProgramByName(Name)) return resolve(std::move(*PathCC)); // Fallback: a nonexistent 'clang' binary next to clangd. - static int Dummy; + static int StaticForMainAddr; std::string ClangdExecutable = - llvm::sys::fs::getMainExecutable("clangd", (void *)&Dummy); + llvm::sys::fs::getMainExecutable("clangd", (void *)&StaticForMainAddr); SmallString<128> ClangPath; ClangPath = llvm::sys::path::parent_path(ClangdExecutable); llvm::sys::path::append(ClangPath, "clang"); @@ -120,8 +120,9 @@ const llvm::Optional detectSysroot() { } std::string detectStandardResourceDir() { - static int Dummy; // Just an address in this process. - return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy); + static int StaticForMainAddr; // Just an address in this process. + return CompilerInvocation::GetResourcesPath("clangd", + (void *)&StaticForMainAddr); } // The path passed to argv[0] is important: diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h index 391632cb086a..7064edd76b8f 100644 --- a/clang-tools-extra/clangd/Config.h +++ b/clang-tools-extra/clangd/Config.h @@ -106,6 +106,13 @@ struct Config { // ::). All nested namespaces are affected as well. std::vector FullyQualifiedNamespaces; } Style; + + /// Configures code completion feature. + struct { + /// Whether code completion includes results that are not visible in current + /// scopes. + bool AllScopes = true; + } Completion; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp index dadc578c3a81..8f402ae06153 100644 --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -192,6 +192,7 @@ struct FragmentCompiler { compile(std::move(F.CompileFlags)); compile(std::move(F.Index)); compile(std::move(F.Diagnostics)); + compile(std::move(F.Completion)); } void compile(Fragment::IfBlock &&F) { @@ -370,7 +371,7 @@ struct FragmentCompiler { } void compile(Fragment::DiagnosticsBlock &&F) { - std::vector Normalized; + std::vector Normalized; for (const auto &Suppressed : F.Suppress) { if (*Suppressed == "*") { Out.Apply.push_back([&](const Params &, Config &C) { @@ -379,15 +380,16 @@ struct FragmentCompiler { }); return; } - Normalized.push_back(normalizeSuppressedCode(*Suppressed)); + Normalized.push_back(normalizeSuppressedCode(*Suppressed).str()); } if (!Normalized.empty()) - Out.Apply.push_back([Normalized](const Params &, Config &C) { - if (C.Diagnostics.SuppressAll) - return; - for (llvm::StringRef N : Normalized) - C.Diagnostics.Suppress.insert(N); - }); + Out.Apply.push_back( + [Normalized(std::move(Normalized))](const Params &, Config &C) { + if (C.Diagnostics.SuppressAll) + return; + for (llvm::StringRef N : Normalized) + C.Diagnostics.Suppress.insert(N); + }); compile(std::move(F.ClangTidy)); } @@ -463,6 +465,15 @@ struct FragmentCompiler { } } + void compile(Fragment::CompletionBlock &&F) { + if (F.AllScopes) { + Out.Apply.push_back( + [AllScopes(**F.AllScopes)](const Params &, Config &C) { + C.Completion.AllScopes = AllScopes; + }); + } + } + constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error; constexpr static llvm::SourceMgr::DiagKind Warning = llvm::SourceMgr::DK_Warning; diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h index c36b07f5e8e2..1365ed4c1037 100644 --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -238,6 +238,14 @@ struct Fragment { std::vector> FullyQualifiedNamespaces; }; StyleBlock Style; + + /// Describes code completion preferences. + struct CompletionBlock { + /// Whether code completion should include suggestions from scopes that are + /// not visible. The required scope prefix will be inserted. + llvm::Optional> AllScopes; + }; + CompletionBlock Completion; }; } // namespace config diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp index 348ee9dd1f75..d50c01168a8d 100644 --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -63,6 +63,7 @@ class Parser { Dict.handle("Index", [&](Node &N) { parse(F.Index, N); }); Dict.handle("Style", [&](Node &N) { parse(F.Style, N); }); Dict.handle("Diagnostics", [&](Node &N) { parse(F.Diagnostics, N); }); + Dict.handle("Completion", [&](Node &N) { parse(F.Completion, N); }); Dict.parse(N); return !(N.failed() || HadError); } @@ -165,6 +166,19 @@ class Parser { Dict.parse(N); } + void parse(Fragment::CompletionBlock &F, Node &N) { + DictParser Dict("Completion", this); + Dict.handle("AllScopes", [&](Node &N) { + if (auto Value = scalarValue(N, "AllScopes")) { + if (auto AllScopes = llvm::yaml::parseBool(**Value)) + F.AllScopes = *AllScopes; + else + warning("AllScopes should be a boolean", N); + } + }); + Dict.parse(N); + } + // Helper for parsing mapping nodes (dictionaries). // We don't use YamlIO as we want to control over unknown keys. class DictParser { diff --git a/clang-tools-extra/clangd/DraftStore.cpp b/clang-tools-extra/clangd/DraftStore.cpp index 97ac9eeaf89f..e040d1ee93d6 100644 --- a/clang-tools-extra/clangd/DraftStore.cpp +++ b/clang-tools-extra/clangd/DraftStore.cpp @@ -11,6 +11,8 @@ #include "support/Logger.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/VirtualFileSystem.h" +#include namespace clang { namespace clangd { @@ -22,7 +24,7 @@ llvm::Optional DraftStore::getDraft(PathRef File) const { if (It == Drafts.end()) return None; - return It->second; + return It->second.D; } std::vector DraftStore::getActiveFiles() const { @@ -75,10 +77,11 @@ std::string DraftStore::addDraft(PathRef File, llvm::StringRef Version, llvm::StringRef Contents) { std::lock_guard Lock(Mutex); - Draft &D = Drafts[File]; - updateVersion(D, Version); - D.Contents = Contents.str(); - return D.Version; + auto &D = Drafts[File]; + updateVersion(D.D, Version); + std::time(&D.MTime); + D.D.Contents = std::make_shared(Contents); + return D.D.Version; } void DraftStore::removeDraft(PathRef File) { @@ -87,5 +90,39 @@ void DraftStore::removeDraft(PathRef File) { Drafts.erase(File); } +namespace { + +/// A read only MemoryBuffer shares ownership of a ref counted string. The +/// shared string object must not be modified while an owned by this buffer. +class SharedStringBuffer : public llvm::MemoryBuffer { + const std::shared_ptr BufferContents; + const std::string Name; + +public: + BufferKind getBufferKind() const override { + return MemoryBuffer::MemoryBuffer_Malloc; + } + + StringRef getBufferIdentifier() const override { return Name; } + + SharedStringBuffer(std::shared_ptr Data, StringRef Name) + : BufferContents(std::move(Data)), Name(Name) { + assert(BufferContents && "Can't create from empty shared_ptr"); + MemoryBuffer::init(BufferContents->c_str(), + BufferContents->c_str() + BufferContents->size(), + /*RequiresNullTerminator=*/true); + } +}; +} // namespace + +llvm::IntrusiveRefCntPtr DraftStore::asVFS() const { + auto MemFS = llvm::makeIntrusiveRefCnt(); + std::lock_guard Guard(Mutex); + for (const auto &Draft : Drafts) + MemFS->addFile(Draft.getKey(), Draft.getValue().MTime, + std::make_unique( + Draft.getValue().D.Contents, Draft.getKey())); + return MemFS; +} } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/DraftStore.h b/clang-tools-extra/clangd/DraftStore.h index e997272bd6b4..6b50b23995a0 100644 --- a/clang-tools-extra/clangd/DraftStore.h +++ b/clang-tools-extra/clangd/DraftStore.h @@ -13,6 +13,7 @@ #include "support/Path.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Support/VirtualFileSystem.h" #include #include #include @@ -27,7 +28,7 @@ namespace clangd { class DraftStore { public: struct Draft { - std::string Contents; + std::shared_ptr Contents; std::string Version; }; @@ -47,9 +48,15 @@ class DraftStore { /// Remove the draft from the store. void removeDraft(PathRef File); + llvm::IntrusiveRefCntPtr asVFS() const; + private: + struct DraftAndTime { + Draft D; + std::time_t MTime; + }; mutable std::mutex Mutex; - llvm::StringMap Drafts; + llvm::StringMap Drafts; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/Features.inc.in b/clang-tools-extra/clangd/Features.inc.in index c21d2b145571..5dfde58890b7 100644 --- a/clang-tools-extra/clangd/Features.inc.in +++ b/clang-tools-extra/clangd/Features.inc.in @@ -1,3 +1,4 @@ #define CLANGD_BUILD_XPC @CLANGD_BUILD_XPC@ #define CLANGD_ENABLE_REMOTE @CLANGD_ENABLE_REMOTE@ +#define ENABLE_GRPC_REFLECTION @ENABLE_GRPC_REFLECTION@ #define CLANGD_MALLOC_TRIM @CLANGD_MALLOC_TRIM@ diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp index bda5dcadf12e..e4846ac7a59d 100644 --- a/clang-tools-extra/clangd/FindSymbols.cpp +++ b/clang-tools-extra/clangd/FindSymbols.cpp @@ -376,10 +376,10 @@ class DocumentOutline { /// Builds the document outline for the generated AST. std::vector build() { - SymBuilder DummyRoot; + SymBuilder Root; for (auto &TopLevel : AST.getLocalTopLevelDecls()) - traverseDecl(TopLevel, DummyRoot); - return std::move(std::move(DummyRoot).build().children); + traverseDecl(TopLevel, Root); + return std::move(std::move(Root).build().children); } private: diff --git a/clang-tools-extra/clangd/Format.cpp b/clang-tools-extra/clangd/Format.cpp index d68a5bc672d0..3963bc21d403 100644 --- a/clang-tools-extra/clangd/Format.cpp +++ b/clang-tools-extra/clangd/Format.cpp @@ -23,7 +23,7 @@ namespace { /// as it isn't sure where the errors are and so can't correct. /// When editing, it's reasonable to assume code before the cursor is complete. void closeBrackets(std::string &Code, const format::FormatStyle &Style) { - SourceManagerForFile FileSM("dummy.cpp", Code); + SourceManagerForFile FileSM("mock_file.cpp", Code); auto &SM = FileSM.get(); FileID FID = SM.getMainFileID(); Lexer Lex(FID, SM.getBufferOrFake(FID), SM, diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 24038f0ec35f..fca19428192e 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -264,9 +264,11 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, StoreDiags ASTDiags; llvm::Optional Patch; + bool PreserveDiags = true; if (Preamble) { Patch = PreamblePatch::create(Filename, Inputs, *Preamble); Patch->apply(*CI); + PreserveDiags = Patch->preserveDiagnostics(); } auto Clang = prepareCompilerInstance( std::move(CI), PreamblePCH, @@ -421,6 +423,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, // tokens from running the preprocessor inside the checks (only // modernize-use-trailing-return-type does that today). syntax::TokenBuffer Tokens = std::move(CollectTokens).consume(); + // Makes SelectionTree build much faster. + Tokens.indexExpandedTokens(); std::vector ParsedDecls = Action->takeTopLevelDecls(); // AST traversals should exclude the preamble, to avoid performance cliffs. Clang->getASTContext().setTraversalScope(ParsedDecls); @@ -441,14 +445,20 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, // CompilerInstance won't run this callback, do it directly. ASTDiags.EndSourceFile(); - std::vector Diags = CompilerInvocationDiags; - // Add diagnostics from the preamble, if any. - if (Preamble) - Diags.insert(Diags.end(), Preamble->Diags.begin(), Preamble->Diags.end()); - // Finally, add diagnostics coming from the AST. - { - std::vector D = ASTDiags.take(CTContext.getPointer()); - Diags.insert(Diags.end(), D.begin(), D.end()); + llvm::Optional> Diags; + // FIXME: Also skip generation of diagnostics alltogether to speed up ast + // builds when we are patching a stale preamble. + if (PreserveDiags) { + Diags = CompilerInvocationDiags; + // Add diagnostics from the preamble, if any. + if (Preamble) + Diags->insert(Diags->end(), Preamble->Diags.begin(), + Preamble->Diags.end()); + // Finally, add diagnostics coming from the AST. + { + std::vector D = ASTDiags.take(CTContext.getPointer()); + Diags->insert(Diags->end(), D.begin(), D.end()); + } } return ParsedAST(Inputs.Version, std::move(Preamble), std::move(Clang), std::move(Action), std::move(Tokens), std::move(Macros), @@ -493,14 +503,12 @@ llvm::ArrayRef ParsedAST::getLocalTopLevelDecls() { const MainFileMacros &ParsedAST::getMacros() const { return Macros; } -const std::vector &ParsedAST::getDiagnostics() const { return Diags; } - std::size_t ParsedAST::getUsedBytes() const { auto &AST = getASTContext(); // FIXME(ibiryukov): we do not account for the dynamically allocated part of // Message and Fixes inside each diagnostic. - std::size_t Total = - clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags); + std::size_t Total = clangd::getUsedBytes(LocalTopLevelDecls) + + (Diags ? clangd::getUsedBytes(*Diags) : 0); // FIXME: the rest of the function is almost a direct copy-paste from // libclang's clang_getCXTUResourceUsage. We could share the implementation. @@ -541,8 +549,8 @@ ParsedAST::ParsedAST(llvm::StringRef Version, std::unique_ptr Action, syntax::TokenBuffer Tokens, MainFileMacros Macros, std::vector LocalTopLevelDecls, - std::vector Diags, IncludeStructure Includes, - CanonicalIncludes CanonIncludes) + llvm::Optional> Diags, + IncludeStructure Includes, CanonicalIncludes CanonIncludes) : Version(Version), Preamble(std::move(Preamble)), Clang(std::move(Clang)), Action(std::move(Action)), Tokens(std::move(Tokens)), Macros(std::move(Macros)), Diags(std::move(Diags)), diff --git a/clang-tools-extra/clangd/ParsedAST.h b/clang-tools-extra/clangd/ParsedAST.h index 263a097b14cb..c1ce6fce7029 100644 --- a/clang-tools-extra/clangd/ParsedAST.h +++ b/clang-tools-extra/clangd/ParsedAST.h @@ -88,7 +88,9 @@ class ParsedAST { /// (These should be const, but RecursiveASTVisitor requires Decl*). ArrayRef getLocalTopLevelDecls(); - const std::vector &getDiagnostics() const; + const llvm::Optional> &getDiagnostics() const { + return Diags; + } /// Returns the estimated size of the AST and the accessory structures, in /// bytes. Does not include the size of the preamble. @@ -120,7 +122,7 @@ class ParsedAST { std::unique_ptr Clang, std::unique_ptr Action, syntax::TokenBuffer Tokens, MainFileMacros Macros, std::vector LocalTopLevelDecls, - std::vector Diags, IncludeStructure Includes, + llvm::Optional> Diags, IncludeStructure Includes, CanonicalIncludes CanonIncludes); std::string Version; @@ -142,8 +144,8 @@ class ParsedAST { /// All macro definitions and expansions in the main file. MainFileMacros Macros; - // Data, stored after parsing. - std::vector Diags; + // Data, stored after parsing. None if AST was built with a stale preamble. + llvm::Optional> Diags; // Top-level decls inside the current file. Not that this does not include // top-level decls from the preamble. std::vector LocalTopLevelDecls; diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h index 1de1d6cfe5fa..5b9d17840214 100644 --- a/clang-tools-extra/clangd/Preamble.h +++ b/clang-tools-extra/clangd/Preamble.h @@ -126,6 +126,9 @@ class PreamblePatch { /// Returns textual patch contents. llvm::StringRef text() const { return PatchContents; } + /// Whether diagnostics generated using this patch are trustable. + bool preserveDiagnostics() const { return PatchContents.empty(); } + private: PreamblePatch() = default; std::string PatchContents; diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index b3ff124df4de..099c8531d341 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -414,6 +414,12 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R, if (auto Implicit = Window->getBoolean("implicitWorkDoneProgressCreate")) R.ImplicitProgressCreation = *Implicit; } + if (auto *General = O->getObject("general")) { + if (auto *StaleRequestSupport = General->getObject("staleRequestSupport")) { + if (auto Cancel = StaleRequestSupport->getBoolean("cancel")) + R.CancelsStaleRequests = *Cancel; + } + } if (auto *OffsetEncoding = O->get("offsetEncoding")) { R.offsetEncoding.emplace(); if (!fromJSON(*OffsetEncoding, *R.offsetEncoding, @@ -744,7 +750,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) { bool fromJSON(const llvm::json::Value &Params, WorkspaceSymbolParams &R, llvm::json::Path P) { llvm::json::ObjectMapper O(Params, P); - return O && O.map("query", R.query); + return O && O.map("query", R.query) && + mapOptOrNull(Params, "limit", R.limit, P); } llvm::json::Value toJSON(const Command &C) { @@ -845,7 +852,8 @@ bool fromJSON(const llvm::json::Value &Params, CompletionContext &R, bool fromJSON(const llvm::json::Value &Params, CompletionParams &R, llvm::json::Path P) { - if (!fromJSON(Params, static_cast(R), P)) + if (!fromJSON(Params, static_cast(R), P) || + !mapOptOrNull(Params, "limit", R.limit, P)) return false; if (auto *Context = Params.getAsObject()->get("context")) return fromJSON(*Context, R.context, P.field("context")); diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index c6074abcb04e..8e90f1f47831 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -475,6 +475,10 @@ struct ClientCapabilities { /// window.implicitWorkDoneProgressCreate bool ImplicitProgressCreation = false; + /// Whether the client claims to cancel stale requests. + /// general.staleRequestSupport.cancel + bool CancelsStaleRequests = false; + /// Whether the client implementation supports a refresh request sent from the /// server to the client. bool SemanticTokenRefreshSupport = false; @@ -1052,8 +1056,13 @@ bool operator==(const SymbolDetails &, const SymbolDetails &); /// The parameters of a Workspace Symbol Request. struct WorkspaceSymbolParams { - /// A non-empty query string + /// A query string to filter symbols by. + /// Clients may send an empty string here to request all the symbols. std::string query; + + /// Max results to return, overriding global default. 0 means no limit. + /// Clangd extension. + llvm::Optional limit; }; bool fromJSON(const llvm::json::Value &, WorkspaceSymbolParams &, llvm::json::Path); @@ -1102,6 +1111,10 @@ bool fromJSON(const llvm::json::Value &, CompletionContext &, llvm::json::Path); struct CompletionParams : TextDocumentPositionParams { CompletionContext context; + + /// Max results to return, overriding global default. 0 means no limit. + /// Clangd extension. + llvm::Optional limit; }; bool fromJSON(const llvm::json::Value &, CompletionParams &, llvm::json::Path); diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index 0b4965c42715..cf06eac01a34 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -294,7 +294,7 @@ class HighlightingsBuilder { HighlightingToken &addToken(SourceLocation Loc, HighlightingKind Kind) { Loc = getHighlightableSpellingToken(Loc, SourceMgr); if (Loc.isInvalid()) - return Dummy; + return InvalidHighlightingToken; const auto *Tok = TB.spelledTokenAt(Loc); assert(Tok); return addToken( @@ -395,7 +395,8 @@ class HighlightingsBuilder { const SourceManager &SourceMgr; const LangOptions &LangOpts; std::vector Tokens; - HighlightingToken Dummy; // returned from addToken(InvalidLoc) + // returned from addToken(InvalidLoc) + HighlightingToken InvalidHighlightingToken; }; llvm::Optional scopeModifier(const NamedDecl *D) { diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp index 14cde561474e..5a9cf05ea818 100644 --- a/clang-tools-extra/clangd/SourceCode.cpp +++ b/clang-tools-extra/clangd/SourceCode.cpp @@ -599,7 +599,7 @@ lex(llvm::StringRef Code, const LangOptions &LangOpts, Action) { // FIXME: InMemoryFileAdapter crashes unless the buffer is null terminated! std::string NullTerminatedCode = Code.str(); - SourceManagerForFile FileSM("dummy.cpp", NullTerminatedCode); + SourceManagerForFile FileSM("mock_file_name.cpp", NullTerminatedCode); auto &SM = FileSM.get(); for (const auto &Tok : syntax::tokenize(SM.getMainFileID(), SM, LangOpts)) Action(Tok, SM); @@ -1091,15 +1091,8 @@ llvm::Error applyChange(std::string &Contents, "computed range length ({1}).", *Change.rangeLength, ComputedRangeLength); - std::string NewContents; - NewContents.reserve(*StartIndex + Change.text.length() + - (Contents.length() - *EndIndex)); + Contents.replace(*StartIndex, *EndIndex - *StartIndex, Change.text); - NewContents = Contents.substr(0, *StartIndex); - NewContents += Change.text; - NewContents += Contents.substr(*EndIndex); - - std::swap(Contents, NewContents); return llvm::Error::success(); } diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 306f690aac63..435deb6ec162 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -1519,13 +1519,6 @@ void TUScheduler::remove(PathRef File) { // preamble of several open headers. } -llvm::StringMap TUScheduler::getAllFileContents() const { - llvm::StringMap Results; - for (auto &It : Files) - Results.try_emplace(It.getKey(), It.getValue()->Contents); - return Results; -} - void TUScheduler::run(llvm::StringRef Name, llvm::StringRef Path, llvm::unique_function Action) { runWithSemaphore(Name, Path, std::move(Action), Barrier); diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index 8749915aa757..8df2c019053e 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -235,9 +235,6 @@ class TUScheduler { /// if requested with WantDiags::Auto or WantDiags::Yes. void remove(PathRef File); - /// Returns a snapshot of all file buffer contents, per last update(). - llvm::StringMap getAllFileContents() const; - /// Schedule an async task with no dependencies. /// Path may be empty (it is used only to set the Context). void run(llvm::StringRef Name, llvm::StringRef Path, diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index 1f821f8edd1e..65bbbcd28b40 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -162,10 +162,10 @@ SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) { SymbolLocation getPreferredLocation(const Location &ASTLoc, const SymbolLocation &IdxLoc, std::string &Scratch) { - // Also use a dummy symbol for the index location so that other fields (e.g. + // Also use a mock symbol for the index location so that other fields (e.g. // definition) are not factored into the preference. Symbol ASTSym, IdxSym; - ASTSym.ID = IdxSym.ID = SymbolID("dummy_id"); + ASTSym.ID = IdxSym.ID = SymbolID("mock_symbol_id"); ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, Scratch); IdxSym.CanonicalDeclaration = IdxLoc; auto Merged = mergeSymbol(ASTSym, IdxSym); diff --git a/clang-tools-extra/clangd/fuzzer/CMakeLists.txt b/clang-tools-extra/clangd/fuzzer/CMakeLists.txt index 778b61158304..18cab4b41e1a 100644 --- a/clang-tools-extra/clangd/fuzzer/CMakeLists.txt +++ b/clang-tools-extra/clangd/fuzzer/CMakeLists.txt @@ -9,7 +9,7 @@ set(LLVM_LINK_COMPONENTS # This fuzzer runs on oss-fuzz, so keep it around even if it looks unreferenced. add_llvm_fuzzer(clangd-fuzzer clangd-fuzzer.cpp - DUMMY_MAIN DummyClangdMain.cpp + DUMMY_MAIN FuzzerClangdMain.cpp ) clang_target_link_libraries(clangd-fuzzer diff --git a/clang-tools-extra/clangd/fuzzer/DummyClangdMain.cpp b/clang-tools-extra/clangd/fuzzer/FuzzerClangdMain.cpp similarity index 91% rename from clang-tools-extra/clangd/fuzzer/DummyClangdMain.cpp rename to clang-tools-extra/clangd/fuzzer/FuzzerClangdMain.cpp index cd5a61217511..7b10dbb78201 100644 --- a/clang-tools-extra/clangd/fuzzer/DummyClangdMain.cpp +++ b/clang-tools-extra/clangd/fuzzer/FuzzerClangdMain.cpp @@ -1,4 +1,4 @@ -//===---- DummyClangdMain.cpp - Entry point to sanity check the fuzzer ----===// +//===--- FuzzerClangdMain.cpp - Entry point to sanity check the fuzzer ----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp index 4741ef622512..f7269b686552 100644 --- a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp +++ b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp @@ -28,22 +28,14 @@ void CanonicalIncludes::addMapping(llvm::StringRef Path, /// Used to minimize the number of lookups in suffix path mappings. constexpr int MaxSuffixComponents = 3; -llvm::StringRef -CanonicalIncludes::mapHeader(llvm::StringRef Header, - llvm::StringRef QualifiedName) const { +llvm::StringRef CanonicalIncludes::mapHeader(llvm::StringRef Header) const { assert(!Header.empty()); - if (StdSymbolMapping) { - auto SE = StdSymbolMapping->find(QualifiedName); - if (SE != StdSymbolMapping->end()) - return SE->second; - } - auto MapIt = FullPathMapping.find(Header); if (MapIt != FullPathMapping.end()) return MapIt->second; if (!StdSuffixHeaderMapping) - return Header; + return ""; int Components = 1; @@ -56,7 +48,11 @@ CanonicalIncludes::mapHeader(llvm::StringRef Header, if (MappingIt != StdSuffixHeaderMapping->end()) return MappingIt->second; } - return Header; + return ""; +} + +llvm::StringRef CanonicalIncludes::mapSymbol(llvm::StringRef QName) const { + return StdSymbolMapping ? StdSymbolMapping->lookup(QName) : ""; } std::unique_ptr diff --git a/clang-tools-extra/clangd/index/CanonicalIncludes.h b/clang-tools-extra/clangd/index/CanonicalIncludes.h index da7dc46db778..36e33e9324dc 100644 --- a/clang-tools-extra/clangd/index/CanonicalIncludes.h +++ b/clang-tools-extra/clangd/index/CanonicalIncludes.h @@ -38,11 +38,11 @@ class CanonicalIncludes { /// Adds a string-to-string mapping from \p Path to \p CanonicalPath. void addMapping(llvm::StringRef Path, llvm::StringRef CanonicalPath); - /// Returns the canonical include for symbol with \p QualifiedName. - /// \p Header is the file the declaration was reachable from. - /// Header itself will be returned if there is no relevant mapping. - llvm::StringRef mapHeader(llvm::StringRef Header, - llvm::StringRef QualifiedName) const; + /// Returns the overridden include for symbol with \p QualifiedName, or "". + llvm::StringRef mapSymbol(llvm::StringRef QualifiedName) const; + + /// Returns the overridden include for for files in \p Header, or "". + llvm::StringRef mapHeader(llvm::StringRef Header) const; /// Adds mapping for system headers and some special symbols (e.g. STL symbols /// in need to be mapped individually). Approximately, the following diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp index b91c66b88770..eb9648c2a6ae 100644 --- a/clang-tools-extra/clangd/index/FileIndex.cpp +++ b/clang-tools-extra/clangd/index/FileIndex.cpp @@ -77,9 +77,9 @@ SlabTuple indexSymbols(ASTContext &AST, std::shared_ptr PP, SymbolCollector Collector(std::move(CollectorOpts)); Collector.setPreprocessor(PP); + index::indexTopLevelDecls(AST, *PP, DeclsToIndex, Collector, IndexOpts); if (MacroRefsToIndex) Collector.handleMacros(*MacroRefsToIndex); - index::indexTopLevelDecls(AST, *PP, DeclsToIndex, Collector, IndexOpts); const auto &SM = AST.getSourceManager(); const auto *MainFileEntry = SM.getFileEntryForID(SM.getMainFileID()); diff --git a/clang-tools-extra/clangd/index/Index.h b/clang-tools-extra/clangd/index/Index.h index 91f7990312c7..04e67bc8df54 100644 --- a/clang-tools-extra/clangd/index/Index.h +++ b/clang-tools-extra/clangd/index/Index.h @@ -149,8 +149,9 @@ class SymbolIndex { /// Returns function which checks if the specified file was used to build this /// index or not. The function must only be called while the index is alive. - virtual llvm::unique_function - indexedFiles() const = 0; + using IndexedFiles = + llvm::unique_function; + virtual IndexedFiles indexedFiles() const = 0; /// Returns estimated size of index (in bytes). virtual size_t estimateMemoryUsage() const = 0; diff --git a/clang-tools-extra/clangd/index/Merge.cpp b/clang-tools-extra/clangd/index/Merge.cpp index 54793cf566e8..54bb1ee06a05 100644 --- a/clang-tools-extra/clangd/index/Merge.cpp +++ b/clang-tools-extra/clangd/index/Merge.cpp @@ -22,6 +22,19 @@ namespace clang { namespace clangd { +namespace { + +// Returns true if file defining/declaring \p S is covered by \p Index. +bool isIndexAuthoritative(const SymbolIndex::IndexedFiles &Index, + const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems to + // be enough to check only the definition if it exists. + const char *OwningFile = + S.Definition ? S.Definition.FileURI : S.CanonicalDeclaration.FileURI; + return (Index(OwningFile) & IndexContents::Symbols) != IndexContents::None; +} +} // namespace + bool MergedIndex::fuzzyFind( const FuzzyFindRequest &Req, llvm::function_ref Callback) const { @@ -37,36 +50,44 @@ bool MergedIndex::fuzzyFind( unsigned DynamicCount = 0; unsigned StaticCount = 0; unsigned MergedCount = 0; + // Number of results ignored due to staleness. + unsigned StaticDropped = 0; More |= Dynamic->fuzzyFind(Req, [&](const Symbol &S) { ++DynamicCount; DynB.insert(S); }); SymbolSlab Dyn = std::move(DynB).build(); - llvm::DenseSet SeenDynamicSymbols; + llvm::DenseSet ReportedDynSymbols; { auto DynamicContainsFile = Dynamic->indexedFiles(); More |= Static->fuzzyFind(Req, [&](const Symbol &S) { - // We expect the definition to see the canonical declaration, so it seems - // to be enough to check only the definition if it exists. - if ((DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI) & - IndexContents::Symbols) != IndexContents::None) - return; - auto DynS = Dyn.find(S.ID); ++StaticCount; - if (DynS == Dyn.end()) - return Callback(S); - ++MergedCount; - SeenDynamicSymbols.insert(S.ID); - Callback(mergeSymbol(*DynS, S)); + auto DynS = Dyn.find(S.ID); + // If symbol also exist in the dynamic index, just merge and report. + if (DynS != Dyn.end()) { + ++MergedCount; + ReportedDynSymbols.insert(S.ID); + return Callback(mergeSymbol(*DynS, S)); + } + + // Otherwise, if the dynamic index owns the symbol's file, it means static + // index is stale just drop the symbol. + if (isIndexAuthoritative(DynamicContainsFile, S)) { + ++StaticDropped; + return; + } + + // If not just report the symbol from static index as is. + return Callback(S); }); } SPAN_ATTACH(Tracer, "dynamic", DynamicCount); SPAN_ATTACH(Tracer, "static", StaticCount); + SPAN_ATTACH(Tracer, "static_dropped", StaticDropped); SPAN_ATTACH(Tracer, "merged", MergedCount); for (const Symbol &S : Dyn) - if (!SeenDynamicSymbols.count(S.ID)) + if (!ReportedDynSymbols.count(S.ID)) Callback(S); return More; } @@ -83,18 +104,21 @@ void MergedIndex::lookup( { auto DynamicContainsFile = Dynamic->indexedFiles(); Static->lookup(Req, [&](const Symbol &S) { - // We expect the definition to see the canonical declaration, so it seems - // to be enough to check only the definition if it exists. - if ((DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI) & - IndexContents::Symbols) != IndexContents::None) + // If we've seen the symbol before, just merge. + if (const Symbol *Sym = B.find(S.ID)) { + RemainingIDs.erase(S.ID); + return Callback(mergeSymbol(*Sym, S)); + } + + // If symbol is missing in dynamic index, and dynamic index owns the + // symbol's file. Static index is stale, just drop the symbol. + if (isIndexAuthoritative(DynamicContainsFile, S)) return; - const Symbol *Sym = B.find(S.ID); + + // Dynamic index doesn't know about this file, just use the symbol from + // static index. RemainingIDs.erase(S.ID); - if (!Sym) - Callback(S); - else - Callback(mergeSymbol(*Sym, S)); + Callback(S); }); } for (const auto &ID : RemainingIDs) diff --git a/clang-tools-extra/clangd/index/ProjectAware.cpp b/clang-tools-extra/clangd/index/ProjectAware.cpp index 80ebaf903b4c..a6cdc86fdc24 100644 --- a/clang-tools-extra/clangd/index/ProjectAware.cpp +++ b/clang-tools-extra/clangd/index/ProjectAware.cpp @@ -57,7 +57,10 @@ class ProjectAwareIndex : public SymbolIndex { llvm::unique_function indexedFiles() const override; - ProjectAwareIndex(IndexFactory Gen) : Gen(std::move(Gen)) {} + ProjectAwareIndex(IndexFactory Gen, bool Sync) : Gen(std::move(Gen)) { + if (!Sync) + Tasks = std::make_unique(); + } private: // Returns the index associated with current context, if any. @@ -68,7 +71,7 @@ class ProjectAwareIndex : public SymbolIndex { mutable llvm::DenseMap> IndexForSpec; - mutable AsyncTaskRunner Tasks; + mutable std::unique_ptr Tasks; const IndexFactory Gen; }; @@ -131,14 +134,15 @@ SymbolIndex *ProjectAwareIndex::getIndex() const { std::lock_guard Lock(Mu); auto Entry = IndexForSpec.try_emplace(External, nullptr); if (Entry.second) - Entry.first->getSecond() = Gen(External, Tasks); + Entry.first->getSecond() = Gen(External, Tasks.get()); return Entry.first->second.get(); } } // namespace -std::unique_ptr createProjectAwareIndex(IndexFactory Gen) { +std::unique_ptr createProjectAwareIndex(IndexFactory Gen, + bool Sync) { assert(Gen); - return std::make_unique(std::move(Gen)); + return std::make_unique(std::move(Gen), Sync); } } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/index/ProjectAware.h b/clang-tools-extra/clangd/index/ProjectAware.h index af98ba612751..888ef3add2eb 100644 --- a/clang-tools-extra/clangd/index/ProjectAware.h +++ b/clang-tools-extra/clangd/index/ProjectAware.h @@ -19,15 +19,16 @@ namespace clangd { /// A functor to create an index for an external index specification. Functor /// should perform any high latency operation in a separate thread through -/// AsyncTaskRunner. +/// AsyncTaskRunner, if set. using IndexFactory = std::function( - const Config::ExternalIndexSpec &, AsyncTaskRunner &)>; + const Config::ExternalIndexSpec &, AsyncTaskRunner *)>; /// Returns an index that answers queries using external indices. IndexFactory -/// specifies how to generate an index from an external source. +/// specifies how to generate an index from an external source. If \p Sync is +/// set, index won't own any asnyc task runner. /// IndexFactory must be injected because this code cannot depend on the remote /// index client. -std::unique_ptr createProjectAwareIndex(IndexFactory); +std::unique_ptr createProjectAwareIndex(IndexFactory, bool Sync); } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index b1363c1f9cef..84d0ca9bbbd1 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -48,31 +48,6 @@ const NamedDecl &getTemplateOrThis(const NamedDecl &ND) { return ND; } -// Returns a URI of \p Path. Firstly, this makes the \p Path absolute using the -// current working directory of the given SourceManager if the Path is not an -// absolute path. If failed, this resolves relative paths against \p FallbackDir -// to get an absolute path. Then, this tries creating an URI for the absolute -// path with schemes specified in \p Opts. This returns an URI with the first -// working scheme, if there is any; otherwise, this returns None. -// -// The Path can be a path relative to the build directory, or retrieved from -// the SourceManager. -std::string toURI(const SourceManager &SM, llvm::StringRef Path, - const SymbolCollector::Options &Opts) { - llvm::SmallString<128> AbsolutePath(Path); - if (auto File = SM.getFileManager().getFile(Path)) { - if (auto CanonPath = getCanonicalPath(*File, SM)) { - AbsolutePath = *CanonPath; - } - } - // We don't perform is_absolute check in an else branch because makeAbsolute - // might return a relative path on some InMemoryFileSystems. - if (!llvm::sys::path::is_absolute(AbsolutePath) && !Opts.FallbackDir.empty()) - llvm::sys::fs::make_absolute(Opts.FallbackDir, AbsolutePath); - llvm::sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/true); - return URI::create(AbsolutePath).toString(); -} - // Checks whether the decl is a private symbol in a header generated by // protobuf compiler. // FIXME: make filtering extensible when there are more use cases for symbol @@ -139,25 +114,6 @@ getTokenRange(SourceLocation TokLoc, const SourceManager &SM, CreatePosition(TokLoc.getLocWithOffset(TokenLength))}; } -// Return the symbol location of the token at \p TokLoc. -llvm::Optional -getTokenLocation(SourceLocation TokLoc, const SourceManager &SM, - const SymbolCollector::Options &Opts, - const clang::LangOptions &LangOpts, - std::string &FileURIStorage) { - auto Path = SM.getFilename(TokLoc); - if (Path.empty()) - return None; - FileURIStorage = toURI(SM, Path, Opts); - SymbolLocation Result; - Result.FileURI = FileURIStorage.c_str(); - auto Range = getTokenRange(TokLoc, SM, LangOpts); - Result.Start = Range.first; - Result.End = Range.second; - - return Result; -} - // Checks whether \p ND is a good candidate to be the *canonical* declaration of // its symbol (e.g. a go-to-declaration target). This overrides the default of // using Clang's canonical declaration, which is the first in the TU. @@ -198,10 +154,178 @@ llvm::Optional indexableRelation(const index::SymbolRelation &R) { } // namespace +// Encapsulates decisions about how to record header paths in the index, +// including filename normalization, URI conversion etc. +// Expensive checks are cached internally. +class SymbolCollector::HeaderFileURICache { + // Weird double-indirect access to PP, which might not be ready yet when + // HeaderFiles is created but will be by the time it's used. + // (IndexDataConsumer::setPreprocessor can happen before or after initialize) + const std::shared_ptr &PP; + const SourceManager &SM; + const CanonicalIncludes *Includes; + llvm::StringRef FallbackDir; + llvm::DenseMap CacheFEToURI; + llvm::StringMap CachePathToURI; + llvm::DenseMap CacheFIDToInclude; + +public: + HeaderFileURICache(const std::shared_ptr &PP, + const SourceManager &SM, + const SymbolCollector::Options &Opts) + : PP(PP), SM(SM), Includes(Opts.Includes), FallbackDir(Opts.FallbackDir) { + } + + // Returns a canonical URI for the file \p FE. + // We attempt to make the path absolute first. + const std::string &toURI(const FileEntry *FE) { + auto R = CacheFEToURI.try_emplace(FE); + if (R.second) { + auto CanonPath = getCanonicalPath(FE, SM); + R.first->second = &toURIInternal(CanonPath ? *CanonPath : FE->getName()); + } + return *R.first->second; + } + + // Returns a canonical URI for \p Path. + // If the file is in the FileManager, use that to canonicalize the path. + // We attempt to make the path absolute in any case. + const std::string &toURI(llvm::StringRef Path) { + if (auto File = SM.getFileManager().getFile(Path)) + return toURI(*File); + return toURIInternal(Path); + } + + // Gets a canonical include (URI of the header or
or "header") for + // header of \p FID (which should usually be the *expansion* file). + // This does not account for any per-symbol overrides! + // Returns "" if includes should not be inserted for this file. + llvm::StringRef getIncludeHeader(FileID FID) { + auto R = CacheFIDToInclude.try_emplace(FID); + if (R.second) + R.first->second = getIncludeHeaderUncached(FID); + return R.first->second; + } + +private: + // This takes care of making paths absolute and path->URI caching, but no + // FileManager-based canonicalization. + const std::string &toURIInternal(llvm::StringRef Path) { + auto R = CachePathToURI.try_emplace(Path); + if (R.second) { + llvm::SmallString<256> AbsPath = Path; + if (!llvm::sys::path::is_absolute(AbsPath) && !FallbackDir.empty()) + llvm::sys::fs::make_absolute(FallbackDir, AbsPath); + assert(llvm::sys::path::is_absolute(AbsPath) && + "If the VFS can't make paths absolute, a FallbackDir must be " + "provided"); + llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true); + R.first->second = URI::create(AbsPath).toString(); + } + return R.first->second; + } + + llvm::StringRef getIncludeHeaderUncached(FileID FID) { + const FileEntry *FE = SM.getFileEntryForID(FID); + if (!FE || FE->getName().empty()) + return ""; + llvm::StringRef Filename = FE->getName(); + // If a file is mapped by canonical headers, use that mapping, regardless + // of whether it's an otherwise-good header (header guards etc). + if (Includes) { + llvm::StringRef Canonical = Includes->mapHeader(Filename); + if (!Canonical.empty()) { + // If we had a mapping, always use it. + if (Canonical.startswith("<") || Canonical.startswith("\"")) + return Canonical; + return toURI(Canonical); + } + } + if (!isSelfContainedHeader(FID, FE)) { + // A .inc or .def file is often included into a real header to define + // symbols (e.g. LLVM tablegen files). + if (Filename.endswith(".inc") || Filename.endswith(".def")) + // Don't use cache reentrantly due to iterator invalidation. + return getIncludeHeaderUncached(SM.getFileID(SM.getIncludeLoc(FID))); + // Conservatively refuse to insert #includes to files without guards. + return ""; + } + // Standard case: just insert the file itself. + return toURI(FE); + } + + bool isSelfContainedHeader(FileID FID, const FileEntry *FE) { + // FIXME: Should files that have been #import'd be considered + // self-contained? That's really a property of the includer, + // not of the file. + if (!PP->getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE) && + !PP->getHeaderSearchInfo().hasFileBeenImported(FE)) + return false; + // This pattern indicates that a header can't be used without + // particular preprocessor state, usually set up by another header. + if (isDontIncludeMeHeader(SM.getBufferData(FID))) + return false; + return true; + } + + // Is Line an #if or #ifdef directive? + static bool isIf(llvm::StringRef Line) { + Line = Line.ltrim(); + if (!Line.consume_front("#")) + return false; + Line = Line.ltrim(); + return Line.startswith("if"); + } + + // Is Line an #error directive mentioning includes? + static bool isErrorAboutInclude(llvm::StringRef Line) { + Line = Line.ltrim(); + if (!Line.consume_front("#")) + return false; + Line = Line.ltrim(); + if (!Line.startswith("error")) + return false; + return Line.contains_lower("includ"); // Matches "include" or "including". + } + + // Heuristically headers that only want to be included via an umbrella. + static bool isDontIncludeMeHeader(llvm::StringRef Content) { + llvm::StringRef Line; + // Only sniff up to 100 lines or 10KB. + Content = Content.take_front(100 * 100); + for (unsigned I = 0; I < 100 && !Content.empty(); ++I) { + std::tie(Line, Content) = Content.split('\n'); + if (isIf(Line) && isErrorAboutInclude(Content.split('\n').first)) + return true; + } + return false; + } +}; + +// Return the symbol location of the token at \p TokLoc. +llvm::Optional +SymbolCollector::getTokenLocation(SourceLocation TokLoc) { + const auto &SM = ASTCtx->getSourceManager(); + auto *FE = SM.getFileEntryForID(SM.getFileID(TokLoc)); + if (!FE) + return None; + + SymbolLocation Result; + Result.FileURI = HeaderFileURIs->toURI(FE).c_str(); + auto Range = getTokenRange(TokLoc, SM, ASTCtx->getLangOpts()); + Result.Start = Range.first; + Result.End = Range.second; + + return Result; +} + SymbolCollector::SymbolCollector(Options Opts) : Opts(std::move(Opts)) {} +SymbolCollector::~SymbolCollector() = default; void SymbolCollector::initialize(ASTContext &Ctx) { ASTCtx = &Ctx; + HeaderFileURIs = std::make_unique( + PP, ASTCtx->getSourceManager(), Opts); CompletionAllocator = std::make_shared(); CompletionTUInfo = std::make_unique(CompletionAllocator); @@ -262,7 +386,7 @@ bool SymbolCollector::handleDeclOccurrence( const Decl *D, index::SymbolRoleSet Roles, llvm::ArrayRef Relations, SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) { - assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set."); + assert(ASTCtx && PP.get() && HeaderFileURIs); assert(CompletionAllocator && CompletionTUInfo); assert(ASTNode.OrigD); // Indexing API puts canonical decl into D, which might not have a valid @@ -383,12 +507,12 @@ bool SymbolCollector::handleDeclOccurrence( } void SymbolCollector::handleMacros(const MainFileMacros &MacroRefsToIndex) { - assert(PP.get()); + assert(HeaderFileURIs && PP.get()); const auto &SM = PP->getSourceManager(); const auto *MainFileEntry = SM.getFileEntryForID(SM.getMainFileID()); assert(MainFileEntry); - const auto MainFileURI = toURI(SM, MainFileEntry->getName(), Opts); + const std::string &MainFileURI = HeaderFileURIs->toURI(MainFileEntry); // Add macro references. for (const auto &IDToRefs : MacroRefsToIndex.MacroRefs) { for (const auto &MacroRef : IDToRefs.second) { @@ -432,7 +556,8 @@ bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name, const auto &SM = PP->getSourceManager(); auto DefLoc = MI->getDefinitionLoc(); // Also avoid storing predefined macros like __DBL_MIN__. - if (SM.isWrittenInBuiltinFile(DefLoc)) + if (SM.isWrittenInBuiltinFile(DefLoc) || + Name->getName() == "__GCC_HAVE_DWARF2_CFI_ASM") return true; auto ID = getSymbolID(Name->getName(), MI, SM); @@ -485,11 +610,9 @@ bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name, } S.SymInfo = index::getSymbolInfoForMacro(*MI); S.Origin = Opts.Origin; - std::string FileURI; // FIXME: use the result to filter out symbols. shouldIndexFile(SM.getFileID(Loc)); - if (auto DeclLoc = - getTokenLocation(DefLoc, SM, Opts, PP->getLangOpts(), FileURI)) + if (auto DeclLoc = getTokenLocation(DefLoc)) S.CanonicalDeclaration = *DeclLoc; CodeCompletionResult SymbolCompletion(Name); @@ -577,44 +700,48 @@ void SymbolCollector::finish() { } // Fill in IncludeHeaders. // We delay this until end of TU so header guards are all resolved. - // Symbols in slabs aren't mutable, so insert() has to walk all the strings - // :-( - for (const auto &Entry : IncludeFiles) + llvm::SmallString<128> QName; + for (const auto &Entry : IncludeFiles) { if (const Symbol *S = Symbols.find(Entry.first)) { - if (auto Header = getIncludeHeader(*S, Entry.second)) { + llvm::StringRef IncludeHeader; + // Look for an overridden include header for this symbol specifically. + if (Opts.Includes) { + QName = S->Scope; + QName.append(S->Name); + IncludeHeader = Opts.Includes->mapSymbol(QName); + if (!IncludeHeader.empty()) { + if (IncludeHeader.front() != '"' && IncludeHeader.front() != '<') + IncludeHeader = HeaderFileURIs->toURI(IncludeHeader); + else if (IncludeHeader == "" && QName == "std::move" && + S->Signature.contains(',')) + IncludeHeader = ""; + } + } + // Otherwise find the approprate include header for the defining file. + if (IncludeHeader.empty()) + IncludeHeader = HeaderFileURIs->getIncludeHeader(Entry.second); + + // Symbols in slabs aren't mutable, insert() has to walk all the strings + if (!IncludeHeader.empty()) { Symbol NewSym = *S; - NewSym.IncludeHeaders.push_back({std::move(*Header), 1}); + NewSym.IncludeHeaders.push_back({IncludeHeader, 1}); Symbols.insert(NewSym); } } + } const auto &SM = ASTCtx->getSourceManager(); - llvm::DenseMap URICache; - auto GetURI = [&](FileID FID) -> llvm::Optional { - auto Found = URICache.find(FID); - if (Found == URICache.end()) { - if (auto *FileEntry = SM.getFileEntryForID(FID)) { - auto FileURI = toURI(SM, FileEntry->getName(), Opts); - Found = URICache.insert({FID, FileURI}).first; - } else { - // Ignore cases where we can not find a corresponding file entry for - // given location, e.g. symbols formed via macro concatenation. - return None; - } - } - return Found->second; - }; auto CollectRef = [&](SymbolID ID, const SymbolRef &LocAndRole, bool Spelled = false) { auto FileID = SM.getFileID(LocAndRole.Loc); // FIXME: use the result to filter out references. shouldIndexFile(FileID); - if (auto FileURI = GetURI(FileID)) { + if (const auto *FE = SM.getFileEntryForID(FileID)) { auto Range = getTokenRange(LocAndRole.Loc, SM, ASTCtx->getLangOpts()); Ref R; R.Location.Start = Range.first; R.Location.End = Range.second; - R.Location.FileURI = FileURI->c_str(); + R.Location.FileURI = HeaderFileURIs->toURI(FE).c_str(); R.Kind = toRefKind(LocAndRole.Roles, Spelled); R.Container = getSymbolID(LocAndRole.Container); Refs.insert(ID, R); @@ -655,8 +782,6 @@ void SymbolCollector::finish() { ReferencedDecls.clear(); ReferencedMacros.clear(); DeclRefs.clear(); - FilesToIndexCache.clear(); - HeaderIsSelfContainedCache.clear(); IncludeFiles.clear(); } @@ -682,13 +807,11 @@ const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID, if (!IsMainFileOnly) S.Flags |= Symbol::VisibleOutsideFile; S.SymInfo = index::getSymbolInfo(&ND); - std::string FileURI; auto Loc = nameLocation(ND, SM); assert(Loc.isValid() && "Invalid source location for NamedDecl"); // FIXME: use the result to filter out symbols. shouldIndexFile(SM.getFileID(Loc)); - if (auto DeclLoc = - getTokenLocation(Loc, SM, Opts, ASTCtx->getLangOpts(), FileURI)) + if (auto DeclLoc = getTokenLocation(Loc)) S.CanonicalDeclaration = *DeclLoc; S.Origin = Opts.Origin; @@ -742,114 +865,15 @@ void SymbolCollector::addDefinition(const NamedDecl &ND, // This is not ideal, but avoids duplicating the "is this a definition" check // in clang::index. We should only see one definition. Symbol S = DeclSym; - std::string FileURI; const auto &SM = ND.getASTContext().getSourceManager(); auto Loc = nameLocation(ND, SM); // FIXME: use the result to filter out symbols. shouldIndexFile(SM.getFileID(Loc)); - if (auto DefLoc = - getTokenLocation(Loc, SM, Opts, ASTCtx->getLangOpts(), FileURI)) + if (auto DefLoc = getTokenLocation(Loc)) S.Definition = *DefLoc; Symbols.insert(S); } -/// Gets a canonical include (URI of the header or
or "header") for -/// header of \p FID (which should usually be the *expansion* file). -/// Returns None if includes should not be inserted for this file. -llvm::Optional SymbolCollector::getIncludeHeader(const Symbol &S, - FileID FID) { - const SourceManager &SM = ASTCtx->getSourceManager(); - const FileEntry *FE = SM.getFileEntryForID(FID); - if (!FE || FE->getName().empty()) - return llvm::None; - llvm::StringRef Filename = FE->getName(); - // If a file is mapped by canonical headers, use that mapping, regardless - // of whether it's an otherwise-good header (header guards etc). - if (Opts.Includes) { - llvm::SmallString<256> QName = S.Scope; - QName.append(S.Name); - llvm::StringRef Canonical = Opts.Includes->mapHeader(Filename, QName); - // If we had a mapping, always use it. - if (Canonical.startswith("<") || Canonical.startswith("\"")) { - // Hack: there are two std::move() overloads from different headers. - // CanonicalIncludes returns the common one-arg one from . - if (Canonical == "" && S.Name == "move" && - S.Signature.contains(',')) - Canonical = ""; - return Canonical.str(); - } - if (Canonical != Filename) - return toURI(SM, Canonical, Opts); - } - if (!isSelfContainedHeader(FID)) { - // A .inc or .def file is often included into a real header to define - // symbols (e.g. LLVM tablegen files). - if (Filename.endswith(".inc") || Filename.endswith(".def")) - return getIncludeHeader(S, SM.getFileID(SM.getIncludeLoc(FID))); - // Conservatively refuse to insert #includes to files without guards. - return llvm::None; - } - // Standard case: just insert the file itself. - return toURI(SM, Filename, Opts); -} - -bool SymbolCollector::isSelfContainedHeader(FileID FID) { - // The real computation (which will be memoized). - auto Compute = [&] { - const SourceManager &SM = ASTCtx->getSourceManager(); - const FileEntry *FE = SM.getFileEntryForID(FID); - if (!FE) - return false; - // FIXME: Should files that have been #import'd be considered - // self-contained? That's really a property of the includer, - // not of the file. - if (!PP->getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE) && - !PP->getHeaderSearchInfo().hasFileBeenImported(FE)) - return false; - // This pattern indicates that a header can't be used without - // particular preprocessor state, usually set up by another header. - if (isDontIncludeMeHeader(SM.getBufferData(FID))) - return false; - return true; - }; - - auto R = HeaderIsSelfContainedCache.try_emplace(FID, false); - if (R.second) - R.first->second = Compute(); - return R.first->second; -} - -// Is Line an #if or #ifdef directive? -static bool isIf(llvm::StringRef Line) { - Line = Line.ltrim(); - if (!Line.consume_front("#")) - return false; - Line = Line.ltrim(); - return Line.startswith("if"); -} -// Is Line an #error directive mentioning includes? -static bool isErrorAboutInclude(llvm::StringRef Line) { - Line = Line.ltrim(); - if (!Line.consume_front("#")) - return false; - Line = Line.ltrim(); - if (!Line.startswith("error")) - return false; - return Line.contains_lower("includ"); // Matches "include" or "including". -} - -bool SymbolCollector::isDontIncludeMeHeader(llvm::StringRef Content) { - llvm::StringRef Line; - // Only sniff up to 100 lines or 10KB. - Content = Content.take_front(100 * 100); - for (unsigned I = 0; I < 100 && !Content.empty(); ++I) { - std::tie(Line, Content) = Content.split('\n'); - if (isIf(Line) && isErrorAboutInclude(Content.split('\n').first)) - return true; - } - return false; -} - bool SymbolCollector::shouldIndexFile(FileID FID) { if (!Opts.FileFilter) return true; diff --git a/clang-tools-extra/clangd/index/SymbolCollector.h b/clang-tools-extra/clangd/index/SymbolCollector.h index 92f847f3d8f3..af184fde69c6 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.h +++ b/clang-tools-extra/clangd/index/SymbolCollector.h @@ -91,6 +91,7 @@ class SymbolCollector : public index::IndexDataConsumer { }; SymbolCollector(Options Opts); + ~SymbolCollector(); /// Returns true is \p ND should be collected. static bool shouldCollectSymbol(const NamedDecl &ND, const ASTContext &ASTCtx, @@ -132,10 +133,9 @@ class SymbolCollector : public index::IndexDataConsumer { void processRelations(const NamedDecl &ND, const SymbolID &ID, ArrayRef Relations); + llvm::Optional getTokenLocation(SourceLocation TokLoc); + llvm::Optional getIncludeHeader(const Symbol &S, FileID); - bool isSelfContainedHeader(FileID); - // Heuristically headers that only want to be included via an umbrella. - static bool isDontIncludeMeHeader(llvm::StringRef); // All Symbols collected from the AST. SymbolSlab::Builder Symbols; @@ -175,7 +175,10 @@ class SymbolCollector : public index::IndexDataConsumer { llvm::DenseMap CanonicalDecls; // Cache whether to index a file or not. llvm::DenseMap FilesToIndexCache; - llvm::DenseMap HeaderIsSelfContainedCache; + // Encapsulates calculations and caches around header paths, which headers + // to insert for which symbol, etc. + class HeaderFileURICache; + std::unique_ptr HeaderFileURIs; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/index/remote/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/CMakeLists.txt index eaa000b745e5..2aa6e9b6cfa9 100644 --- a/clang-tools-extra/clangd/index/remote/CMakeLists.txt +++ b/clang-tools-extra/clangd/index/remote/CMakeLists.txt @@ -1,5 +1,7 @@ if (CLANGD_ENABLE_REMOTE) generate_protos(RemoteIndexProto "Index.proto") + generate_protos(MonitoringServiceProto "MonitoringService.proto" + GRPC) generate_protos(RemoteIndexServiceProto "Service.proto" DEPENDS "Index.proto" GRPC) @@ -8,6 +10,7 @@ if (CLANGD_ENABLE_REMOTE) target_link_libraries(RemoteIndexServiceProto PRIVATE RemoteIndexProto + MonitoringServiceProto ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../) @@ -36,6 +39,6 @@ if (CLANGD_ENABLE_REMOTE) add_subdirectory(marshalling) add_subdirectory(server) else() - # Provides a dummy implementation of clangdRemoteIndex. + # Provides a no-op implementation of clangdRemoteIndex. add_subdirectory(unimplemented) endif() diff --git a/clang-tools-extra/clangd/index/remote/MonitoringService.proto b/clang-tools-extra/clangd/index/remote/MonitoringService.proto new file mode 100644 index 000000000000..75d807c19005 --- /dev/null +++ b/clang-tools-extra/clangd/index/remote/MonitoringService.proto @@ -0,0 +1,27 @@ +//===--- MonitoringService.proto - CLangd Remote index monitoring service -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +syntax = "proto2"; + +package clang.clangd.remote.v1; + +message MonitoringInfoRequest {} +message MonitoringInfoReply { + // Time since the server started (in seconds). + optional uint64 uptime_seconds = 1; + // Time since the index was built on the indexing machine. + optional uint64 index_age_seconds = 2; + // ID of the indexed commit in Version Control System. + optional string index_commit_hash = 3; + // URL to the index file. + optional string index_link = 4; +} + +service Monitor { + rpc MonitoringInfo(MonitoringInfoRequest) returns (MonitoringInfoReply) {} +} diff --git a/clang-tools-extra/clangd/index/remote/Service.proto b/clang-tools-extra/clangd/index/remote/Service.proto index 4e39ff9ec666..7c7efa530200 100644 --- a/clang-tools-extra/clangd/index/remote/Service.proto +++ b/clang-tools-extra/clangd/index/remote/Service.proto @@ -23,4 +23,3 @@ service SymbolIndex { rpc Relations(RelationsRequest) returns (stream RelationsReply) {} } - diff --git a/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt index e6959db6bbd8..f1131e53c919 100644 --- a/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt +++ b/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt @@ -14,7 +14,10 @@ target_link_libraries(clangd-index-server clangDaemon clangdSupport + MonitoringServiceProto RemoteIndexProto RemoteIndexServiceProto clangdRemoteMarshalling + + ${REFLECTION_LIBRARY} ) diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp index 3de2c38f7c08..f3cf131bb8a5 100644 --- a/clang-tools-extra/clangd/index/remote/server/Server.cpp +++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp @@ -6,8 +6,12 @@ // //===----------------------------------------------------------------------===// +#include "Features.inc" #include "Index.pb.h" +#include "MonitoringService.grpc.pb.h" +#include "MonitoringService.pb.h" #include "Service.grpc.pb.h" +#include "Service.pb.h" #include "index/Index.h" #include "index/Serialization.h" #include "index/Symbol.h" @@ -35,6 +39,10 @@ #include #include +#if ENABLE_GRPC_REFLECTION +#include +#endif + namespace clang { namespace clangd { namespace remote { @@ -283,11 +291,46 @@ class RemoteIndexServer final : public v1::SymbolIndex::Service { clangd::SymbolIndex &Index; }; +class Monitor final : public v1::Monitor::Service { +public: + Monitor(llvm::sys::TimePoint<> IndexAge) + : StartTime(std::chrono::system_clock::now()), IndexBuildTime(IndexAge) {} + + void updateIndex(llvm::sys::TimePoint<> UpdateTime) { + IndexBuildTime.exchange(UpdateTime); + } + +private: + // FIXME(kirillbobyrev): Most fields should be populated when the index + // reloads (probably in adjacent metadata.txt file next to loaded .idx) but + // they aren't right now. + grpc::Status MonitoringInfo(grpc::ServerContext *Context, + const v1::MonitoringInfoRequest *Request, + v1::MonitoringInfoReply *Reply) override { + Reply->set_uptime_seconds(std::chrono::duration_cast( + std::chrono::system_clock::now() - StartTime) + .count()); + // FIXME(kirillbobyrev): We are currently making use of the last + // modification time of the index artifact to deduce its age. This is wrong + // as it doesn't account for the indexing delay. Propagate some metadata + // with the index artifacts to indicate time of the commit we indexed. + Reply->set_index_age_seconds( + std::chrono::duration_cast( + std::chrono::system_clock::now() - IndexBuildTime.load()) + .count()); + return grpc::Status::OK; + } + + const llvm::sys::TimePoint<> StartTime; + std::atomic> IndexBuildTime; +}; + // Detect changes in \p IndexPath file and load new versions of the index // whenever they become available. void hotReload(clangd::SwapIndex &Index, llvm::StringRef IndexPath, llvm::vfs::Status &LastStatus, - llvm::IntrusiveRefCntPtr &FS) { + llvm::IntrusiveRefCntPtr &FS, + Monitor &Monitor) { auto Status = FS->status(IndexPath); // Requested file is same as loaded index: no reload is needed. if (!Status || (Status->getLastModificationTime() == @@ -304,21 +347,26 @@ void hotReload(clangd::SwapIndex &Index, llvm::StringRef IndexPath, return; } Index.reset(std::move(NewIndex)); + Monitor.updateIndex(Status->getLastModificationTime()); log("New index version loaded. Last modification time: {0}, size: {1} bytes.", Status->getLastModificationTime(), Status->getSize()); } void runServerAndWait(clangd::SymbolIndex &Index, llvm::StringRef ServerAddress, - llvm::StringRef IndexPath) { + llvm::StringRef IndexPath, Monitor &Monitor) { RemoteIndexServer Service(Index, IndexRoot); grpc::EnableDefaultHealthCheckService(true); +#if ENABLE_GRPC_REFLECTION + grpc::reflection::InitProtoReflectionServerBuilderPlugin(); +#endif grpc::ServerBuilder Builder; Builder.AddListeningPort(ServerAddress.str(), grpc::InsecureServerCredentials()); Builder.AddChannelArgument(GRPC_ARG_MAX_CONNECTION_IDLE_MS, IdleTimeoutSeconds * 1000); Builder.RegisterService(&Service); + Builder.RegisterService(&Monitor); std::unique_ptr Server(Builder.BuildAndStart()); log("Server listening on {0}", ServerAddress); @@ -417,16 +465,18 @@ int main(int argc, char *argv[]) { } clang::clangd::SwapIndex Index(std::move(SymIndex)); - std::thread HotReloadThread([&Index, &Status, &FS]() { + Monitor Monitor(Status->getLastModificationTime()); + + std::thread HotReloadThread([&Index, &Status, &FS, &Monitor]() { llvm::vfs::Status LastStatus = *Status; static constexpr auto RefreshFrequency = std::chrono::seconds(30); while (!clang::clangd::shutdownRequested()) { - hotReload(Index, llvm::StringRef(IndexPath), LastStatus, FS); + hotReload(Index, llvm::StringRef(IndexPath), LastStatus, FS, Monitor); std::this_thread::sleep_for(RefreshFrequency); } }); - runServerAndWait(Index, ServerAddress, IndexPath); + runServerAndWait(Index, ServerAddress, IndexPath, Monitor); HotReloadThread.join(); } diff --git a/clang-tools-extra/clangd/quality/CompletionModel.cmake b/clang-tools-extra/clangd/quality/CompletionModel.cmake index 60c6d2aa8433..41bc2ed1890b 100644 --- a/clang-tools-extra/clangd/quality/CompletionModel.cmake +++ b/clang-tools-extra/clangd/quality/CompletionModel.cmake @@ -5,8 +5,8 @@ # will define a C++ class called ${cpp_class} - which may be a # namespace-qualified class name. function(gen_decision_forest model filename cpp_class) - set(model_compiler ${CMAKE_SOURCE_DIR}/../clang-tools-extra/clangd/quality/CompletionModelCodegen.py) - + set(model_compiler ${LLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR}/clangd/quality/CompletionModelCodegen.py) + set(output_dir ${CMAKE_CURRENT_BINARY_DIR}) set(header_file ${output_dir}/${filename}.h) set(cpp_file ${output_dir}/${filename}.cpp) diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp index cc6830d0ab37..5431046836ca 100644 --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -22,14 +22,17 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ParentMapContext.h" #include "clang/AST/Stmt.h" +#include "clang/Basic/CharInfo.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Tooling/Syntax/Tokens.h" #include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/JSON.h" #include namespace clang { @@ -178,8 +181,7 @@ enum class ReasonToReject { UnsupportedSymbol, AmbiguousSymbol, - // name validation. - RenameToKeywords, + // name validation. FIXME: reconcile with InvalidName SameName, }; @@ -241,8 +243,6 @@ llvm::Error makeError(ReasonToReject Reason) { return "symbol is not a supported kind (e.g. namespace, macro)"; case ReasonToReject::AmbiguousSymbol: return "there are multiple symbols at the given location"; - case ReasonToReject::RenameToKeywords: - return "the chosen name is a keyword"; case ReasonToReject::SameName: return "new name is the same as the old name"; } @@ -437,6 +437,7 @@ struct InvalidName { enum Kind { Keywords, Conflict, + BadIdentifier, }; Kind K; std::string Details; @@ -447,6 +448,8 @@ std::string toString(InvalidName::Kind K) { return "Keywords"; case InvalidName::Conflict: return "Conflict"; + case InvalidName::BadIdentifier: + return "BadIdentifier"; } llvm_unreachable("unhandled InvalidName kind"); } @@ -459,12 +462,31 @@ llvm::Error makeError(InvalidName Reason) { Reason.Details); case InvalidName::Conflict: return llvm::formatv("conflict with the symbol in {0}", Reason.Details); + case InvalidName::BadIdentifier: + return llvm::formatv("the chosen name \"{0}\" is not a valid identifier", + Reason.Details); } llvm_unreachable("unhandled InvalidName kind"); }; return error("invalid name: {0}", Message(Reason)); } +static bool mayBeValidIdentifier(llvm::StringRef Ident) { + assert(llvm::json::isUTF8(Ident)); + if (Ident.empty()) + return false; + // We don't check all the rules for non-ascii characters (most are allowed). + bool AllowDollar = true; // lenient + if (llvm::isASCII(Ident.front()) && + !isIdentifierHead(Ident.front(), AllowDollar)) + return false; + for (char C : Ident) { + if (llvm::isASCII(C) && !isIdentifierBody(C, AllowDollar)) + return false; + } + return true; +} + // Check if we can rename the given RenameDecl into NewName. // Return details if the rename would produce a conflict. llvm::Optional checkName(const NamedDecl &RenameDecl, @@ -476,6 +498,8 @@ llvm::Optional checkName(const NamedDecl &RenameDecl, llvm::Optional Result; if (isKeyword(NewName, ASTCtx.getLangOpts())) Result = InvalidName{InvalidName::Keywords, NewName.str()}; + else if (!mayBeValidIdentifier(NewName)) + Result = InvalidName{InvalidName::BadIdentifier, NewName.str()}; else { // Name conflict detection. // Function conflicts are subtle (overloading), so ignore them. @@ -586,10 +610,10 @@ findOccurrencesOutsideFile(const NamedDecl &RenameDecl, // index (background index) is relatively stale. We choose the dirty buffers // as the file content we rename on, and fallback to file content on disk if // there is no dirty buffer. -llvm::Expected renameOutsideFile( - const NamedDecl &RenameDecl, llvm::StringRef MainFilePath, - llvm::StringRef NewName, const SymbolIndex &Index, size_t MaxLimitFiles, - llvm::function_ref(PathRef)> GetFileContent) { +llvm::Expected +renameOutsideFile(const NamedDecl &RenameDecl, llvm::StringRef MainFilePath, + llvm::StringRef NewName, const SymbolIndex &Index, + size_t MaxLimitFiles, llvm::vfs::FileSystem &FS) { trace::Span Tracer("RenameOutsideFile"); auto AffectedFiles = findOccurrencesOutsideFile(RenameDecl, MainFilePath, Index, MaxLimitFiles); @@ -599,13 +623,16 @@ llvm::Expected renameOutsideFile( for (auto &FileAndOccurrences : *AffectedFiles) { llvm::StringRef FilePath = FileAndOccurrences.first(); - auto AffectedFileCode = GetFileContent(FilePath); - if (!AffectedFileCode) { - elog("Fail to read file content: {0}", AffectedFileCode.takeError()); + auto ExpBuffer = FS.getBufferForFile(FilePath); + if (!ExpBuffer) { + elog("Fail to read file content: Fail to open file {0}: {1}", FilePath, + ExpBuffer.getError().message()); continue; } + + auto AffectedFileCode = (*ExpBuffer)->getBuffer(); auto RenameRanges = - adjustRenameRanges(*AffectedFileCode, RenameDecl.getNameAsString(), + adjustRenameRanges(AffectedFileCode, RenameDecl.getNameAsString(), std::move(FileAndOccurrences.second), RenameDecl.getASTContext().getLangOpts()); if (!RenameRanges) { @@ -617,7 +644,7 @@ llvm::Expected renameOutsideFile( FilePath); } auto RenameEdit = - buildRenameEdit(FilePath, *AffectedFileCode, *RenameRanges, NewName); + buildRenameEdit(FilePath, AffectedFileCode, *RenameRanges, NewName); if (!RenameEdit) return error("failed to rename in file {0}: {1}", FilePath, RenameEdit.takeError()); @@ -668,28 +695,13 @@ void findNearMiss( } // namespace llvm::Expected rename(const RenameInputs &RInputs) { + assert(!RInputs.Index == !RInputs.FS && + "Index and FS must either both be specified or both null."); trace::Span Tracer("Rename flow"); const auto &Opts = RInputs.Opts; ParsedAST &AST = RInputs.AST; const SourceManager &SM = AST.getSourceManager(); llvm::StringRef MainFileCode = SM.getBufferData(SM.getMainFileID()); - auto GetFileContent = [&RInputs, - &SM](PathRef AbsPath) -> llvm::Expected { - llvm::Optional DirtyBuffer; - if (RInputs.GetDirtyBuffer && - (DirtyBuffer = RInputs.GetDirtyBuffer(AbsPath))) - return std::move(*DirtyBuffer); - - auto Content = - SM.getFileManager().getVirtualFileSystem().getBufferForFile(AbsPath); - if (!Content) - return error("Fail to open file {0}: {1}", AbsPath, - Content.getError().message()); - if (!*Content) - return error("Got no buffer for file {0}", AbsPath); - - return (*Content)->getBuffer().str(); - }; // Try to find the tokens adjacent to the cursor position. auto Loc = sourceLocationInMainFile(SM, RInputs.Pos); if (!Loc) @@ -765,7 +777,7 @@ llvm::Expected rename(const RenameInputs &RInputs) { RenameDecl, RInputs.MainFilePath, RInputs.NewName, *RInputs.Index, Opts.LimitFiles == 0 ? std::numeric_limits::max() : Opts.LimitFiles, - GetFileContent); + *RInputs.FS); if (!OtherFilesEdits) return OtherFilesEdits.takeError(); Result.GlobalChanges = *OtherFilesEdits; diff --git a/clang-tools-extra/clangd/refactor/Rename.h b/clang-tools-extra/clangd/refactor/Rename.h index 7eca4610eaca..03ae4f7f1563 100644 --- a/clang-tools-extra/clangd/refactor/Rename.h +++ b/clang-tools-extra/clangd/refactor/Rename.h @@ -21,11 +21,6 @@ namespace clangd { class ParsedAST; class SymbolIndex; -/// Gets dirty buffer for a given file \p AbsPath. -/// Returns None if there is no dirty buffer for the given file. -using DirtyBufferGetter = - llvm::function_ref(PathRef AbsPath)>; - struct RenameOptions { /// The maximum number of affected files (0 means no limit), only meaningful /// when AllowCrossFile = true. @@ -42,14 +37,14 @@ struct RenameInputs { ParsedAST &AST; llvm::StringRef MainFilePath; + // The filesystem to query when performing cross file renames. + // If this is set, Index must also be set, likewise if this is nullptr, Index + // must also be nullptr. + llvm::IntrusiveRefCntPtr FS = nullptr; + const SymbolIndex *Index = nullptr; RenameOptions Opts = {}; - // When set, used by the rename to get file content for all rename-related - // files. - // If there is no corresponding dirty buffer, we will use the file content - // from disk. - DirtyBufferGetter GetDirtyBuffer = nullptr; }; struct RenameResult { diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index 4cdd36cbd4c9..18c521119972 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -272,6 +272,10 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, if (MD->isStatic()) DelKeyword(tok::kw_static, {FD->getBeginLoc(), FD->getLocation()}); } + if (const auto *CD = dyn_cast(FD)) { + if (CD->isExplicit()) + DelKeyword(tok::kw_explicit, {FD->getBeginLoc(), FD->getLocation()}); + } if (Errors) return std::move(Errors); diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp index c603861c3d69..a4db11f1a364 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp @@ -376,7 +376,7 @@ bool eligibleForExtraction(const SelectionTree::Node *N) { if (llvm::isa(E) || llvm::isa(E)) return false; - // Extracting Exprs like a = 1 gives dummy = a = 1 which isn't useful. + // Extracting Exprs like a = 1 gives placeholder = a = 1 which isn't useful. // FIXME: we could still hoist the assignment, and leave the variable there? ParsedBinaryOperator BinOp; if (BinOp.parse(*N) && BinaryOperator::isAssignmentOp(BinOp.Kind)) @@ -387,7 +387,7 @@ bool eligibleForExtraction(const SelectionTree::Node *N) { if (!Parent) return false; // We don't want to extract expressions used as statements, that would leave - // a `dummy;` around that has no effect. + // a `placeholder;` around that has no effect. // Unfortunately because the AST doesn't have ExprStmt, we have to check in // this roundabout way. if (childExprIsStmt(Parent->ASTNode.get(), @@ -422,7 +422,7 @@ const SelectionTree::Node *computeExtractedExpr(const SelectionTree::Node *N) { llvm::isa(SelectedExpr)) if (const SelectionTree::Node *Call = getCallExpr(N)) TargetNode = Call; - // Extracting Exprs like a = 1 gives dummy = a = 1 which isn't useful. + // Extracting Exprs like a = 1 gives placeholder = a = 1 which isn't useful. if (const BinaryOperator *BinOpExpr = dyn_cast_or_null(SelectedExpr)) { if (BinOpExpr->getOpcode() == BinaryOperatorKind::BO_Assign) @@ -433,13 +433,13 @@ const SelectionTree::Node *computeExtractedExpr(const SelectionTree::Node *N) { return TargetNode; } -/// Extracts an expression to the variable dummy +/// Extracts an expression to the variable placeholder /// Before: /// int x = 5 + 4 * 3; /// ^^^^^ /// After: -/// auto dummy = 5 + 4; -/// int x = dummy * 3; +/// auto placeholder = 5 + 4; +/// int x = placeholder * 3; class ExtractVariable : public Tweak { public: const char *id() const override final; @@ -476,7 +476,7 @@ bool ExtractVariable::prepare(const Selection &Inputs) { Expected ExtractVariable::apply(const Selection &Inputs) { tooling::Replacements Result; // FIXME: get variable name from user or suggest based on type - std::string VarName = "dummy"; + std::string VarName = "placeholder"; SourceRange Range = Target->getExtractionChars(); // insert new variable declaration if (auto Err = Result.add(Target->insertDeclaration(VarName, Range))) diff --git a/clang-tools-extra/clangd/support/Trace.cpp b/clang-tools-extra/clangd/support/Trace.cpp index d69b1c2bbde5..9cfc58c37733 100644 --- a/clang-tools-extra/clangd/support/Trace.cpp +++ b/clang-tools-extra/clangd/support/Trace.cpp @@ -112,14 +112,14 @@ class JSONTracer : public EventTracer { "s", llvm::json::Object{{"id", FlowID}, {"name", "Context crosses threads"}, - {"cat", "dummy"}}, + {"cat", "mock_cat"}}, (*Parent)->TID, (*Parent)->StartTime); Tracer->jsonEvent( "f", llvm::json::Object{{"id", FlowID}, {"bp", "e"}, {"name", "Context crosses threads"}, - {"cat", "dummy"}}, + {"cat", "mock_cat"}}, TID); } } diff --git a/clang-tools-extra/clangd/test/log.test b/clang-tools-extra/clangd/test/log.test index 5d60c10eb917..7a53d361ddde 100644 --- a/clang-tools-extra/clangd/test/log.test +++ b/clang-tools-extra/clangd/test/log.test @@ -1,9 +1,9 @@ -# RUN: env CLANGD_FLAGS=-index-file=no-such-index not clangd -lit-test &1 >/dev/null | FileCheck %s +# RUN: env CLANGD_FLAGS=-compile-commands-dir=no-such-dir not clangd -lit-test &1 >/dev/null | FileCheck %s CHECK: I[{{.*}}]{{.*}} clangd version {{.*}} CHECK: Working directory: {{.*}} CHECK: argv[0]: clangd CHECK: argv[1]: -lit-test -CHECK: CLANGD_FLAGS: -index-file=no-such-index -CHECK: E[{{.*}}] Can't open no-such-index +CHECK: CLANGD_FLAGS: -compile-commands-dir=no-such-dir +CHECK: E[{{.*}}] Path specified by --compile-commands-dir does not exist. CHECK: Starting LSP over stdin/stdout diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp index 9e3e439ae70d..20b86daff8af 100644 --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -26,6 +26,7 @@ #include "ClangdLSPServer.h" #include "CodeComplete.h" +#include "Config.h" #include "GlobalCompilationDatabase.h" #include "Hover.h" #include "ParsedAST.h" @@ -93,7 +94,8 @@ class Checker { bool buildCommand(const ThreadsafeFS &TFS) { log("Loading compilation database..."); DirectoryBasedGlobalCompilationDatabase::Options CDBOpts(TFS); - CDBOpts.CompileCommandsDir = Opts.CompileCommandsDir; + CDBOpts.CompileCommandsDir = + Config::current().CompileFlags.CDBSearch.FixedCDBPath; std::unique_ptr BaseCDB = std::make_unique(CDBOpts); BaseCDB = getQueryDriverDatabase(llvm::makeArrayRef(Opts.QueryDriverGlobs), @@ -179,7 +181,7 @@ class Checker { elog("Failed to build AST"); return false; } - ErrCount += showErrors(llvm::makeArrayRef(AST->getDiagnostics()) + ErrCount += showErrors(llvm::makeArrayRef(*AST->getDiagnostics()) .drop_front(Preamble->Diags.size())); if (Opts.BuildDynamicSymbolIndex) { @@ -245,6 +247,9 @@ bool check(llvm::StringRef File, const ThreadsafeFS &TFS, } log("Testing on source file {0}", File); + auto ContextProvider = ClangdServer::createConfiguredContextProvider( + Opts.ConfigProvider, nullptr); + WithContext Ctx(ContextProvider("")); Checker C(File, Opts); if (!C.buildCommand(TFS) || !C.buildInvocation(TFS, Contents) || !C.buildAST()) diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 3afcd5f08333..c48821cba2c7 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -8,6 +8,8 @@ #include "ClangdLSPServer.h" #include "CodeComplete.h" +#include "Config.h" +#include "ConfigProvider.h" #include "Features.inc" #include "PathMapping.h" #include "Protocol.h" @@ -43,6 +45,7 @@ #include #include #include +#include #include #ifndef _WIN32 @@ -534,7 +537,7 @@ const char TestScheme::TestDir[] = "/clangd-test"; std::unique_ptr loadExternalIndex(const Config::ExternalIndexSpec &External, - AsyncTaskRunner &Tasks) { + AsyncTaskRunner *Tasks) { switch (External.Kind) { case Config::ExternalIndexSpec::Server: log("Associating {0} with remote index at {1}.", External.MountPoint, @@ -544,15 +547,94 @@ loadExternalIndex(const Config::ExternalIndexSpec &External, log("Associating {0} with monolithic index at {1}.", External.MountPoint, External.Location); auto NewIndex = std::make_unique(std::make_unique()); - Tasks.runAsync("Load-index:" + External.Location, - [File = External.Location, PlaceHolder = NewIndex.get()] { - if (auto Idx = loadIndex(File, /*UseDex=*/true)) - PlaceHolder->reset(std::move(Idx)); - }); + auto IndexLoadTask = [File = External.Location, + PlaceHolder = NewIndex.get()] { + if (auto Idx = loadIndex(File, /*UseDex=*/true)) + PlaceHolder->reset(std::move(Idx)); + }; + if (Tasks) { + Tasks->runAsync("Load-index:" + External.Location, + std::move(IndexLoadTask)); + } else { + IndexLoadTask(); + } return std::move(NewIndex); } llvm_unreachable("Invalid ExternalIndexKind."); } + +class FlagsConfigProvider : public config::Provider { +private: + config::CompiledFragment Frag; + + std::vector + getFragments(const config::Params &, + config::DiagnosticCallback) const override { + return {Frag}; + } + +public: + FlagsConfigProvider() { + llvm::Optional CDBSearch; + llvm::Optional IndexSpec; + llvm::Optional BGPolicy; + + // If --compile-commands-dir arg was invoked, check value and override + // default path. + if (!CompileCommandsDir.empty()) { + if (llvm::sys::fs::exists(CompileCommandsDir)) { + // We support passing both relative and absolute paths to the + // --compile-commands-dir argument, but we assume the path is absolute + // in the rest of clangd so we make sure the path is absolute before + // continuing. + llvm::SmallString<128> Path(CompileCommandsDir); + if (std::error_code EC = llvm::sys::fs::make_absolute(Path)) { + elog("Error while converting the relative path specified by " + "--compile-commands-dir to an absolute path: {0}. The argument " + "will be ignored.", + EC.message()); + } else { + CDBSearch = {Config::CDBSearchSpec::FixedDir, Path.str().str()}; + } + } else { + elog("Path specified by --compile-commands-dir does not exist. The " + "argument will be ignored."); + } + } + if (!IndexFile.empty()) { + Config::ExternalIndexSpec Spec; + Spec.Kind = Spec.File; + Spec.Location = IndexFile; + IndexSpec = std::move(Spec); + } +#if CLANGD_ENABLE_REMOTE + if (!RemoteIndexAddress.empty()) { + assert(!ProjectRoot.empty() && IndexFile.empty()); + Config::ExternalIndexSpec Spec; + Spec.Kind = Spec.Server; + Spec.Location = RemoteIndexAddress; + Spec.MountPoint = ProjectRoot; + IndexSpec = std::move(Spec); + BGPolicy = Config::BackgroundPolicy::Skip; + } +#endif + if (!EnableBackgroundIndex) { + BGPolicy = Config::BackgroundPolicy::Skip; + } + + Frag = [=](const config::Params &, Config &C) { + if (CDBSearch) + C.CompileFlags.CDBSearch = *CDBSearch; + if (IndexSpec) + C.Index.External = *IndexSpec; + if (BGPolicy) + C.Index.Background = *BGPolicy; + if (AllScopesCompletion.getNumOccurrences()) + C.Completion.AllScopes = AllScopesCompletion; + return true; + }; + } +}; } // namespace } // namespace clangd } // namespace clang @@ -693,29 +775,6 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var ClangdLSPServer::Options Opts; Opts.UseDirBasedCDB = (CompileArgsFrom == FilesystemCompileArgs); - // If --compile-commands-dir arg was invoked, check value and override default - // path. - if (!CompileCommandsDir.empty()) { - if (llvm::sys::fs::exists(CompileCommandsDir)) { - // We support passing both relative and absolute paths to the - // --compile-commands-dir argument, but we assume the path is absolute in - // the rest of clangd so we make sure the path is absolute before - // continuing. - llvm::SmallString<128> Path(CompileCommandsDir); - if (std::error_code EC = llvm::sys::fs::make_absolute(Path)) { - elog("Error while converting the relative path specified by " - "--compile-commands-dir to an absolute path: {0}. The argument " - "will be ignored.", - EC.message()); - } else { - Opts.CompileCommandsDir = std::string(Path.str()); - } - } else { - elog("Path specified by --compile-commands-dir does not exist. The " - "argument will be ignored."); - } - } - switch (PCHStorage) { case PCHStorageFlag::Memory: Opts.StorePreamblesInMemory = true; @@ -729,18 +788,6 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var Opts.BuildDynamicSymbolIndex = true; std::vector> IdxStack; std::unique_ptr StaticIdx; - std::future AsyncIndexLoad; // Block exit while loading the index. - if (!IndexFile.empty()) { - // Load the index asynchronously. Meanwhile SwapIndex returns no results. - SwapIndex *Placeholder; - StaticIdx.reset(Placeholder = new SwapIndex(std::make_unique())); - AsyncIndexLoad = runAsync([Placeholder] { - if (auto Idx = loadIndex(IndexFile, /*UseDex=*/true)) - Placeholder->reset(std::move(Idx)); - }); - if (Sync) - AsyncIndexLoad.wait(); - } #if CLANGD_ENABLE_REMOTE if (RemoteIndexAddress.empty() != ProjectRoot.empty()) { llvm::errs() << "remote-index-address and project-path have to be " @@ -750,8 +797,6 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var if (!RemoteIndexAddress.empty()) { if (IndexFile.empty()) { log("Connecting to remote index at {0}", RemoteIndexAddress); - StaticIdx = remote::getClient(RemoteIndexAddress, ProjectRoot); - EnableBackgroundIndex = false; } else { elog("When enabling remote index, IndexFile should not be specified. " "Only one can be used at time. Remote index will ignored."); @@ -759,7 +804,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var } #endif Opts.BackgroundIndex = EnableBackgroundIndex; - auto PAI = createProjectAwareIndex(loadExternalIndex); + auto PAI = createProjectAwareIndex(loadExternalIndex, Sync); if (StaticIdx) { IdxStack.emplace_back(std::move(StaticIdx)); IdxStack.emplace_back( @@ -783,7 +828,6 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var Opts.CodeComplete.IncludeIndicator.NoInsert.clear(); } Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets; - Opts.CodeComplete.AllScopes = AllScopesCompletion; Opts.CodeComplete.RunParser = CodeCompletionParse; Opts.CodeComplete.RankingModel = RankingModel; @@ -802,12 +846,13 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var } else { elog("Couldn't determine user config file, not loading"); } - std::vector ProviderPointers; - for (const auto &P : ProviderStack) - ProviderPointers.push_back(P.get()); - Config = config::Provider::combine(std::move(ProviderPointers)); - Opts.ConfigProvider = Config.get(); } + ProviderStack.push_back(std::make_unique()); + std::vector ProviderPointers; + for (const auto &P : ProviderStack) + ProviderPointers.push_back(P.get()); + Config = config::Provider::combine(std::move(ProviderPointers)); + Opts.ConfigProvider = Config.get(); // Create an empty clang-tidy option. TidyProvider ClangTidyOptProvider; diff --git a/clang-tools-extra/clangd/unittests/CanonicalIncludesTests.cpp b/clang-tools-extra/clangd/unittests/CanonicalIncludesTests.cpp index fa96a4579624..31f99b7615d3 100644 --- a/clang-tools-extra/clangd/unittests/CanonicalIncludesTests.cpp +++ b/clang-tools-extra/clangd/unittests/CanonicalIncludesTests.cpp @@ -20,11 +20,8 @@ TEST(CanonicalIncludesTest, CStandardLibrary) { Language.C11 = true; CI.addSystemHeadersMapping(Language); // Usual standard library symbols are mapped correctly. - EXPECT_EQ("", CI.mapHeader("path/stdio.h", "printf")); - // Suffix mapping isn't available for C, instead of mapping to ` we - // just leave the header as-is. - EXPECT_EQ("include/stdio.h", - CI.mapHeader("include/stdio.h", "unknown_symbol")); + EXPECT_EQ("", CI.mapSymbol("printf")); + EXPECT_EQ("", CI.mapSymbol("unknown_symbol")); } TEST(CanonicalIncludesTest, CXXStandardLibrary) { @@ -34,17 +31,16 @@ TEST(CanonicalIncludesTest, CXXStandardLibrary) { CI.addSystemHeadersMapping(Language); // Usual standard library symbols are mapped correctly. - EXPECT_EQ("", CI.mapHeader("path/vector.h", "std::vector")); - EXPECT_EQ("", CI.mapHeader("path/stdio.h", "std::printf")); + EXPECT_EQ("", CI.mapSymbol("std::vector")); + EXPECT_EQ("", CI.mapSymbol("std::printf")); // std::move is ambiguous, currently always mapped to - EXPECT_EQ("", - CI.mapHeader("libstdc++/bits/stl_algo.h", "std::move")); + EXPECT_EQ("", CI.mapSymbol("std::move")); // Unknown std symbols aren't mapped. - EXPECT_EQ("foo/bar.h", CI.mapHeader("foo/bar.h", "std::notathing")); + EXPECT_EQ("", CI.mapSymbol("std::notathing")); // iosfwd declares some symbols it doesn't own. - EXPECT_EQ("", CI.mapHeader("iosfwd", "std::ostream")); + EXPECT_EQ("", CI.mapSymbol("std::ostream")); // And (for now) we assume it owns the others. - EXPECT_EQ("", CI.mapHeader("iosfwd", "std::notwathing")); + EXPECT_EQ("", CI.mapHeader("iosfwd")); } TEST(CanonicalIncludesTest, PathMapping) { @@ -52,20 +48,8 @@ TEST(CanonicalIncludesTest, PathMapping) { CanonicalIncludes CI; CI.addMapping("foo/bar", ""); - EXPECT_EQ("", CI.mapHeader("foo/bar", "some::symbol")); - EXPECT_EQ("bar/bar", CI.mapHeader("bar/bar", "some::symbol")); -} - -TEST(CanonicalIncludesTest, SymbolMapping) { - // As used for standard library. - CanonicalIncludes CI; - LangOptions Language; - Language.CPlusPlus = true; - // Ensures 'std::vector' is mapped to ''. - CI.addSystemHeadersMapping(Language); - - EXPECT_EQ("", CI.mapHeader("foo/bar", "std::vector")); - EXPECT_EQ("foo/bar", CI.mapHeader("foo/bar", "other::symbol")); + EXPECT_EQ("", CI.mapHeader("foo/bar")); + EXPECT_EQ("", CI.mapHeader("bar/bar")); } TEST(CanonicalIncludesTest, Precedence) { @@ -76,15 +60,9 @@ TEST(CanonicalIncludesTest, Precedence) { CI.addSystemHeadersMapping(Language); // We added a mapping from some/path to . - ASSERT_EQ("", CI.mapHeader("some/path", "")); + ASSERT_EQ("", CI.mapHeader("some/path")); // We should have a path from 'bits/stl_vector.h' to ''. - ASSERT_EQ("", CI.mapHeader("bits/stl_vector.h", "")); - // We should also have a symbol mapping from 'std::map' to ''. - ASSERT_EQ("", CI.mapHeader("some/header.h", "std::map")); - - // And the symbol mapping should take precedence over paths mapping. - EXPECT_EQ("", CI.mapHeader("bits/stl_vector.h", "std::map")); - EXPECT_EQ("", CI.mapHeader("some/path", "std::map")); + ASSERT_EQ("", CI.mapHeader("bits/stl_vector.h")); } } // namespace diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp index 15320e8bd8e8..49e1f7aa93b6 100644 --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -407,9 +407,9 @@ TEST(ClangdServerTest, SearchLibDir) { // Put crtbegin.o into LibDir/64 to trick clang into thinking there's a gcc // installation there. - SmallString<64> DummyLibFile; - llvm::sys::path::append(DummyLibFile, LibDir, "64", "crtbegin.o"); - FS.Files[DummyLibFile] = ""; + SmallString<64> MockLibFile; + llvm::sys::path::append(MockLibFile, LibDir, "64", "crtbegin.o"); + FS.Files[MockLibFile] = ""; SmallString<64> IncludeDir("/randomusr/include/c++"); llvm::sys::path::append(IncludeDir, Version); diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 0ff1e83b7613..a57ae49f9159 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -1253,6 +1253,19 @@ TEST(SignatureHelpTest, Overloads) { EXPECT_EQ(0, Results.activeParameter); } +TEST(SignatureHelpTest, OverloadInitListRegression) { + auto Results = signatures(R"cpp( + struct A {int x;}; + struct B {B(A);}; + void f(); + int main() { + B b({1}); + f(^); + } + )cpp"); + EXPECT_THAT(Results.signatures, UnorderedElementsAre(Sig("f() -> void"))); +} + TEST(SignatureHelpTest, DefaultArgs) { auto Results = signatures(R"cpp( void bar(int x, int y = 0); diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp index d9aa171f3102..b68d7e5f5e17 100644 --- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp @@ -443,6 +443,22 @@ TEST_F(ConfigCompileTests, ExternalBlockMountPoint) { ASSERT_FALSE(Conf.Index.External); #endif } + +TEST_F(ConfigCompileTests, AllScopes) { + // Defaults to true. + EXPECT_TRUE(compileAndApply()); + EXPECT_TRUE(Conf.Completion.AllScopes); + + Frag = {}; + Frag.Completion.AllScopes = false; + EXPECT_TRUE(compileAndApply()); + EXPECT_FALSE(Conf.Completion.AllScopes); + + Frag = {}; + Frag.Completion.AllScopes = true; + EXPECT_TRUE(compileAndApply()); + EXPECT_TRUE(Conf.Completion.AllScopes); +} } // namespace } // namespace config } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp index e1c81344de20..0c216c208706 100644 --- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp @@ -10,10 +10,12 @@ #include "ConfigFragment.h" #include "ConfigTesting.h" #include "Protocol.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Testing/Support/SupportHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -164,6 +166,35 @@ TEST(ParseYAML, ExternalBlock) { EXPECT_THAT(*Results[0].Index.External.getValue()->Server, Val("bar")); } +TEST(ParseYAML, AllScopes) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +Completion: + AllScopes: True + )yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + ASSERT_THAT(Diags.Diagnostics, IsEmpty()); + ASSERT_EQ(Results.size(), 1u); + EXPECT_THAT(Results[0].Completion.AllScopes, llvm::ValueIs(Val(true))); +} + +TEST(ParseYAML, AllScopesWarn) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +Completion: + AllScopes: $diagrange[[Truex]] + )yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, + ElementsAre(AllOf(DiagMessage("AllScopes should be a boolean"), + DiagKind(llvm::SourceMgr::DK_Warning), + DiagPos(YAML.range("diagrange").start), + DiagRange(YAML.range("diagrange"))))); + ASSERT_EQ(Results.size(), 1u); + EXPECT_THAT(Results[0].Completion.AllScopes, testing::Eq(llvm::None)); +} } // namespace } // namespace config } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index aebb231f39f9..d5b4a08a4229 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -135,7 +135,7 @@ o]](); auto TU = TestTU::withCode(Test.code()); TU.ClangTidyProvider = addTidyChecks("google-explicit-constructor"); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), ElementsAre( // This range spans lines. AllOf(Diag(Test.range("typo"), @@ -173,14 +173,14 @@ o]](); TEST(DiagnosticsTest, FlagsMatter) { Annotations Test("[[void]] main() {} // error-ok"); auto TU = TestTU::withCode(Test.code()); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"), WithFix(Fix(Test.range(), "int", "change 'void' to 'int'"))))); // Same code built as C gets different diagnostics. TU.Filename = "Plain.c"; EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), ElementsAre(AllOf( Diag(Test.range(), "return type of 'main' is not 'int'"), WithFix(Fix(Test.range(), "int", "change return type to 'int'"))))); @@ -192,7 +192,7 @@ TEST(DiagnosticsTest, DiagnosticPreamble) { )cpp"); auto TU = TestTU::withCode(Test.code()); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), ElementsAre(::testing::AllOf( Diag(Test.range(), "'not-found.h' file not found"), DiagSource(Diag::Clang), DiagName("pp_file_not_found")))); @@ -209,7 +209,7 @@ TEST(DiagnosticsTest, DeduplicatedClangTidyDiagnostics) { "hicpp-uppercase-literal-suffix"); // Verify that we filter out the duplicated diagnostic message. EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre(::testing::AllOf( Diag(Test.range(), "floating point literal has suffix 'f', which is not uppercase"), @@ -229,7 +229,7 @@ TEST(DiagnosticsTest, DeduplicatedClangTidyDiagnostics) { // The check doesn't handle template instantiations which ends up emitting // duplicated messages, verify that we deduplicate them. EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre(::testing::AllOf( Diag(Test.range(), "floating point literal has suffix 'f', which is not uppercase"), @@ -254,7 +254,7 @@ TEST(DiagnosticsTest, ClangTidy) { "modernize-deprecated-headers," "modernize-use-trailing-return-type"); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre( AllOf(Diag(Test.range("deprecated"), "inclusion of deprecated C++ header 'assert.h'; consider " @@ -296,7 +296,7 @@ TEST(DiagnosticsTest, ClangTidyEOF) { TU.AdditionalFiles["a.h"] = TU.AdditionalFiles["b.h"] = ""; TU.ClangTidyProvider = addTidyChecks("llvm-include-order"); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), Contains(AllOf(Diag(Test.range(), "#includes are not sorted properly"), DiagSource(Diag::ClangTidy), DiagName("llvm-include-order")))); @@ -314,7 +314,7 @@ TEST(DiagnosticTest, TemplatesInHeaders) { TestTU TU = TestTU::withCode(Main.code()); TU.HeaderCode = Header.code().str(); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), ElementsAre(AllOf( Diag(Main.range(), "in template: base specifier must name a class"), WithNote(Diag(Header.range(), "error occurred here"), @@ -340,7 +340,7 @@ TEST(DiagnosticTest, MakeUnique) { } } )cpp"; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Main.range(), "in template: " @@ -368,7 +368,7 @@ TEST(DiagnosticTest, NoMultipleDiagnosticInFlight) { TestTU TU = TestTU::withCode(Main.code()); TU.ClangTidyProvider = addTidyChecks("modernize-loop-convert"); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre(::testing::AllOf( Diag(Main.range(), "use range-based for loop instead"), DiagSource(Diag::ClangTidy), DiagName("modernize-loop-convert")))); @@ -384,14 +384,14 @@ TEST(DiagnosticTest, RespectsDiagnosticConfig) { )cpp"); auto TU = TestTU::withCode(Main.code()); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), ElementsAre(Diag(Main.range(), "use of undeclared identifier 'unknown'"), Diag(Main.range("ret"), "void function 'x' should not return a value"))); Config Cfg; Cfg.Diagnostics.Suppress.insert("return-type"); WithContextValue WithCfg(Config::Key, std::move(Cfg)); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), ElementsAre(Diag(Main.range(), "use of undeclared identifier 'unknown'"))); } @@ -413,7 +413,7 @@ TEST(DiagnosticTest, ClangTidySuppressionComment) { TestTU TU = TestTU::withCode(Main.code()); TU.ClangTidyProvider = addTidyChecks("bugprone-integer-division"); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre(::testing::AllOf( Diag(Main.range(), "result of integer division used in a floating " "point context; possible loss of precision"), @@ -431,7 +431,7 @@ TEST(DiagnosticTest, ClangTidyWarningAsError) { TU.ClangTidyProvider = addTidyChecks("bugprone-integer-division", "bugprone-integer-division"); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre(::testing::AllOf( Diag(Main.range(), "result of integer division used in a floating " "point context; possible loss of precision"), @@ -450,7 +450,7 @@ TEST(DiagnosticTest, LongFixMessages) { )cpp"); TestTU TU = TestTU::withCode(Source.code()); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), ElementsAre(WithFix(Fix( Source.range(), "somereallyreallyreallyreallyreallyreallyreallyreallylongidentifier", @@ -466,7 +466,7 @@ n]] = 10; // error-ok } )cpp"); TU.Code = std::string(Source.code()); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), ElementsAre(WithFix( Fix(Source.range(), "ident", "change 'ide\\…' to 'ident'")))); } @@ -481,7 +481,7 @@ TEST(DiagnosticTest, ClangTidySuppressionCommentTrumpsWarningAsError) { TestTU TU = TestTU::withCode(Main.code()); TU.ClangTidyProvider = addTidyChecks("bugprone-integer-division", "bugprone-integer-division"); - EXPECT_THAT(TU.build().getDiagnostics(), UnorderedElementsAre()); + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre()); } TEST(DiagnosticTest, ClangTidyNoLiteralDataInMacroToken) { @@ -496,7 +496,7 @@ TEST(DiagnosticTest, ClangTidyNoLiteralDataInMacroToken) { )cpp"); TestTU TU = TestTU::withCode(Main.code()); TU.ClangTidyProvider = addTidyChecks("bugprone-bad-signal-to-kill-thread"); - EXPECT_THAT(TU.build().getDiagnostics(), UnorderedElementsAre()); // no-crash + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre()); // no-crash } TEST(DiagnosticTest, ElseAfterReturnRange) { @@ -513,7 +513,7 @@ TEST(DiagnosticTest, ElseAfterReturnRange) { TestTU TU = TestTU::withCode(Main.code()); TU.ClangTidyProvider = addTidyChecks("llvm-else-after-return"); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), ElementsAre(Diag(Main.range(), "do not use 'else' after 'return'"))); } @@ -532,7 +532,7 @@ TEST(DiagnosticsTest, Preprocessor) { #endif )cpp"); EXPECT_THAT( - TestTU::withCode(Test.code()).build().getDiagnostics(), + *TestTU::withCode(Test.code()).build().getDiagnostics(), ElementsAre(Diag(Test.range(), "use of undeclared identifier 'b'"))); } @@ -542,7 +542,7 @@ TEST(DiagnosticsTest, IgnoreVerify) { )cpp"); TU.ExtraArgs.push_back("-Xclang"); TU.ExtraArgs.push_back("-verify"); - EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty()); + EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty()); } // Recursive main-file include is diagnosed, and doesn't crash. @@ -552,7 +552,7 @@ TEST(DiagnosticsTest, RecursivePreamble) { int symbol; )cpp"); TU.Filename = "foo.h"; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), ElementsAre(DiagName("pp_including_mainfile_in_preamble"))); EXPECT_THAT(TU.build().getLocalTopLevelDecls(), SizeIs(1)); } @@ -565,7 +565,7 @@ TEST(DiagnosticsTest, RecursivePreamblePragmaOnce) { int symbol; )cpp"); TU.Filename = "foo.h"; - EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty()); + EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty()); EXPECT_THAT(TU.build().getLocalTopLevelDecls(), SizeIs(1)); } @@ -581,7 +581,7 @@ TEST(DiagnosticsTest, RecursivePreambleIfndefGuard) { )cpp"); TU.Filename = "foo.h"; // FIXME: should be no errors here. - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), ElementsAre(DiagName("pp_including_mainfile_in_preamble"))); EXPECT_THAT(TU.build().getLocalTopLevelDecls(), SizeIs(1)); } @@ -598,7 +598,7 @@ TEST(DiagnosticsTest, InsideMacros) { return $bar[[TEN]]; } )cpp"); - EXPECT_THAT(TestTU::withCode(Test.code()).build().getDiagnostics(), + EXPECT_THAT(*TestTU::withCode(Test.code()).build().getDiagnostics(), ElementsAre(Diag(Test.range("foo"), "cannot initialize return object of type " "'int *' with an rvalue of type 'int'"), @@ -614,7 +614,7 @@ TEST(DiagnosticsTest, NoFixItInMacro) { [[Define]](main) // error-ok )cpp"); auto TU = TestTU::withCode(Test.code()); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"), Not(WithFix(_))))); } @@ -625,7 +625,7 @@ TEST(ClangdTest, MSAsm) { llvm::InitializeAllTargetInfos(); // As in ClangdMain auto TU = TestTU::withCode("void fn() { __asm { cmp cl,64 } }"); TU.ExtraArgs = {"-fms-extensions"}; - EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty()); + EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty()); } TEST(DiagnosticsTest, ToLSP) { @@ -783,7 +783,7 @@ class T { TU.ExternalIndex = Index.get(); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAreArray( {AllOf(Diag(Test.range("nested"), "incomplete type 'ns::X' named in nested name specifier"), @@ -868,7 +868,7 @@ int main() { MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab()); TU.ExternalIndex = Index.get(); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Test.range("base"), "base class has incomplete type"), Diag(Test.range("access"), @@ -901,7 +901,7 @@ using Type = ns::$template[[Foo]]; TU.ExternalIndex = Index.get(); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre( AllOf(Diag(Test.range("unqualified1"), "unknown type name 'X'"), DiagName("unknown_typename"), @@ -946,7 +946,7 @@ void foo() { SymbolWithHeader{"na::nb::X", "unittest:///b.h", "\"b.h\""}}); TU.ExternalIndex = Index.get(); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre(AllOf( Diag(Test.range("unqualified"), "unknown type name 'X'"), DiagName("unknown_typename"), @@ -967,7 +967,7 @@ TEST(IncludeFixerTest, NoCrashMemebrAccess) { TU.ExternalIndex = Index.get(); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre(Diag(Test.range(), "no member named 'xy' in 'X'"))); } @@ -1002,7 +1002,7 @@ void bar(X *x) { TU.ExternalIndex = Index.get(); auto Parsed = TU.build(); - for (const auto &D : Parsed.getDiagnostics()) { + for (const auto &D : *Parsed.getDiagnostics()) { if (D.Fixes.size() != 1) { ADD_FAILURE() << "D.Fixes.size() != 1"; continue; @@ -1027,7 +1027,7 @@ void g() { ns::$[[scope]]::X_Y(); } TU.ExternalIndex = Index.get(); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre(AllOf( Diag(Test.range(), "no member named 'scope' in namespace 'ns'"), DiagName("no_member"), @@ -1055,7 +1055,7 @@ void f() { TU.ExternalIndex = Index.get(); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), UnorderedElementsAre( AllOf( Diag(Test.range("q1"), "use of undeclared identifier 'clangd'; " @@ -1098,7 +1098,7 @@ namespace c { SymbolWithHeader{"a::X", "unittest:///x.h", "\"x.h\""}); TU.ExternalIndex = Index.get(); - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre(AllOf( Diag(Test.range(), "no type named 'X' in namespace 'a'"), DiagName("typename_nested_not_found"), @@ -1124,7 +1124,7 @@ TEST(IncludeFixerTest, NoCrashOnTemplateInstantiations) { TU.ExternalIndex = Index.get(); EXPECT_THAT( - TU.build().getDiagnostics(), + *TU.build().getDiagnostics(), ElementsAre(Diag(Test.range(), "use of undeclared identifier 'a'"))); } @@ -1135,7 +1135,7 @@ TEST(DiagsInHeaders, DiagInsideHeader) { Annotations Header("[[no_type_spec]]; // error-ok"); TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", std::string(Header.code())}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre(AllOf( Diag(Main.range(), "in included file: C++ requires a " "type specifier for all declarations"), @@ -1149,7 +1149,7 @@ TEST(DiagsInHeaders, DiagInTransitiveInclude) { TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", "#include \"b.h\""}, {"b.h", "no_type_spec; // error-ok"}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Main.range(), "in included file: C++ requires a " "type specifier for all declarations"))); @@ -1163,7 +1163,7 @@ TEST(DiagsInHeaders, DiagInMultipleHeaders) { TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", "no_type_spec; // error-ok"}, {"b.h", "no_type_spec; // error-ok"}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Main.range("a"), "in included file: C++ requires a type " "specifier for all declarations"), @@ -1180,7 +1180,7 @@ TEST(DiagsInHeaders, PreferExpansionLocation) { TU.AdditionalFiles = { {"a.h", "#include \"b.h\"\n"}, {"b.h", "#ifndef X\n#define X\nno_type_spec; // error-ok\n#endif"}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre(Diag(Main.range(), "in included file: C++ requires a type " "specifier for all declarations"))); @@ -1198,7 +1198,7 @@ TEST(DiagsInHeaders, PreferExpansionLocationMacros) { {"a.h", "#include \"c.h\"\n"}, {"b.h", "#include \"c.h\"\n"}, {"c.h", "#ifndef X\n#define X\nno_type_spec; // error-ok\n#endif"}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Main.range(), "in included file: C++ requires a " "type specifier for all declarations"))); @@ -1227,7 +1227,7 @@ TEST(DiagsInHeaders, LimitDiagsOutsideMainFile) { no_type_spec_9; no_type_spec_10; #endif)cpp"}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Main.range(), "in included file: C++ requires a " "type specifier for all declarations"))); @@ -1242,7 +1242,7 @@ TEST(DiagsInHeaders, OnlyErrorOrFatal) { int x = 5/0;)cpp"); TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", std::string(Header.code())}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre(AllOf( Diag(Main.range(), "in included file: C++ requires " "a type specifier for all declarations"), @@ -1260,7 +1260,7 @@ TEST(DiagsInHeaders, OnlyDefaultErrorOrFatal) { TU.AdditionalFiles = {{"a.h", std::string(Header.code())}}; // promote warnings to errors. TU.ExtraArgs = {"-Werror", "-Wunused"}; - EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty()); + EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty()); } TEST(DiagsInHeaders, FromNonWrittenSources) { @@ -1273,7 +1273,7 @@ TEST(DiagsInHeaders, FromNonWrittenSources) { TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", std::string(Header.code())}}; TU.ExtraArgs = {"-DFOO=NOOO"}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre(AllOf( Diag(Main.range(), "in included file: use of undeclared identifier 'NOOO'"), @@ -1291,7 +1291,7 @@ TEST(DiagsInHeaders, ErrorFromMacroExpansion) { X;)cpp"); TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", std::string(Header.code())}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Main.range(), "in included file: use of undeclared " "identifier 'foo'; did you mean 'fo'?"))); @@ -1308,7 +1308,7 @@ TEST(DiagsInHeaders, ErrorFromMacroArgument) { X(foo);)cpp"); TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", std::string(Header.code())}}; - EXPECT_THAT(TU.build().getDiagnostics(), + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre( Diag(Main.range(), "in included file: use of undeclared " "identifier 'foo'; did you mean 'fo'?"))); @@ -1320,7 +1320,7 @@ TEST(IgnoreDiags, FromNonWrittenInclude) { TU.AdditionalFiles = {{"a.h", "void main();"}}; // The diagnostic "main must return int" is from the header, we don't attempt // to render it in the main file as there is no written location there. - EXPECT_THAT(TU.build().getDiagnostics(), UnorderedElementsAre()); + EXPECT_THAT(*TU.build().getDiagnostics(), UnorderedElementsAre()); } TEST(ToLSPDiag, RangeIsInMain) { diff --git a/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp b/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp index a6ed5d4436a0..5375ea4273af 100644 --- a/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp +++ b/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp @@ -24,20 +24,20 @@ TEST(DraftStore, Versions) { EXPECT_EQ("25", DS.addDraft(File, "25", "")); EXPECT_EQ("25", DS.getDraft(File)->Version); - EXPECT_EQ("", DS.getDraft(File)->Contents); + EXPECT_EQ("", *DS.getDraft(File)->Contents); EXPECT_EQ("26", DS.addDraft(File, "", "x")); EXPECT_EQ("26", DS.getDraft(File)->Version); - EXPECT_EQ("x", DS.getDraft(File)->Contents); + EXPECT_EQ("x", *DS.getDraft(File)->Contents); EXPECT_EQ("27", DS.addDraft(File, "", "x")) << "no-op change"; EXPECT_EQ("27", DS.getDraft(File)->Version); - EXPECT_EQ("x", DS.getDraft(File)->Contents); + EXPECT_EQ("x", *DS.getDraft(File)->Contents); // We allow versions to go backwards. EXPECT_EQ("7", DS.addDraft(File, "7", "y")); EXPECT_EQ("7", DS.getDraft(File)->Version); - EXPECT_EQ("y", DS.getDraft(File)->Contents); + EXPECT_EQ("y", *DS.getDraft(File)->Contents); } } // namespace diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp index 2ec64128485b..9c02f697d46c 100644 --- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp +++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp @@ -463,7 +463,9 @@ MATCHER_P2(hasFlag, Flag, Path, "") { return true; } -auto hasFlag(llvm::StringRef Flag) { return hasFlag(Flag, "dummy.cc"); } +auto hasFlag(llvm::StringRef Flag) { + return hasFlag(Flag, "mock_file_name.cc"); +} TEST_F(DirectoryBasedGlobalCompilationDatabaseCacheTest, Cacheable) { MockFS FS; @@ -507,15 +509,15 @@ TEST_F(DirectoryBasedGlobalCompilationDatabaseCacheTest, Cacheable) { // compile_commands.json takes precedence over compile_flags.txt. FS.Files["foo/compile_commands.json"] = llvm::formatv(R"json([{ - "file": "{0}/foo/dummy.cc", - "command": "clang -DBAZ dummy.cc", + "file": "{0}/foo/mock_file.cc", + "command": "clang -DBAZ mock_file.cc", "directory": "{0}/foo", }])json", llvm::sys::path::convert_to_slash(testRoot())); EXPECT_EQ(FooBar, lookupCDB(GDB, testPath("foo/test.cc"), Stale)) << "cache still valid"; auto Baz = lookupCDB(GDB, testPath("foo/test.cc"), Fresh); - EXPECT_THAT(Baz, hasFlag("-DBAZ", testPath("foo/dummy.cc"))) + EXPECT_THAT(Baz, hasFlag("-DBAZ", testPath("foo/mock_file.cc"))) << "compile_commands overrides compile_flags"; // Removing compile_commands.json reveals compile_flags.txt again. diff --git a/clang-tools-extra/clangd/unittests/IndexTests.cpp b/clang-tools-extra/clangd/unittests/IndexTests.cpp index 2b4b3af85613..5b6223a0ddc5 100644 --- a/clang-tools-extra/clangd/unittests/IndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/IndexTests.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "Annotations.h" +#include "SyncAPI.h" #include "TestIndex.h" #include "TestTU.h" #include "index/FileIndex.h" @@ -17,6 +18,7 @@ #include "clang/Index/IndexSymbol.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include using ::testing::_; using ::testing::AllOf; @@ -312,16 +314,28 @@ TEST(MergeIndexTest, LookupRemovedDefinition) { AST = Test.build(); DynamicIndex.updateMain(testPath(Test.Filename), AST); - // Merged index should not return the symbol definition if this definition - // location is inside a file from the dynamic index. + // Even though the definition is actually deleted in the newer version of the + // file, we still chose to merge with information coming from static index. + // This seems wrong, but is generic behavior we want for e.g. include headers + // which are always missing from the dynamic index LookupRequest LookupReq; LookupReq.IDs = {Foo.ID}; unsigned SymbolCounter = 0; Merge.lookup(LookupReq, [&](const Symbol &Sym) { ++SymbolCounter; - EXPECT_FALSE(Sym.Definition); + EXPECT_TRUE(Sym.Definition); }); EXPECT_EQ(SymbolCounter, 1u); + + // Drop the symbol completely. + Test.Code = "class Bar {};"; + AST = Test.build(); + DynamicIndex.updateMain(testPath(Test.Filename), AST); + + // Now we don't expect to see the symbol at all. + SymbolCounter = 0; + Merge.lookup(LookupReq, [&](const Symbol &Sym) { ++SymbolCounter; }); + EXPECT_EQ(SymbolCounter, 0u); } TEST(MergeIndexTest, FuzzyFind) { @@ -585,6 +599,44 @@ TEST(MergeTest, MergeIncludesOnDifferentDefinitions) { IncludeHeaderWithRef("new", 1u))); } +TEST(MergeIndexTest, IncludeHeadersMerged) { + auto S = symbol("Z"); + S.Definition.FileURI = "unittest:///foo.cc"; + + SymbolSlab::Builder DynB; + S.IncludeHeaders.clear(); + DynB.insert(S); + SymbolSlab DynSymbols = std::move(DynB).build(); + RefSlab DynRefs; + auto DynSize = DynSymbols.bytes() + DynRefs.bytes(); + auto DynData = std::make_pair(std::move(DynSymbols), std::move(DynRefs)); + llvm::StringSet<> DynFiles = {S.Definition.FileURI}; + MemIndex DynIndex(std::move(DynData.first), std::move(DynData.second), + RelationSlab(), std::move(DynFiles), IndexContents::Symbols, + std::move(DynData), DynSize); + + SymbolSlab::Builder StaticB; + S.IncludeHeaders.push_back({"
", 0}); + StaticB.insert(S); + auto StaticIndex = + MemIndex::build(std::move(StaticB).build(), RefSlab(), RelationSlab()); + MergedIndex Merge(&DynIndex, StaticIndex.get()); + + EXPECT_THAT(runFuzzyFind(Merge, S.Name), + ElementsAre(testing::Field( + &Symbol::IncludeHeaders, + ElementsAre(IncludeHeaderWithRef("
", 0u))))); + + LookupRequest Req; + Req.IDs = {S.ID}; + std::string IncludeHeader; + Merge.lookup(Req, [&](const Symbol &S) { + EXPECT_TRUE(IncludeHeader.empty()); + ASSERT_EQ(S.IncludeHeaders.size(), 1u); + IncludeHeader = S.IncludeHeaders.front().IncludeHeader.str(); + }); + EXPECT_EQ(IncludeHeader, "
"); +} } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/ModulesTests.cpp b/clang-tools-extra/clangd/unittests/ModulesTests.cpp index 83d6b28d6dfc..b56b91836508 100644 --- a/clang-tools-extra/clangd/unittests/ModulesTests.cpp +++ b/clang-tools-extra/clangd/unittests/ModulesTests.cpp @@ -61,7 +61,7 @@ TEST(Modules, PreambleBuildVisibility) { header "module.h" } )modulemap"; - EXPECT_TRUE(TU.build().getDiagnostics().empty()); + EXPECT_TRUE(TU.build().getDiagnostics()->empty()); } TEST(Modules, Diagnostic) { diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp index b96d1243d243..5435648cd9be 100644 --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -511,7 +511,7 @@ TEST(ParsedASTTest, ReplayPreambleForTidyCheckers) { auto PatchedAST = ParsedAST::build(testPath(TU.Filename), TU.inputs(FS), std::move(CI), {}, BaselinePreamble); ASSERT_TRUE(PatchedAST); - EXPECT_TRUE(PatchedAST->getDiagnostics().empty()); + EXPECT_FALSE(PatchedAST->getDiagnostics()); } // Then ensure correctness by making sure includes were seen only once. @@ -526,7 +526,7 @@ TEST(ParsedASTTest, ReplayPreambleForTidyCheckers) { auto PatchedAST = ParsedAST::build(testPath(TU.Filename), TU.inputs(FS), std::move(CI), {}, BaselinePreamble); ASSERT_TRUE(PatchedAST); - EXPECT_TRUE(PatchedAST->getDiagnostics().empty()); + EXPECT_FALSE(PatchedAST->getDiagnostics()); EXPECT_THAT(Includes, ElementsAre(WithFileName(testPath("__preamble_patch__.h")), WithFileName("b.h"), WithFileName("a.h"))); @@ -569,7 +569,7 @@ TEST(ParsedASTTest, PatchesAdditionalIncludes) { auto PatchedAST = ParsedAST::build(testPath("foo.cpp"), Inputs, std::move(CI), {}, EmptyPreamble); ASSERT_TRUE(PatchedAST); - ASSERT_TRUE(PatchedAST->getDiagnostics().empty()); + ASSERT_FALSE(PatchedAST->getDiagnostics()); // Ensure source location information is correct, including resolved paths. EXPECT_THAT(PatchedAST->getIncludeStructure().MainFileIncludes, diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index 4eee9effb824..70a14241a8ac 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -274,8 +274,12 @@ TEST(PreamblePatchTest, Define) { auto AST = createPatchedAST("", Modified.code()); ASSERT_TRUE(AST); - EXPECT_THAT(AST->getDiagnostics(), - Not(Contains(Field(&Diag::Range, Modified.range())))); + std::vector MacroRefRanges; + for (auto &M : AST->getMacros().MacroRefs) { + for (auto &O : M.getSecond()) + MacroRefRanges.push_back(O.Rng); + } + EXPECT_THAT(MacroRefRanges, Contains(Modified.range())); } } @@ -298,8 +302,6 @@ TEST(PreamblePatchTest, OrderingPreserved) { auto AST = createPatchedAST(Baseline, Modified.code()); ASSERT_TRUE(AST); - EXPECT_THAT(AST->getDiagnostics(), - Not(Contains(Field(&Diag::Range, Modified.range())))); } TEST(PreamblePatchTest, LocateMacroAtWorks) { @@ -535,6 +537,15 @@ TEST(PreamblePatch, ModifiedBounds) { ExpectedBounds.PreambleEndsAtStartOfLine); } } + +TEST(PreamblePatch, DropsDiagnostics) { + llvm::StringLiteral Code = "#define FOO\nx;/* error-ok */"; + // First check that this code generates diagnostics. + EXPECT_THAT(*TestTU::withCode(Code).build().getDiagnostics(), + testing::Not(testing::IsEmpty())); + // Ensure they are dropeed when a patched preamble is used. + EXPECT_FALSE(createPatchedAST("", Code)->getDiagnostics()); +} } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/ProjectAwareIndexTests.cpp b/clang-tools-extra/clangd/unittests/ProjectAwareIndexTests.cpp index 0d14d2ed5d54..c8ce0c0d154d 100644 --- a/clang-tools-extra/clangd/unittests/ProjectAwareIndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/ProjectAwareIndexTests.cpp @@ -33,11 +33,11 @@ std::unique_ptr createIndex() { } TEST(ProjectAware, Test) { - IndexFactory Gen = [](const Config::ExternalIndexSpec &, AsyncTaskRunner &) { + IndexFactory Gen = [](const Config::ExternalIndexSpec &, AsyncTaskRunner *) { return createIndex(); }; - auto Idx = createProjectAwareIndex(std::move(Gen)); + auto Idx = createProjectAwareIndex(std::move(Gen), true); FuzzyFindRequest Req; Req.Query = "1"; Req.AnyScope = true; @@ -54,12 +54,12 @@ TEST(ProjectAware, Test) { TEST(ProjectAware, CreatedOnce) { unsigned InvocationCount = 0; - IndexFactory Gen = [&](const Config::ExternalIndexSpec &, AsyncTaskRunner &) { + IndexFactory Gen = [&](const Config::ExternalIndexSpec &, AsyncTaskRunner *) { ++InvocationCount; return createIndex(); }; - auto Idx = createProjectAwareIndex(std::move(Gen)); + auto Idx = createProjectAwareIndex(std::move(Gen), true); // No invocation at start. EXPECT_EQ(InvocationCount, 0U); FuzzyFindRequest Req; diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp index 5e16640ccded..f917e30cd7fe 100644 --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -33,6 +33,19 @@ using testing::SizeIs; using testing::UnorderedElementsAre; using testing::UnorderedElementsAreArray; +llvm::IntrusiveRefCntPtr +createOverlay(llvm::IntrusiveRefCntPtr Base, + llvm::IntrusiveRefCntPtr Overlay) { + auto OFS = + llvm::makeIntrusiveRefCnt(std::move(Base)); + OFS->pushOverlay(std::move(Overlay)); + return OFS; +} + +llvm::IntrusiveRefCntPtr getVFSFromAST(ParsedAST &AST) { + return &AST.getSourceManager().getFileManager().getVirtualFileSystem(); +} + // Convert a Range to a Ref. Ref refWithRange(const clangd::Range &Range, const std::string &URI) { Ref Result; @@ -815,7 +828,8 @@ TEST(RenameTest, WithinFileRename) { auto Index = TU.index(); for (const auto &RenamePos : Code.points()) { auto RenameResult = - rename({RenamePos, NewName, AST, testPath(TU.Filename), Index.get()}); + rename({RenamePos, NewName, AST, testPath(TU.Filename), + getVFSFromAST(AST), Index.get()}); ASSERT_TRUE(bool(RenameResult)) << RenameResult.takeError(); ASSERT_EQ(1u, RenameResult->GlobalChanges.size()); EXPECT_EQ( @@ -830,7 +844,7 @@ TEST(RenameTest, Renameable) { const char *Code; const char* ErrorMessage; // null if no error bool IsHeaderFile; - llvm::StringRef NewName = "DummyName"; + llvm::StringRef NewName = "MockName"; }; const bool HeaderFile = true; Case Cases[] = { @@ -1101,13 +1115,21 @@ TEST(RenameTest, IndexMergeMainFile) { auto AST = TU.build(); auto Main = testPath("main.cc"); + auto InMemFS = llvm::makeIntrusiveRefCnt(); + InMemFS->addFile(testPath("main.cc"), 0, + llvm::MemoryBuffer::getMemBuffer(Code.code())); + InMemFS->addFile(testPath("other.cc"), 0, + llvm::MemoryBuffer::getMemBuffer(Code.code())); auto Rename = [&](const SymbolIndex *Idx) { - auto GetDirtyBuffer = [&](PathRef Path) -> llvm::Optional { - return Code.code().str(); // Every file has the same content. - }; - RenameInputs Inputs{Code.point(), "xPrime", AST, Main, - Idx, RenameOptions(), GetDirtyBuffer}; + RenameInputs Inputs{Code.point(), + "xPrime", + AST, + Main, + Idx ? createOverlay(getVFSFromAST(AST), InMemFS) + : nullptr, + Idx, + RenameOptions()}; auto Results = rename(Inputs); EXPECT_TRUE(bool(Results)) << llvm::toString(Results.takeError()); return std::move(*Results); @@ -1218,6 +1240,21 @@ TEST(RenameTest, PrepareRename) { testing::HasSubstr("keyword")); EXPECT_THAT(Tracer.takeMetric("rename_name_invalid", "Keywords"), ElementsAre(1)); + + for (std::string BadIdent : {"foo!bar", "123foo", "😀@"}) { + Results = runPrepareRename(Server, FooCCPath, FooCC.point(), + /*NewName=*/BadIdent, {}); + EXPECT_FALSE(Results); + EXPECT_THAT(llvm::toString(Results.takeError()), + testing::HasSubstr("identifier")); + EXPECT_THAT(Tracer.takeMetric("rename_name_invalid", "BadIdentifier"), + ElementsAre(1)); + } + for (std::string GoodIdent : {"fooBar", "__foo$", "😀"}) { + Results = runPrepareRename(Server, FooCCPath, FooCC.point(), + /*NewName=*/GoodIdent, {}); + EXPECT_TRUE(bool(Results)); + } } TEST(CrossFileRenameTests, DirtyBuffer) { @@ -1237,25 +1274,19 @@ TEST(CrossFileRenameTests, DirtyBuffer) { Annotations MainCode("class [[Fo^o]] {};"); auto MainFilePath = testPath("main.cc"); - // Dirty buffer for foo.cc. - auto GetDirtyBuffer = [&](PathRef Path) -> llvm::Optional { - if (Path == FooPath) - return FooDirtyBuffer.code().str(); - return llvm::None; - }; + llvm::IntrusiveRefCntPtr InMemFS = + new llvm::vfs::InMemoryFileSystem; + InMemFS->addFile(FooPath, 0, + llvm::MemoryBuffer::getMemBuffer(FooDirtyBuffer.code())); // Run rename on Foo, there is a dirty buffer for foo.cc, rename should // respect the dirty buffer. TestTU TU = TestTU::withCode(MainCode.code()); auto AST = TU.build(); llvm::StringRef NewName = "newName"; - auto Results = rename({MainCode.point(), - NewName, - AST, - MainFilePath, - Index.get(), - {}, - GetDirtyBuffer}); + auto Results = + rename({MainCode.point(), NewName, AST, MainFilePath, + createOverlay(getVFSFromAST(AST), InMemFS), Index.get()}); ASSERT_TRUE(bool(Results)) << Results.takeError(); EXPECT_THAT( applyEdits(std::move(Results->GlobalChanges)), @@ -1270,13 +1301,8 @@ TEST(CrossFileRenameTests, DirtyBuffer) { // Set a file "bar.cc" on disk. TU.AdditionalFiles["bar.cc"] = std::string(BarCode.code()); AST = TU.build(); - Results = rename({MainCode.point(), - NewName, - AST, - MainFilePath, - Index.get(), - {}, - GetDirtyBuffer}); + Results = rename({MainCode.point(), NewName, AST, MainFilePath, + createOverlay(getVFSFromAST(AST), InMemFS), Index.get()}); ASSERT_TRUE(bool(Results)) << Results.takeError(); EXPECT_THAT( applyEdits(std::move(Results->GlobalChanges)), @@ -1312,13 +1338,8 @@ TEST(CrossFileRenameTests, DirtyBuffer) { size_t estimateMemoryUsage() const override { return 0; } } PIndex; - Results = rename({MainCode.point(), - NewName, - AST, - MainFilePath, - &PIndex, - {}, - GetDirtyBuffer}); + Results = rename({MainCode.point(), NewName, AST, MainFilePath, + createOverlay(getVFSFromAST(AST), InMemFS), &PIndex}); EXPECT_FALSE(Results); EXPECT_THAT(llvm::toString(Results.takeError()), testing::HasSubstr("too many occurrences")); @@ -1368,8 +1389,8 @@ TEST(CrossFileRenameTests, DeduplicateRefsFromIndex) { Ref ReturnedRef; } DIndex(XRefInBarCC); llvm::StringRef NewName = "newName"; - auto Results = - rename({MainCode.point(), NewName, AST, MainFilePath, &DIndex}); + auto Results = rename({MainCode.point(), NewName, AST, MainFilePath, + getVFSFromAST(AST), &DIndex}); ASSERT_TRUE(bool(Results)) << Results.takeError(); EXPECT_THAT( applyEdits(std::move(Results->GlobalChanges)), diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp index e9c689f329ab..a063c84a6a4c 100644 --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -581,7 +581,7 @@ TEST(SelectionTest, PathologicalPreprocessor) { auto TU = TestTU::withCode(Test.code()); TU.AdditionalFiles["Expand.inc"] = "MACRO\n"; auto AST = TU.build(); - EXPECT_THAT(AST.getDiagnostics(), ::testing::IsEmpty()); + EXPECT_THAT(*AST.getDiagnostics(), ::testing::IsEmpty()); auto T = makeSelectionTree(Case, AST); EXPECT_EQ("BreakStmt", T.commonAncestor()->kind()); diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp index 924cfd03cba7..87df23baf48a 100644 --- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp +++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp @@ -1463,9 +1463,6 @@ TEST_F(SymbolCollectorTest, CanonicalSTLHeader) { } )cpp", /*Main=*/""); - for (const auto &S : Symbols) - llvm::errs() << S.Scope << S.Name << " in " << S.IncludeHeaders.size() - << "\n"; EXPECT_THAT( Symbols, UnorderedElementsAre( diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index 22b6ea2296d2..d68cb3efa3d6 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -71,7 +71,7 @@ MATCHER_P2(TUState, PreambleActivity, ASTActivity, "") { return true; } -// Dummy ContextProvider to verify the provider is invoked & contexts are used. +// Simple ContextProvider to verify the provider is invoked & contexts are used. static Key BoundPath; Context bindPath(PathRef F) { return Context::current().derive(BoundPath, F.str()); @@ -121,7 +121,7 @@ class TUSchedulerTests : public ::testing::Test { class CaptureDiags : public ParsingCallbacks { public: void onMainAST(PathRef File, ParsedAST &AST, PublishFn Publish) override { - reportDiagnostics(File, AST.getDiagnostics(), Publish); + reportDiagnostics(File, *AST.getDiagnostics(), Publish); } void onFailedAST(PathRef File, llvm::StringRef Version, diff --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp index 8d336b3f4e19..1c6e54774c03 100644 --- a/clang-tools-extra/clangd/unittests/TestTU.cpp +++ b/clang-tools-extra/clangd/unittests/TestTU.cpp @@ -113,6 +113,11 @@ ParsedAST TestTU::build() const { ADD_FAILURE() << "Failed to build code:\n" << Code; llvm_unreachable("Failed to build TestTU!"); } + if (!AST->getDiagnostics()) { + ADD_FAILURE() << "TestTU should always build an AST with a fresh Preamble" + << Code; + return std::move(*AST); + } // Check for error diagnostics and report gtest failures (unless expected). // This guards against accidental syntax errors silently subverting tests. // error-ok is awfully primitive - using clang -verify would be nicer. @@ -128,7 +133,8 @@ ParsedAST TestTU::build() const { return false; }(); if (!ErrorOk) { - for (const auto &D : AST->getDiagnostics()) + // We always build AST with a fresh preamble in TestTU. + for (const auto &D : *AST->getDiagnostics()) if (D.Severity >= DiagnosticsEngine::Error) { ADD_FAILURE() << "TestTU failed to build (suppress with /*error-ok*/): \n" @@ -189,7 +195,7 @@ const NamedDecl &findDecl(ParsedAST &AST, llvm::StringRef QName) { llvm::StringRef Name) -> const NamedDecl & { auto LookupRes = Scope.lookup(DeclarationName(&Ctx.Idents.get(Name))); assert(!LookupRes.empty() && "Lookup failed"); - assert(LookupRes.size() == 1 && "Lookup returned multiple results"); + assert(LookupRes.isSingleResult() && "Lookup returned multiple results"); return *LookupRes.front(); }; diff --git a/clang-tools-extra/clangd/unittests/TestTU.h b/clang-tools-extra/clangd/unittests/TestTU.h index 18b490332b1a..169cab045ea1 100644 --- a/clang-tools-extra/clangd/unittests/TestTU.h +++ b/clang-tools-extra/clangd/unittests/TestTU.h @@ -78,6 +78,7 @@ struct TestTU { // By default, build() will report Error diagnostics as GTest errors. // Suppress this behavior by adding an 'error-ok' comment to the code. + // The result will always have getDiagnostics() populated. ParsedAST build() const; std::shared_ptr preamble(PreambleParsedCallback PreambleCallback = nullptr) const; diff --git a/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp b/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp index 08f936ce8b55..09f90fd6e6b5 100644 --- a/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp +++ b/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp @@ -398,7 +398,7 @@ TEST(TypeHierarchy, RecursiveHierarchyUnbounded) { // The compiler should produce a diagnostic for hitting the // template instantiation depth. - ASSERT_TRUE(!AST.getDiagnostics().empty()); + ASSERT_TRUE(!AST.getDiagnostics()->empty()); // Make sure getTypeHierarchy() doesn't get into an infinite recursion. // The parent is reported as "S" because "S<0>" is an invalid instantiation. diff --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp index fa627282e193..a872341a871a 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp @@ -267,6 +267,28 @@ TEST_F(DefineOutlineTest, ApplyTest) { };)cpp", " void A::foo() {}\n", }, + { + R"cpp( + struct Foo { + explicit Fo^o(int) {} + };)cpp", + R"cpp( + struct Foo { + explicit Foo(int) ; + };)cpp", + " Foo::Foo(int) {}\n", + }, + { + R"cpp( + struct Foo { + explicit explicit Fo^o(int) {} + };)cpp", + R"cpp( + struct Foo { + explicit explicit Foo(int) ; + };)cpp", + " Foo::Foo(int) {}\n", + }, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Test); diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp index 4e9223cfe553..5862d4938d4a 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp @@ -131,7 +131,7 @@ TEST_F(ExtractVariableTest, Test) { int a = 5 * (4 + (3 [[- 1)]]); })cpp", R"cpp(void varDecl() { - auto dummy = (3 - 1); int a = 5 * (4 + dummy); + auto placeholder = (3 - 1); int a = 5 * (4 + placeholder); })cpp"}, // FIXME: extraction from switch case /*{R"cpp(void f(int a) { @@ -146,11 +146,11 @@ TEST_F(ExtractVariableTest, Test) { } })cpp", R"cpp(void f(int a) { - auto dummy = 1 + 2; if(1) + auto placeholder = 1 + 2; if(1) while(a < 1) switch (1) { case 1: - a = dummy; + a = placeholder; break; default: break; @@ -164,11 +164,11 @@ TEST_F(ExtractVariableTest, Test) { /*FIXME: It should be extracted like this. R"cpp(#define PLUS(x) x++ void f(int a) { - auto dummy = 1+a; int y = PLUS(dummy); + auto placeholder = 1+a; int y = PLUS(placeholder); })cpp"},*/ R"cpp(#define PLUS(x) x++ void f(int a) { - auto dummy = PLUS(1+a); int y = dummy; + auto placeholder = PLUS(1+a); int y = placeholder; })cpp"}, // ensure InsertionPoint isn't inside a macro {R"cpp(#define LOOP(x) while (1) {a = x;} @@ -178,8 +178,8 @@ TEST_F(ExtractVariableTest, Test) { })cpp", R"cpp(#define LOOP(x) while (1) {a = x;} void f(int a) { - auto dummy = 3; if(1) - LOOP(5 + dummy) + auto placeholder = 3; if(1) + LOOP(5 + placeholder) })cpp"}, {R"cpp(#define LOOP(x) do {x;} while(1); void f(int a) { @@ -188,15 +188,15 @@ TEST_F(ExtractVariableTest, Test) { })cpp", R"cpp(#define LOOP(x) do {x;} while(1); void f(int a) { - auto dummy = 3; if(1) - LOOP(5 + dummy) + auto placeholder = 3; if(1) + LOOP(5 + placeholder) })cpp"}, // attribute testing {R"cpp(void f(int a) { [ [gsl::suppress("type")] ] for (;;) a = [[1]] + 1; })cpp", R"cpp(void f(int a) { - auto dummy = 1; [ [gsl::suppress("type")] ] for (;;) a = dummy + 1; + auto placeholder = 1; [ [gsl::suppress("type")] ] for (;;) a = placeholder + 1; })cpp"}, // MemberExpr {R"cpp(class T { @@ -206,7 +206,7 @@ TEST_F(ExtractVariableTest, Test) { };)cpp", R"cpp(class T { T f() { - auto dummy = T().f(); return dummy.f(); + auto placeholder = T().f(); return placeholder.f(); } };)cpp"}, // Function DeclRefExpr @@ -214,7 +214,7 @@ TEST_F(ExtractVariableTest, Test) { return [[f]](); })cpp", R"cpp(int f() { - auto dummy = f(); return dummy; + auto placeholder = f(); return placeholder; })cpp"}, // FIXME: Wrong result for \[\[clang::uninitialized\]\] int b = [[1]]; // since the attr is inside the DeclStmt and the bounds of @@ -225,33 +225,33 @@ TEST_F(ExtractVariableTest, Test) { int x = 1 + [[2 + 3 + 4]] + 5; })cpp", R"cpp(void f() { - auto dummy = 2 + 3 + 4; int x = 1 + dummy + 5; + auto placeholder = 2 + 3 + 4; int x = 1 + placeholder + 5; })cpp"}, {R"cpp(void f() { int x = [[1 + 2 + 3]] + 4 + 5; })cpp", R"cpp(void f() { - auto dummy = 1 + 2 + 3; int x = dummy + 4 + 5; + auto placeholder = 1 + 2 + 3; int x = placeholder + 4 + 5; })cpp"}, {R"cpp(void f() { int x = 1 + 2 + [[3 + 4 + 5]]; })cpp", R"cpp(void f() { - auto dummy = 3 + 4 + 5; int x = 1 + 2 + dummy; + auto placeholder = 3 + 4 + 5; int x = 1 + 2 + placeholder; })cpp"}, // Non-associative operations have no special support {R"cpp(void f() { int x = 1 - [[2 - 3 - 4]] - 5; })cpp", R"cpp(void f() { - auto dummy = 1 - 2 - 3 - 4; int x = dummy - 5; + auto placeholder = 1 - 2 - 3 - 4; int x = placeholder - 5; })cpp"}, // A mix of associative operators isn't associative. {R"cpp(void f() { int x = 0 + 1 * [[2 + 3]] * 4 + 5; })cpp", R"cpp(void f() { - auto dummy = 1 * 2 + 3 * 4; int x = 0 + dummy + 5; + auto placeholder = 1 * 2 + 3 * 4; int x = 0 + placeholder + 5; })cpp"}, // Overloaded operators are supported, we assume associativity // as if they were built-in. @@ -269,7 +269,7 @@ TEST_F(ExtractVariableTest, Test) { S operator+(S, S); void f() { - auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5); + auto placeholder = S(2) + S(3) + S(4); S x = S(1) + placeholder + S(5); })cpp"}, // Don't try to analyze across macro boundaries // FIXME: it'd be nice to do this someday (in a safe way) @@ -279,7 +279,7 @@ TEST_F(ExtractVariableTest, Test) { })cpp", R"cpp(#define ECHO(X) X void f() { - auto dummy = 1 + ECHO(2 + 3) + 4; int x = dummy + 5; + auto placeholder = 1 + ECHO(2 + 3) + 4; int x = placeholder + 5; })cpp"}, {R"cpp(#define ECHO(X) X void f() { @@ -287,7 +287,7 @@ TEST_F(ExtractVariableTest, Test) { })cpp", R"cpp(#define ECHO(X) X void f() { - auto dummy = 1 + ECHO(2) + ECHO(3) + 4; int x = dummy + 5; + auto placeholder = 1 + ECHO(2) + ECHO(3) + 4; int x = placeholder + 5; })cpp"}, }; for (const auto &IO : InputOutputs) { diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 91207090902d..2e38c7d86dc9 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -83,6 +83,12 @@ New checks Finds ``pthread_setcanceltype`` function calls where a thread's cancellation type is set to asynchronous. +- New :doc:`altera-unroll-loops + ` check. + + Finds inner loops that have not been unrolled, as well as fully unrolled + loops with unknown loops bounds or a large number of iterations. + - New :doc:`cppcoreguidelines-prefer-member-initializer ` check. @@ -112,11 +118,10 @@ Changes in existing checks function or assignment to ``nullptr``. Added support for pointers to ``std::unique_ptr``. -Deprecated checks -^^^^^^^^^^^^^^^^^ +Removed checks +^^^^^^^^^^^^^^ -- The :doc:`readability-deleted-default - ` check has been deprecated. +- The readability-deleted-default check has been removed. The clang warning `Wdefaulted-function-deleted `_ diff --git a/clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst b/clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst new file mode 100644 index 000000000000..419a1edf0211 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst @@ -0,0 +1,105 @@ +.. title:: clang-tidy - altera-unroll-loops + +altera-unroll-loops +=================== + +Finds inner loops that have not been unrolled, as well as fully unrolled loops +with unknown loop bounds or a large number of iterations. + +Unrolling inner loops could improve the performance of OpenCL kernels. However, +if they have unknown loop bounds or a large number of iterations, they cannot +be fully unrolled, and should be partially unrolled. + +Notes: + +- This check is unable to determine the number of iterations in a ``while`` or + ``do..while`` loop; hence if such a loop is fully unrolled, a note is emitted + advising the user to partially unroll instead. + +- In ``for`` loops, our check only works with simple arithmetic increments ( + ``+``, ``-``, ``*``, ``/``). For all other increments, partial unrolling is + advised. + +- Depending on the exit condition, the calculations for determining if the + number of iterations is large may be off by 1. This should not be an issue + since the cut-off is generally arbitrary. + +Based on the `Altera SDK for OpenCL: Best Practices Guide +`_. + +.. code-block:: c++ + + for (int i = 0; i < 10; i++) { // ok: outer loops should not be unrolled + int j = 0; + do { // warning: this inner do..while loop should be unrolled + j++; + } while (j < 15); + + int k = 0; + #pragma unroll + while (k < 20) { // ok: this inner loop is already unrolled + k++; + } + } + + int A[1000]; + #pragma unroll + // warning: this loop is large and should be partially unrolled + for (int a : A) { + printf("%d", a); + } + + #pragma unroll 5 + // ok: this loop is large, but is partially unrolled + for (int a : A) { + printf("%d", a); + } + + #pragma unroll + // warning: this loop is large and should be partially unrolled + for (int i = 0; i < 1000; ++i) { + printf("%d", i); + } + + #pragma unroll 5 + // ok: this loop is large, but is partially unrolled + for (int i = 0; i < 1000; ++i) { + printf("%d", i); + } + + #pragma unroll + // warning: << operator not supported, recommend partial unrolling + for (int i = 0; i < 1000; i<<1) { + printf("%d", i); + } + + std::vector someVector (100, 0); + int i = 0; + #pragma unroll + // note: loop may be large, recommend partial unrolling + while (i < someVector.size()) { + someVector[i]++; + } + + #pragma unroll + // note: loop may be large, recommend partial unrolling + while (true) { + printf("In loop"); + } + + #pragma unroll 5 + // ok: loop may be large, but is partially unrolled + while (i < someVector.size()) { + someVector[i]++; + } + +Options +------- + +.. option:: MaxLoopIterations + + Defines the maximum number of loop iterations that a fully unrolled loop + can have. By default, it is set to `100`. + + In practice, this refers to the integer value of the upper bound + within the loop statement's condition expression. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index e53c0e704963..bdce63cd26b6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -33,6 +33,7 @@ Clang-Tidy Checks `altera-kernel-name-restriction `_, `altera-single-work-item-barrier `_, `altera-struct-pack-align `_, "Yes" + `altera-unroll-loops `_, `android-cloexec-accept `_, "Yes" `android-cloexec-accept4 `_, `android-cloexec-creat `_, "Yes" @@ -280,7 +281,6 @@ Clang-Tidy Checks `readability-container-size-empty `_, "Yes" `readability-convert-member-functions-to-static `_, `readability-delete-null-pointer `_, "Yes" - `readability-deleted-default `_, `readability-else-after-return `_, "Yes" `readability-function-cognitive-complexity `_, `readability-function-size `_, diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-deleted-default.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-deleted-default.rst deleted file mode 100644 index 5f2083e00061..000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/readability-deleted-default.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. title:: clang-tidy - readability-deleted-default - -readability-deleted-default -=========================== - -This check has been deprecated prefer to make use of the `Wdefaulted-function-deleted -`_ -flag. diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/modernize-concat-nested-namespaces/modernize-concat-nested-namespaces.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/modernize-concat-nested-namespaces/modernize-concat-nested-namespaces.h new file mode 100644 index 000000000000..752b33718dca --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/modernize-concat-nested-namespaces/modernize-concat-nested-namespaces.h @@ -0,0 +1,8 @@ +namespace nn1 { +namespace nn2 { +// CHECK-FIXES: namespace nn1::nn2 +void t(); +} // namespace nn2 +} // namespace nn1 +// CHECK-FIXES: void t(); +// CHECK-FIXES-NEXT: } // namespace nn1 diff --git a/clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp b/clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp new file mode 100644 index 000000000000..06c1cbaf3a28 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp @@ -0,0 +1,516 @@ +// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* +// RUN: %check_clang_tidy -check-suffix=MULT %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 5}]}" -header-filter=.* "--" -DMULT + +#ifdef MULT +// For loops with *= and /= increments. +void for_loop_mult_div_increments(int *A) { +// *= +#pragma unroll + for (int i = 2; i <= 32; i *= 2) + A[i]++; // OK + +#pragma unroll + for (int i = 2; i <= 64; i *= 2) + // CHECK-MESSAGES-MULT: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; // Not OK + +// /= +#pragma unroll + for (int i = 32; i >= 2; i /= 2) + A[i]++; // OK + +#pragma unroll + for (int i = 64; i >= 2; i /= 2) + // CHECK-MESSAGES-MULT: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; // Not OK +} +#else +// Cannot determine loop bounds for while loops. +void while_loops(int *A) { + // Recommend unrolling loops that aren't already unrolled. + int j = 0; + while (j < 2000) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[1] += j; + j++; + } + + do { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[2] += j; + j++; + } while (j < 2000); + +// If a while loop is fully unrolled, add a note recommending partial +// unrolling. +#pragma unroll + while (j < 2000) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive + A[j]++; + } + +#pragma unroll + do { + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive + A[j]++; + } while (j < 2000); + +// While loop is partially unrolled, no action needed. +#pragma unroll 4 + while (j < 2000) { + A[j]++; + } + +#pragma unroll 4 + do { + A[j]++; + } while (j < 2000); +} + +// Range-based for loops. +void cxx_for_loops(int *A, int vectorSize) { + // Loop with known array size should be unrolled. + int a[] = {0, 1, 2, 3, 4, 5}; + for (int k : a) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[k]++; + } + +// Loop with known size correctly unrolled. +#pragma unroll + for (int k : a) { + A[k]++; + } + + // Loop with unknown size should be partially unrolled. + int b[vectorSize]; +#pragma unroll + for (int k : b) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + k++; + } + +// Loop with unknown size correctly unrolled. +#pragma unroll 5 + for (int k : b) { + k++; + } + + // Loop with large size should be partially unrolled. + int c[51]; +#pragma unroll + for (int k : c) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[k]++; + } + +// Loop with large size correctly unrolled. +#pragma unroll 5 + for (int k : c) { + A[k]++; + } +} + +// Simple for loops. +void for_loops(int *A, int size) { + // Recommend unrolling loops that aren't already unrolled. + for (int i = 0; i < 2000; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[0] += i; + } + +// Loop with known size correctly unrolled. +#pragma unroll + for (int i = 0; i < 50; ++i) { + A[i]++; + } + +// Loop with unknown size should be partially unrolled. +#pragma unroll + for (int i = 0; i < size; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +#pragma unroll + for (;;) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[0]++; + } + + int i = 0; +#pragma unroll + for (; i < size; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +#pragma unroll + for (int i = 0;; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +#pragma unroll + for (int i = 0; i < size;) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +#pragma unroll + for (int i = size; i < 50; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +#pragma unroll + for (int i = 0; true; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +#pragma unroll + for (int i = 0; i == i; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +// Loop with unknown size correctly unrolled. +#pragma unroll 5 + for (int i = 0; i < size; ++i) { + A[i]++; + } + +// Loop with large size should be partially unrolled. +#pragma unroll + for (int i = 0; i < 51; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; + } + +// Loop with large size correctly unrolled. +#pragma unroll 5 + for (int i = 0; i < 51; ++i) { + A[i]++; + } +} + +// For loops with different increments. +void for_loop_increments(int *A) { +// ++ +#pragma unroll + for (int i = 0; i < 50; ++i) + A[i]++; // OK + +#pragma unroll + for (int i = 0; i < 51; ++i) + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; // Not OK + +// -- +#pragma unroll + for (int i = 50; i > 0; --i) + A[i]++; // OK + +#pragma unroll + for (int i = 51; i > 0; --i) + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; // Not OK + +// += +#pragma unroll + for (int i = 0; i < 100; i += 2) + A[i]++; // OK + +#pragma unroll + for (int i = 0; i < 101; i += 2) + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; // Not OK + +// -= +#pragma unroll + for (int i = 100; i > 0; i -= 2) + A[i]++; // OK + +#pragma unroll + for (int i = 101; i > 0; i -= 2) + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[i]++; // Not OK +} + +// Inner loops should be unrolled. +void nested_simple_loops(int *A) { + for (int i = 0; i < 1000; ++i) { + for (int j = 0; j < 2000; ++j) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[0] += i + j; + } + } + + for (int i = 0; i < 1000; ++i) { + int j = 0; + while (j < 2000) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[1] += i + j; + j++; + } + } + + for (int i = 0; i < 1000; ++i) { + int j = 0; + do { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[2] += i + j; + j++; + } while (j < 2000); + } + + int i = 0; + while (i < 1000) { + for (int j = 0; j < 2000; ++j) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[3] += i + j; + } + i++; + } + + i = 0; + while (i < 1000) { + int j = 0; + while (j < 2000) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[4] += i + j; + j++; + } + i++; + } + + i = 0; + while (i < 1000) { + int j = 0; + do { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[5] += i + j; + j++; + } while (j < 2000); + i++; + } + + i = 0; + do { + for (int j = 0; j < 2000; ++j) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[6] += i + j; + } + i++; + } while (i < 1000); + + i = 0; + do { + int j = 0; + while (j < 2000) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[7] += i + j; + j++; + } + i++; + } while (i < 1000); + + i = 0; + do { + int j = 0; + do { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[8] += i + j; + j++; + } while (j < 2000); + i++; + } while (i < 1000); + + for (int i = 0; i < 100; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + A[i]++; + } + + i = 0; + while (i < 100) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + i++; + } + + i = 0; + do { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] + i++; + } while (i < 100); +} + +// These loops are all correctly unrolled. +void unrolled_nested_simple_loops(int *A) { + for (int i = 0; i < 1000; ++i) { +#pragma unroll + for (int j = 0; j < 50; ++j) { + A[0] += i + j; + } + } + + for (int i = 0; i < 1000; ++i) { + int j = 0; +#pragma unroll 5 + while (j < 50) { + A[1] += i + j; + j++; + } + } + + for (int i = 0; i < 1000; ++i) { + int j = 0; +#pragma unroll 5 + do { + A[2] += i + j; + j++; + } while (j < 50); + } + + int i = 0; + while (i < 1000) { +#pragma unroll + for (int j = 0; j < 50; ++j) { + A[3] += i + j; + } + i++; + } + + i = 0; + while (i < 1000) { + int j = 0; +#pragma unroll 5 + while (50 > j) { + A[4] += i + j; + j++; + } + i++; + } + + i = 0; + while (1000 > i) { + int j = 0; +#pragma unroll 5 + do { + A[5] += i + j; + j++; + } while (j < 50); + i++; + } + + i = 0; + do { +#pragma unroll + for (int j = 0; j < 50; ++j) { + A[6] += i + j; + } + i++; + } while (i < 1000); + + i = 0; + do { + int j = 0; +#pragma unroll 5 + while (j < 50) { + A[7] += i + j; + j++; + } + i++; + } while (i < 1000); + + i = 0; + do { + int j = 0; +#pragma unroll 5 + do { + A[8] += i + j; + j++; + } while (j < 50); + i++; + } while (i < 1000); +} + +// These inner loops are large and should be partially unrolled. +void unrolled_nested_simple_loops_large_num_iterations(int *A) { + for (int i = 0; i < 1000; ++i) { +#pragma unroll + for (int j = 0; j < 51; ++j) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[0] += i + j; + } + } + + int i = 0; + while (i < 1000) { +#pragma unroll + for (int j = 0; j < 51; ++j) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[3] += i + j; + } + i++; + } + + i = 0; + do { +#pragma unroll + for (int j = 0; j < 51; ++j) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[6] += i + j; + } + i++; + } while (i < 1000); + + i = 0; + do { + int j = 0; +#pragma unroll + do { + // CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive + A[8] += i + j; + j++; + } while (j < 51); + i++; + } while (i < 1000); + + i = 0; + int a[51]; + do { +#pragma unroll + for (int k : a) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + A[k]++; + } + } while (i < 1000); +} + +// These loops have unknown bounds and should be partially unrolled. +void fully_unrolled_unknown_bounds(int vectorSize) { + int someVector[101]; + +// There is no loop condition +#pragma unroll + for (;;) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + someVector[0]++; + } + +#pragma unroll + for (int i = 0; 1 < 5; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + someVector[i]++; + } + +// Both sides are value-dependent +#pragma unroll + for (int i = 0; i < vectorSize; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops] + someVector[i]++; + } +} +#endif +// There are no fix-its for this check diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-terminating-continue.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-terminating-continue.cpp index 4bdcbc42fc47..04fc4a80ea7d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-terminating-continue.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-terminating-continue.cpp @@ -32,6 +32,15 @@ void f() { // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue] // CHECK-FIXES: if (x > 0) break; } while (false); + + switch (2) { + case 2: + do { + continue; // LoopInSwitch + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue] + // CHECK-FIXES: break; // LoopInSwitch + } while (0); + } } void g() { @@ -62,4 +71,12 @@ void g() { if (n>2) continue; } } while (false); + + do { + switch (2) { + case 1: + case 2: + continue; + } + } while (false); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp index dcde32d0f069..7c13c1c61cf2 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp @@ -1,4 +1,13 @@ -// RUN: %check_clang_tidy -std=c++17-or-later %s modernize-concat-nested-namespaces %t +// RUN: cp %S/Inputs/modernize-concat-nested-namespaces/modernize-concat-nested-namespaces.h %T/modernize-concat-nested-namespaces.h +// RUN: %check_clang_tidy -std=c++17 %s modernize-concat-nested-namespaces %t -- -header-filter=".*" -- -I %T +// RUN: FileCheck -input-file=%T/modernize-concat-nested-namespaces.h %S/Inputs/modernize-concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES +// Restore header file and re-run with c++20: +// RUN: cp %S/Inputs/modernize-concat-nested-namespaces/modernize-concat-nested-namespaces.h %T/modernize-concat-nested-namespaces.h +// RUN: %check_clang_tidy -std=c++20 %s modernize-concat-nested-namespaces %t -- -header-filter=".*" -- -I %T +// RUN: FileCheck -input-file=%T/modernize-concat-nested-namespaces.h %S/Inputs/modernize-concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES + +#include "modernize-concat-nested-namespaces.h" +// CHECK-MESSAGES-DAG: modernize-concat-nested-namespaces.h:1:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] namespace n1 {} @@ -27,7 +36,7 @@ void t(); namespace n9 { namespace n10 { -// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] // CHECK-FIXES: namespace n9::n10 void t(); } // namespace n10 @@ -36,7 +45,7 @@ void t(); namespace n11 { namespace n12 { -// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] // CHECK-FIXES: namespace n11::n12 namespace n13 { void t(); @@ -60,7 +69,7 @@ void t(); namespace n18 { namespace n19 { namespace n20 { -// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] // CHECK-FIXES: namespace n18::n19::n20 void t(); } // namespace n20 @@ -83,7 +92,7 @@ namespace n23 { namespace { namespace n24 { namespace n25 { -// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] // CHECK-FIXES: namespace n24::n25 void t(); } // namespace n25 @@ -95,7 +104,7 @@ void t(); namespace n26::n27 { namespace n28 { namespace n29::n30 { -// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] // CHECK-FIXES: namespace n26::n27::n28::n29::n30 void t() {} } // namespace n29::n30 @@ -105,14 +114,14 @@ void t() {} namespace n31 { namespace n32 {} -// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] } // namespace n31 // CHECK-FIXES-EMPTY namespace n33 { namespace n34 { namespace n35 {} -// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] } // namespace n34 // CHECK-FIXES-EMPTY namespace n36 { @@ -127,7 +136,7 @@ void t(); #define IEXIST namespace n39 { namespace n40 { -// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] // CHECK-FIXES: namespace n39::n40 #ifdef IEXIST void t() {} @@ -138,7 +147,7 @@ void t() {} namespace n41 { namespace n42 { -// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] +// CHECK-MESSAGES-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] // CHECK-FIXES: namespace n41::n42 #ifdef IDONTEXIST void t() {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements.cpp index 8dc5bf150fa3..494c2b780a7c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements.cpp @@ -74,30 +74,41 @@ void test() { do_something("for"); // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces // CHECK-FIXES: for (;;) { - // CHECK-FIXES: } + // CHECK-FIXES-NEXT: do_something("for"); + // CHECK-FIXES-NEXT: } + for (;;) { - do_something("for"); + do_something("for-ok"); } for (;;) ; // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces // CHECK-FIXES: for (;;) { - // CHECK-FIXES: } + // CHECK-FIXES-NEXT: ; + // CHECK-FIXES-NEXT: } int arr[4] = {1, 2, 3, 4}; for (int a : arr) do_something("for-range"); // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces // CHECK-FIXES: for (int a : arr) { - // CHECK-FIXES: } - for (int a : arr) { + // CHECK-FIXES-NEXT: do_something("for-range"); + // CHECK-FIXES-NEXT: } + for (int &assign : arr) + assign = 7; + // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: statement should be inside braces + // CHECK-FIXES: for (int &assign : arr) { + // CHECK-FIXES-NEXT: assign = 7; + // CHECK-FIXES-NEXT: } + for (int ok : arr) { do_something("for-range"); } - for (int a : arr) + for (int NullStmt : arr) ; - // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces - // CHECK-FIXES: for (int a : arr) { - // CHECK-FIXES: } + // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: statement should be inside braces + // CHECK-FIXES: for (int NullStmt : arr) { + // CHECK-FIXES-NEXT: ; + // CHECK-FIXES-NEXT: } while (cond("while1")) do_something("while"); @@ -143,14 +154,19 @@ void test() { // CHECK-FIXES-NEXT: } if (cond("ifif3")) - // comment + // comment1 if (cond("ifif4")) { - // comment - /*comment*/; // comment + // comment2 + /*comment3*/; // comment4 } // CHECK-MESSAGES: :[[@LINE-6]]:21: warning: statement should be inside braces // CHECK-FIXES: if (cond("ifif3")) { - // CHECK-FIXES: } + // CHECK-FIXES-NEXT: // comment1 + // CHECK-FIXES-NEXT: if (cond("ifif4")) { + // CHECK-FIXES-NEXT: // comment2 + // CHECK-FIXES-NEXT: /*comment3*/; // comment4 + // CHECK-FIXES-NEXT: } + // CHECK-FIXES-NEXT: } if (cond("ifif5")) ; /* multi-line @@ -170,6 +186,161 @@ void test() { // CHECK-FIXES-NEXT: } // CHECK-FIXES-NEXT: } // CHECK-FIXES-NEXT: } + + int S; + if (cond("assign with brackets")) + S = {5}; + // CHECK-MESSAGES: :[[@LINE-2]]:36: warning: statement should be inside braces + // CHECK-FIXES: if (cond("assign with brackets")) { + // CHECK-FIXES-NEXT: S = {5}; + // CHECK-FIXES-NEXT: } + + if (cond("assign with brackets 2")) + S = { 5 } /* comment1 */ ; /* comment2 */ + // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: statement should be inside braces + // CHECK-FIXES: if (cond("assign with brackets 2")) { + // CHECK-FIXES-NEXT: S = { 5 } /* comment1 */ ; /* comment2 */ + // CHECK-FIXES-NEXT: } + + if (cond("return")) + return; + // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: statement should be inside braces + // CHECK-FIXES: if (cond("return")) { + // CHECK-FIXES-NEXT: return; + // CHECK-FIXES-NEXT: } + + while (cond("break and continue")) { + // CHECK-FIXES: while (cond("break and continue")) { + if (true) + break; + // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: statement should be inside braces + // CHECK-FIXES: {{^}} if (true) {{{$}} + // CHECK-FIXES-NEXT: {{^}} break;{{$}} + // CHECK-FIXES-NEXT: {{^ *}}}{{$}} + if (false) + continue; + // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: statement should be inside braces + // CHECK-FIXES: {{^}} if (false) {{{$}} + // CHECK-FIXES-NEXT: {{^}} continue;{{$}} + // CHECK-FIXES-NEXT: {{^ *}}}{{$}} + } //end + // CHECK-FIXES: } //end + + if (cond("decl 1")) + int s; + else + int t; + // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces + // CHECK-FIXES: if (cond("decl 1")) { + // CHECK-FIXES-NEXT: int s; + // CHECK-FIXES-NEXT: } else { + // CHECK-FIXES-NEXT: int t; + // CHECK-FIXES-NEXT: } + + if (cond("decl 2")) + int s = (5); + else + int t = (5); + // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces + // CHECK-FIXES: if (cond("decl 2")) { + // CHECK-FIXES-NEXT: int s = (5); + // CHECK-FIXES-NEXT: } else { + // CHECK-FIXES-NEXT: int t = (5); + // CHECK-FIXES-NEXT: } + + if (cond("decl 3")) + int s = {6}; + else + int t = {6}; + // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces + // CHECK-FIXES: if (cond("decl 3")) { + // CHECK-FIXES-NEXT: int s = {6}; + // CHECK-FIXES-NEXT: } else { + // CHECK-FIXES-NEXT: int t = {6}; + // CHECK-FIXES-NEXT: } +} + +void test_whitespace() { + while(cond("preserve empty lines")) + if(cond("using continue within if")) + continue; + + + test(); + + // CHECK-MESSAGES: :[[@LINE-7]]:{{[0-9]+}}: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-7]]:{{[0-9]+}}: warning: statement should be inside braces + // CHECK-FIXES: {{^}} while(cond("preserve empty lines")) {{{$}} + // CHECK-FIXES-NEXT: {{^}} if(cond("using continue within if")) {{{$}} + // CHECK-FIXES-NEXT: {{^ continue;$}} + // The closing brace is added at beginning of line, clang-format can be + // applied afterwards. + // CHECK-FIXES-NEXT: {{^}$}} + // CHECK-FIXES-NEXT: {{^}$}} + // Following whitespace is assumed to not to belong to the else branch. + // However the check is not possible with CHECK-FIXES-NEXT. + // CHECK-FIXES: {{^}} test();{{$}} + + if (cond("preserve empty lines")) + + + int s; + + + else + + + int t; + + + test(); + + // CHECK-MESSAGES: :[[@LINE-14]]:{{[0-9]+}}: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-9]]:{{[0-9]+}}: warning: statement should be inside braces + // CHECK-FIXES: {{^}} if (cond("preserve empty lines")) {{{$}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ int s;$}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ } else {$}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ int t;$}} + // The closing brace is added at beginning of line, clang-format can be + // applied afterwards. + // CHECK-FIXES-NEXT: {{^}$}} + // Following whitespace is assumed to not to belong to the else branch. + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^}} test();{{$}} +} + +int test_return_int() { + if (cond("return5")) + return 5; + // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: statement should be inside braces + // CHECK-FIXES: if (cond("return5")) { + // CHECK-FIXES-NEXT: return 5; + // CHECK-FIXES-NEXT: } + + if (cond("return{6}")) + return {6}; + // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces + // CHECK-FIXES: if (cond("return{6}")) { + // CHECK-FIXES-NEXT: return {6}; + // CHECK-FIXES-NEXT: } + + // From https://bugs.llvm.org/show_bug.cgi?id=25970 + if (cond("25970")) return {25970}; + return {!25970}; + // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces + // CHECK-FIXES: if (cond("25970")) { return {25970}; + // CHECK-FIXES-NEXT: } + // CHECK-FIXES-NEXT: return {!25970}; } void f(const char *p) { @@ -203,4 +374,86 @@ int test_macros(bool b) { // CHECK-FIXES: {{^}} for (;;) {{{$}} // CHECK-FIXES-NEXT: {{^ ;$}} // CHECK-FIXES-NEXT: {{^}$}} + + + #define WRAP(X) { X; } + // This is to ensure no other CHECK-FIXES matches the macro definition: + // CHECK-FIXES: WRAP + + // Use-case: LLVM_DEBUG({ for(...) do_something(); }); + WRAP({ + for (;;) + do_something("for in wrapping macro 1"); + }); + // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces + // CHECK-FIXES: for (;;) { + // CHECK-FIXES-NEXT: do_something("for in wrapping macro 1"); + // CHECK-FIXES-NEXT: } + + // Use-case: LLVM_DEBUG( for(...) do_something(); ); + WRAP( + for (;;) + do_something("for in wrapping macro 2"); + ); + // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces + // CHECK-FIXES: for (;;) { + // CHECK-FIXES-NEXT: do_something("for in wrapping macro 2"); + // CHECK-FIXES-NEXT: } + + // Use-case: LLVM_DEBUG( for(...) do_something() ); + // This is not supported and this test ensure it's correctly not changed. + // We don't want to add the `}` into the Macro and there is no other way + // to add it except for introduction of a NullStmt. + WRAP( + for (;;) + do_something("for in wrapping macro 3") + ); + // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces + // CHECK-FIXES: WRAP( + // CHECK-FIXES-NEXT: for (;;) + // CHECK-FIXES-NEXT: do_something("for in wrapping macro 3") + // CHECK-FIXES-NEXT: ); + + // Taken from https://bugs.llvm.org/show_bug.cgi?id=22785 + int i; + #define MACRO_1 i++ + #define MACRO_2 + if( i % 3) i--; + else if( i % 2) MACRO_1; + else MACRO_2; + // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:18: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces + // CHECK-FIXES: if( i % 3) { i--; + // CHECK-FIXES-NEXT: } else if( i % 2) { MACRO_1; + // CHECK-FIXES-NEXT: } else { MACRO_2; + // CHECK-FIXES-NEXT: } + + // Taken from https://bugs.llvm.org/show_bug.cgi?id=22785 + #define M(x) x + + if (b) + return 1; + else + return 2; + // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces + // CHECK-FIXES: if (b) { + // CHECK-FIXES-NEXT: return 1; + // CHECK-FIXES-NEXT: } else { + // CHECK-FIXES-NEXT: return 2; + // CHECK-FIXES-NEXT: } + + if (b) + return 1; + else + M(return 2); + // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces + // CHECK-FIXES: if (b) { + // CHECK-FIXES-NEXT: return 1; + // CHECK-FIXES-NEXT: } else { + // CHECK-FIXES-NEXT: M(return 2); + // CHECK-FIXES-NEXT: } + } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-deleted-default.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-deleted-default.cpp deleted file mode 100644 index 232f224128a6..000000000000 --- a/clang-tools-extra/test/clang-tidy/checkers/readability-deleted-default.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// RUN: %check_clang_tidy %s readability-deleted-default %t -- -- -fno-ms-compatibility - -class NoDefault { -public: - NoDefault() = delete; - NoDefault(NoDefault &&Other) = delete; - NoDefault(const NoDefault &Other) = delete; -}; - -class MissingEverything { -public: - MissingEverything() = default; - // CHECK-MESSAGES: warning: default constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is lacking a default constructor; definition can either be removed or explicitly deleted [readability-deleted-default] - MissingEverything(MissingEverything &&Other) = default; - // CHECK-MESSAGES: warning: move constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is neither copyable nor movable; definition can either be removed or explicitly deleted [readability-deleted-default] - MissingEverything(const MissingEverything &Other) = default; - // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is not copyable; definition can either be removed or explicitly deleted [readability-deleted-default] - MissingEverything &operator=(MissingEverything &&Other) = default; - // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default] - MissingEverything &operator=(const MissingEverything &Other) = default; - // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default] - -private: - NoDefault ND; -}; - -class NotAssignable { -public: - NotAssignable(NotAssignable &&Other) = default; - NotAssignable(const NotAssignable &Other) = default; - NotAssignable &operator=(NotAssignable &&Other) = default; - // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted - NotAssignable &operator=(const NotAssignable &Other) = default; - // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted - -private: - const int I = 0; -}; - -class Movable { -public: - Movable() = default; - Movable(Movable &&Other) = default; - Movable(const Movable &Other) = delete; - Movable &operator=(Movable &&Other) = default; - Movable &operator=(const Movable &Other) = delete; -}; - -class NotCopyable { -public: - NotCopyable(NotCopyable &&Other) = default; - NotCopyable(const NotCopyable &Other) = default; - // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted - NotCopyable &operator=(NotCopyable &&Other) = default; - NotCopyable &operator=(const NotCopyable &Other) = default; - // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted -private: - Movable M; -}; - -template class Templated { -public: - // No warning here, it is a templated class. - Templated() = default; - Templated(Templated &&Other) = default; - Templated(const Templated &Other) = default; - Templated &operator=(Templated &&Other) = default; - Templated &operator=(const Templated &Other) = default; - - class InnerTemplated { - public: - // This class is not in itself templated, but we still don't have warning. - InnerTemplated() = default; - InnerTemplated(InnerTemplated &&Other) = default; - InnerTemplated(const InnerTemplated &Other) = default; - InnerTemplated &operator=(InnerTemplated &&Other) = default; - InnerTemplated &operator=(const InnerTemplated &Other) = default; - - private: - T TVar; - }; - - class InnerNotTemplated { - public: - // This one could technically have warnings, but currently doesn't. - InnerNotTemplated() = default; - InnerNotTemplated(InnerNotTemplated &&Other) = default; - InnerNotTemplated(const InnerNotTemplated &Other) = default; - InnerNotTemplated &operator=(InnerNotTemplated &&Other) = default; - InnerNotTemplated &operator=(const InnerNotTemplated &Other) = default; - - private: - int I; - }; - -private: - const T TVar{}; -}; - -int FunctionWithInnerClass() { - class InnerNotAssignable { - public: - InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default; - // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted - private: - const int I = 0; - }; - return 1; -}; - -template -int TemplateFunctionWithInnerClass() { - class InnerNotAssignable { - public: - InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default; - private: - const T TVar{}; - }; - return 1; -}; - -void Foo() { - Templated V1; - Templated::InnerTemplated V2; - Templated::InnerNotTemplated V3; - TemplateFunctionWithInnerClass(); -} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp index f66202ecd11b..11ffc6c16615 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp @@ -148,6 +148,10 @@ int global3; int g_twice_global3 = ADD_TO_SELF(global3); // CHECK-FIXES: {{^}}int g_twice_global3 = ADD_TO_SELF(g_global3);{{$}} +int g_Global4; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for global variable 'g_Global4' +// CHECK-FIXES: {{^}}int g_global4;{{$}} + enum my_enumeration { // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: invalid case style for enum 'my_enumeration' // CHECK-FIXES: {{^}}enum EMyEnumeration {{{$}} @@ -544,6 +548,9 @@ unsigned const MyConstGlobal_array[] = {1,2,3}; // CHECK-FIXES: {{^}}unsigned const MY_CONST_GLOBAL_ARRAY[] = {1,2,3};{{$}} int * MyGlobal_Ptr;// -> ok +int * my_second_global_Ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for global pointer 'my_second_global_Ptr' +// CHECK-FIXES: {{^}}int * MySecondGlobal_Ptr;{{$}} int * const MyConstantGlobalPointer = nullptr; // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for global constant pointer 'MyConstantGlobalPointer' // CHECK-FIXES: {{^}}int * const MY_CONSTANT_GLOBAL_POINTER_Ptr = nullptr;{{$}} diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-spaces b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-spaces new file mode 100644 index 000000000000..4aa1f846ade6 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-spaces @@ -0,0 +1,9 @@ +Checks: " + -* + , + hicpp-uppercase-literal-suffix + ,hicpp-use-auto + + + , hicpp-use-emplace +" diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp index 49028d198f75..16b216a1d4f6 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp @@ -1,2 +1,8 @@ // RUN: clang-tidy -config-file=%S/Inputs/config-file/config-file -dump-config -- | FileCheck %s -check-prefix=CHECK-BASE // CHECK-BASE: Checks: {{.*}}hicpp-uppercase-literal-suffix +// RUN: clang-tidy -config-file=%S/Inputs/config-file/config-file-spaces --list-checks -- | FileCheck %s -check-prefix=CHECK-SPACES +// CHECK-SPACES: Enabled checks: +// CHECK-SPACES-NEXT: hicpp-uppercase-literal-suffix +// CHECK-SPACES-NEXT: hicpp-use-auto +// CHECK-SPACES-NEXT: hicpp-use-emplace +// CHECK-SPACES-EMPTY: diff --git a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp index ba6ad112dfa4..d5578cf16f59 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp @@ -39,7 +39,8 @@ // CHECK-NEXT: Reason: EnterFile // CHECK-NEXT: FileType: C_User // CHECK-NEXT: PrevFID: (invalid) -// CHECK-NEXT: - Callback: FileChanged +// CHECK: - Callback: MacroDefined +// CHECK: - Callback: FileChanged // CHECK-NEXT: Loc: ":1:1" // CHECK-NEXT: Reason: ExitFile // CHECK-NEXT: FileType: C_User diff --git a/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp b/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp index 47f9e1c4ff6a..1d85607e86b7 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp @@ -31,6 +31,7 @@ X // CHECK: MacroNameTok: __STDC_UTF_32__ // CHECK-NEXT: MacroDirective: MD_Define // CHECK: - Callback: MacroDefined +// CHECK: - Callback: MacroDefined // CHECK-NEXT: MacroNameTok: MACRO // CHECK-NEXT: MacroDirective: MD_Define // CHECK-NEXT: - Callback: MacroExpands diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 4695dc8a46ff..95cdbd8f6663 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -113,6 +113,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) include(TableGen) include(HandleLLVMOptions) include(VersionFromVCS) + include(GetErrcMessages) include(LLVMDistributionSupport) set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}") @@ -131,7 +132,8 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX} ) if(LLVM_INCLUDE_TESTS) - find_package(Python3 REQUIRED COMPONENTS Interpreter) + find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION} REQUIRED + COMPONENTS Interpreter) # Check prebuilt llvm/utils. if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX} @@ -176,6 +178,8 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) endif() set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") + get_errc_messages(LLVM_LIT_ERRC_MESSAGES) + # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools. if( WIN32 AND NOT CYGWIN ) set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") @@ -463,7 +467,8 @@ option(CLANG_ENABLE_STATIC_ANALYZER option(CLANG_ENABLE_PROTO_FUZZER "Build Clang protobuf fuzzer." OFF) -option(CLANG_ROUND_TRIP_CC1_ARGS "Round-trip command line arguments in -cc1." OFF) +option(CLANG_ROUND_TRIP_CC1_ARGS + "Round-trip command line arguments in -cc1." ${LLVM_ENABLE_ASSERTIONS}) if(NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT) message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3") @@ -636,6 +641,11 @@ if (CLANG_ENABLE_BOOTSTRAP) set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-bins/) if(BOOTSTRAP_LLVM_ENABLE_LLD) + # adding lld to clang-bootstrap-deps without having it enabled in + # LLVM_ENABLE_PROJECTS just generates a cryptic error message. + if (NOT "lld" IN_LIST LLVM_ENABLE_PROJECTS) + message(FATAL_ERROR "LLD is enabled in the boostrap build, but lld is not in LLVM_ENABLE_PROJECTS") + endif() add_dependencies(clang-bootstrap-deps lld) endif() @@ -855,13 +865,24 @@ if (CLANG_ENABLE_BOOTSTRAP) set(CLANG_BOOTSTRAP_TARGETS check-llvm check-clang check-all) endif() foreach(target ${CLANG_BOOTSTRAP_TARGETS}) - # exclude from main target - set_target_properties(${NEXT_CLANG_STAGE} PROPERTIES _EP_${target}_EXCLUDE_FROM_MAIN On) + # Install targets have side effects, so we always want to execute them. + # "install" is reserved by CMake and can't be used as a step name for + # ExternalProject_Add_Step, so we can match against "^install-" instead of + # "^install" to get a tighter match. CMake's installation scripts already + # skip up-to-date files, so there's no behavior change if you install to the + # same destination multiple times. + if(target MATCHES "^install-") + set(step_always ON) + else() + set(step_always OFF) + endif() ExternalProject_Add_Step(${NEXT_CLANG_STAGE} ${target} COMMAND ${CMAKE_COMMAND} --build --target ${target} COMMENT "Performing ${target} for '${NEXT_CLANG_STAGE}'" DEPENDEES configure + ALWAYS ${step_always} + EXCLUDE_FROM_MAIN ON USES_TERMINAL 1 ) diff --git a/clang/cmake/caches/3-stage-base.cmake b/clang/cmake/caches/3-stage-base.cmake index 88ab5d77f16f..31391aa4defc 100644 --- a/clang/cmake/caches/3-stage-base.cmake +++ b/clang/cmake/caches/3-stage-base.cmake @@ -1,14 +1,34 @@ set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "") set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "") set(LLVM_BUILD_EXTERNAL_COMPILER_RT ON CACHE BOOL "") -set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") -# Use LLD do have less requirements on system linker, unless we're on an apple -# platform where the system compiler is to be prefered. if(APPLE) + # Use LLD to have fewer requirements on system linker, unless we're on an apple + # platform where the system compiler is to be preferred. + set(BOOTSTRAP_LLVM_ENABLE_LLD OFF CACHE BOOL "") + set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") +elseif(CMAKE_HOST_UNIX) + # s390/SystemZ is unsupported by LLD, so don't try to enable LTO if it + # cannot work. + # We do our own uname business here since the appropriate variables from CMake + # and llvm are not yet available. + find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin ) + if(CMAKE_UNAME) + exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR + RETURN_VALUE val) + endif(CMAKE_UNAME) + + if("${CMAKE_HOST_SYSTEM_PROCESSOR}" MATCHES "s390") + set(BOOTSTRAP_LLVM_ENABLE_LTO OFF CACHE BOOL "") set(BOOTSTRAP_LLVM_ENABLE_LLD OFF CACHE BOOL "") -else() + else() + set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") set(BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "") + endif() + +else() + set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") + set(BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "") endif() diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 667e33c700d5..27391bdafb3e 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -263,6 +263,7 @@ set(LLVM_TOOLCHAIN_TOOLS llvm-elfabi llvm-gsymutil llvm-lib + llvm-lipo llvm-mt llvm-nm llvm-objcopy diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index 2809f0192cdb..d61b5e6f04e4 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -116,15 +116,16 @@ endif() set(CLANG_BOOTSTRAP_TARGETS check-all - check-llvm check-clang check-lld + check-llvm + check-polly llvm-config - test-suite - test-depends - llvm-test-depends clang-test-depends lld-test-depends + llvm-test-depends + test-suite + test-depends distribution install-distribution install-distribution-stripped diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 0038dccd53f9..d895587c458a 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -18,9 +18,9 @@ GCC-compatible ``clang`` and ``clang++`` drivers. .. program:: clang -.. option:: -B, --prefix , --prefix= +.. option:: -B, --prefix , --prefix= -Add to search path for binaries and object files used implicitly +Search $prefix/$triple-$file and $prefix$file for executables, libraries, includes, and data files used by the compiler. $prefix may or may not be a directory .. option:: -F @@ -256,7 +256,7 @@ Build this module as a system module. Only used with -emit-module .. option:: --gcc-toolchain=, -gcc-toolchain -Use the gcc toolchain at the given directory +Search for GCC installation in the specified directory on targets which commonly use GCC. The directory usually contains 'lib{,32,64}/gcc{,-cross}/$triple' and 'include'. If specified, sysroot is skipped for GCC detection. Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation .. option:: -gcodeview @@ -2797,10 +2797,6 @@ Use packed stack layout (SystemZ only). Specify maximum number of prefixes to use for padding -.. option:: -mpie-copy-relocations, -mno-pie-copy-relocations - -Use copy relocations support for PIE builds - .. option:: -mprefer-vector-width= Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions. @@ -3798,4 +3794,3 @@ undef all system defines .. option:: -z Pass -z to the linker - diff --git a/clang/docs/DiagnosticsReference.rst b/clang/docs/DiagnosticsReference.rst deleted file mode 100644 index 04d7f74d5bfc..000000000000 --- a/clang/docs/DiagnosticsReference.rst +++ /dev/null @@ -1,14010 +0,0 @@ -.. - ------------------------------------------------------------------- - NOTE: This file is automatically generated by running clang-tblgen - -gen-diag-docs. Do not edit this file by hand!! - ------------------------------------------------------------------- - -.. Add custom CSS to output. FIXME: This should be put into rather - than the start of . -.. raw:: html - - - -.. FIXME: rST doesn't support formatting this, so we format all elements - as monospace font face instead. -.. |nbsp| unicode:: 0xA0 - :trim: - -.. Roles generated by clang-tblgen. -.. role:: error -.. role:: warning -.. role:: remark -.. role:: diagtext -.. role:: placeholder(emphasis) - -========================= -Diagnostic flags in Clang -========================= -.. contents:: - :local: - -Introduction -============ - -This page lists the diagnostic flags currently supported by Clang. - -Diagnostic flags -================ - --W --- -Synonym for `-Wextra`_. - - --W#pragma-messages ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --W#warnings ------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --WCFString-literal ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`input conversion stopped due to an input byte that does not belong to the input codeset UTF-8`| -+------------------------------------------------------------------------------------------------------------------------------------+ - - --WCL4 ------ -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wall`_, `-Wextra`_. - - --WIndependentClass-attribute ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'objc\_independent\_class' attribute may be put on a typedef only; attribute is ignored`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'objc\_independent\_class' attribute may be put on Objective-C object pointer type only; attribute is ignored`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --WNSObject-attribute --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'NSObject' attribute may be put on a typedef only; attribute is ignored`| -+--------------------------------------------------------------------------------------------------------------+ - - --Wabi ------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wabsolute-value ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`absolute value function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`given an argument of type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`but has parameter of type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`which may cause truncation of value`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------+----------------------+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`taking the absolute value of` |nbsp| |+--------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is suspicious`| -| ||:diagtext:`pointer` || | -| |+--------------------+| | -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`array` || | -| |+--------------------+| | -+---------------------------------------------------------------------------+----------------------+---------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`taking the absolute value of unsigned type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has no effect`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------------+----------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using` |nbsp| |+--------------------------+| |nbsp| :diagtext:`absolute value function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`when argument is of` |nbsp| |+--------------------------+| |nbsp| :diagtext:`type`| -| ||:diagtext:`integer` || ||:diagtext:`integer` || | -| |+--------------------------+| |+--------------------------+| | -| ||:diagtext:`floating point`|| ||:diagtext:`floating point`|| | -| |+--------------------------+| |+--------------------------+| | -| ||:diagtext:`complex` || ||:diagtext:`complex` || | -| |+--------------------------+| |+--------------------------+| | -+----------------------------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------------+----------------------------+------------------------+ - - --Wabstract-final-class ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------+--------------------+-------------+ -|:warning:`warning:` |nbsp| :diagtext:`abstract class is marked '`|+------------------+|:diagtext:`'`| -| ||:diagtext:`final` || | -| |+------------------+| | -| ||:diagtext:`sealed`|| | -| |+------------------+| | -+-----------------------------------------------------------------+--------------------+-------------+ - - --Wabstract-vbase-init ---------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializer for virtual base class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of abstract class` |nbsp| :placeholder:`B` |nbsp| :diagtext:`will never be used`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Waddress ---------- -This diagnostic is enabled by default. - -Controls `-Wpointer-bool-conversion`_, `-Wstring-compare`_, `-Wtautological-pointer-compare`_. - - --Waddress-of-packed-member --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`taking address of packed member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of class or structure` |nbsp| :placeholder:`B` |nbsp| :diagtext:`may result in an unaligned pointer value`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Waddress-of-temporary ----------------------- -This diagnostic is an error by default, but the flag ``-Wno-address-of-temporary`` can be used to disable the error. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`taking the address of a temporary object of type` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------------------------+ - - --Waggregate-return ------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wall ------ -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wmisleading-indentation`_, `-Wmost`_, `-Wparentheses`_, `-Wswitch`_, `-Wswitch-bool`_. - - --Walloca --------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is discouraged; there is no way to check for failure but failure may still occur, resulting in a possibly exploitable security vulnerability`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Walloca-with-align-alignof ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`second argument to \_\_builtin\_alloca\_with\_align is supposed to be in bits`| -+--------------------------------------------------------------------------------------------------------------------+ - - --Wambiguous-delete ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple suitable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`functions for` |nbsp| :placeholder:`B`:diagtext:`; no 'operator delete' function will be invoked if initialization throws an exception`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wambiguous-ellipsis --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+---------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'...' in this location creates a C-style varargs function`|+-------------------------------------------+| -| ||:diagtext:`, not a function parameter pack`|| -| |+-------------------------------------------+| -| || || -| |+-------------------------------------------+| -+------------------------------------------------------------------------------------------------+---------------------------------------------+ - - --Wambiguous-macro ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ambiguous expansion of macro` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------+ - - --Wambiguous-member-template ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`lookup of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in member access expression is ambiguous; using member of` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wambiguous-reversed-operator ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 considers use of overloaded operator '`:placeholder:`A`:diagtext:`' (with operand types` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C`:diagtext:`) to be ambiguous despite there being a unique best viable function`|+-----------------------------------------------+| -| || |nbsp| :diagtext:`with non-reversed arguments`|| -| |+-----------------------------------------------+| -| || || -| |+-----------------------------------------------+| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ - - --Wanalyzer-incompatible-plugin ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`checker plugin '`:placeholder:`A`:diagtext:`' is not compatible with this version of the analyzer`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - - --Wanon-enum-enum-conversion ---------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wdeprecated-anon-enum-enum-conversion`_. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+-----------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+-----------------------------------------------+ - - --Wanonymous-pack-parens ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++11 requires a parenthesized pack declaration to have a name`| -+---------------------------------------------------------------------------------------------------------+ - - --Warc ------ -This diagnostic is enabled by default. - -Controls `-Warc-non-pod-memaccess`_, `-Warc-retain-cycles`_, `-Warc-unsafe-retained-assign`_. - - --Warc-bridge-casts-disallowed-in-nonarc ---------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' casts have no effect when not using ARC`| -+-------------------------------------------------------------------------------------------------------------+ - - --Warc-maybe-repeated-use-of-weak --------------------------------- -**Diagnostic text:** - -+---------------------------------------------------+-------------------------------+------------------------------------------------------------------------------------------+----------------------+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`weak` |nbsp| |+-----------------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`may be accessed multiple times in this` |nbsp| |+--------------------+| |nbsp| :diagtext:`and may be unpredictably set to nil; assign to a strong variable to keep the object alive`| -| ||:diagtext:`variable` || ||:diagtext:`function`|| | -| |+-----------------------------+| |+--------------------+| | -| ||:diagtext:`property` || ||:diagtext:`method` || | -| |+-----------------------------+| |+--------------------+| | -| ||:diagtext:`implicit property`|| ||:diagtext:`block` || | -| |+-----------------------------+| |+--------------------+| | -| ||:diagtext:`instance variable`|| ||:diagtext:`lambda` || | -| |+-----------------------------+| |+--------------------+| | -+---------------------------------------------------+-------------------------------+------------------------------------------------------------------------------------------+----------------------+-------------------------------------------------------------------------------------------------------------+ - - --Warc-non-pod-memaccess ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------------+| |nbsp| :diagtext:`this` |nbsp| :placeholder:`B` |nbsp| :diagtext:`call is a pointer to ownership-qualified type` |nbsp| :placeholder:`C`| -| ||:diagtext:`destination for`|| | -| |+---------------------------+| | -| ||:diagtext:`source of` || | -| |+---------------------------+| | -+---------------------------+-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ - - --Warc-performSelector-leaks ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`performSelector may cause a leak because its selector is unknown`| -+-------------------------------------------------------------------------------------------------------+ - - --Warc-repeated-use-of-weak --------------------------- -Also controls `-Warc-maybe-repeated-use-of-weak`_. - -**Diagnostic text:** - -+---------------------------------------------------+-------------------------------+--------------------------------------------------------------------------------------+----------------------+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`weak` |nbsp| |+-----------------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`is accessed multiple times in this` |nbsp| |+--------------------+| |nbsp| :diagtext:`but may be unpredictably set to nil; assign to a strong variable to keep the object alive`| -| ||:diagtext:`variable` || ||:diagtext:`function`|| | -| |+-----------------------------+| |+--------------------+| | -| ||:diagtext:`property` || ||:diagtext:`method` || | -| |+-----------------------------+| |+--------------------+| | -| ||:diagtext:`implicit property`|| ||:diagtext:`block` || | -| |+-----------------------------+| |+--------------------+| | -| ||:diagtext:`instance variable`|| ||:diagtext:`lambda` || | -| |+-----------------------------+| |+--------------------+| | -+---------------------------------------------------+-------------------------------+--------------------------------------------------------------------------------------+----------------------+-------------------------------------------------------------------------------------------------------------+ - - --Warc-retain-cycles -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`capturing` |nbsp| :placeholder:`A` |nbsp| :diagtext:`strongly in this block is likely to lead to a retain cycle`| -+------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Warc-unsafe-retained-assign ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------+---------------------------------+-------------------------------------+----------------------+------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`assigning` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`to a weak` |nbsp| |+--------------------+|:diagtext:`; object will be released after assignment`| -| ||:diagtext:`array literal` || ||:diagtext:`property`|| | -| |+-------------------------------+| |+--------------------+| | -| ||:diagtext:`dictionary literal` || ||:diagtext:`variable`|| | -| |+-------------------------------+| |+--------------------+| | -| ||:diagtext:`numeric literal` || | | | -| |+-------------------------------+| | | | -| ||:diagtext:`boxed expression` || | | | -| |+-------------------------------+| | | | -| ||:diagtext:``|| | | | -| |+-------------------------------+| | | | -| ||:diagtext:`block literal` || | | | -| |+-------------------------------+| | | | -+--------------------------------------------------------+---------------------------------+-------------------------------------+----------------------+------------------------------------------------------+ - -+---------------------------------------------------------------------------+--------------------------------+--------+----------------------+------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`assigning retained object to` |nbsp| |+------------------------------+| |nbsp| |+--------------------+|:diagtext:`; object will be released after assignment`| -| ||:diagtext:`weak` || ||:diagtext:`property`|| | -| |+------------------------------+| |+--------------------+| | -| ||:diagtext:`unsafe\_unretained`|| ||:diagtext:`variable`|| | -| |+------------------------------+| |+--------------------+| | -+---------------------------------------------------------------------------+--------------------------------+--------+----------------------+------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`assigning retained object to unsafe property; object will be released after assignment`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wargument-outside-range ------------------------- -This diagnostic is an error by default, but the flag ``-Wno-argument-outside-range`` can be used to disable the error. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`argument value` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is outside the valid range \[`:placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`\]`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Warray-bounds --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+ -|:warning:`warning:` |nbsp| :diagtext:`array index` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is past the end of the array (which contains` |nbsp| :placeholder:`B` |nbsp| :diagtext:`element`|+-------------+|:diagtext:`)`| -| || || | -| |+-------------+| | -| ||:diagtext:`s`|| | -| |+-------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array index` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is before the beginning of the array`| -+----------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------+----------------------------------------------------------------------------+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array argument is too small;` |nbsp| |+--------------------------------------------------------------------------+|:diagtext:`, callee requires at least` |nbsp| :placeholder:`B`| -| ||+------------------------------------------------------------------------+|| | -| |||:diagtext:`contains` |nbsp| :placeholder:`A` |nbsp| :diagtext:`elements`||| | -| ||+------------------------------------------------------------------------+|| | -| |+--------------------------------------------------------------------------+| | -| ||+----------------------------------------------+ || | -| |||:diagtext:`is of size` |nbsp| :placeholder:`A`| || | -| ||+----------------------------------------------+ || | -| |+--------------------------------------------------------------------------+| | -+---------------------------------------------------------------------------+----------------------------------------------------------------------------+--------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'static' has no effect on zero-length arrays`| -+-----------------------------------------------------------------------------------+ - - --Warray-bounds-pointer-arithmetic ---------------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+ -|:warning:`warning:` |nbsp| :diagtext:`the pointer incremented by` |nbsp| :placeholder:`A` |nbsp| :diagtext:`refers past the end of the array (that contains` |nbsp| :placeholder:`B` |nbsp| :diagtext:`element`|+-------------+|:diagtext:`)`| -| || || | -| |+-------------+| | -| ||:diagtext:`s`|| | -| |+-------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the pointer decremented by` |nbsp| :placeholder:`A` |nbsp| :diagtext:`refers before the beginning of the array`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wasm ------ -Synonym for `-Wasm-operand-widths`_. - - --Wasm-operand-widths --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`value size does not match register size specified by the constraint and modifier`| -+-----------------------------------------------------------------------------------------------------------------------+ - - --Wassign-enum -------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`integer constant not in range of enumerated type` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------+ - - --Wassume --------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the argument to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has side effects that will be discarded`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - - --Wat-protocol -------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Watimport-in-framework-header ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of '@import' in framework header is discouraged, including this header requires -fmodules`| -+------------------------------------------------------------------------------------------------------------------------------------+ - - --Watomic-alignment ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+------------------------+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`atomic operation may incur significant performance penalty`| -| ||:diagtext:`large` || | -| |+----------------------+| | -| ||:diagtext:`misaligned`|| | -| |+----------------------+| | -+---------------------------+------------------------+------------------------------------------------------------------------------+ - - --Watomic-implicit-seq-cst -------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - - --Watomic-memory-ordering ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`memory order argument to atomic operation is invalid`| -+-------------------------------------------------------------------------------------------+ - - --Watomic-properties -------------------- -Controls `-Wcustom-atomic-properties`_, `-Wimplicit-atomic-properties`_. - - --Watomic-property-with-user-defined-accessor --------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------+--------------------+-----------------------------------------------+--------------------+ -|:warning:`warning:` |nbsp| :diagtext:`writable atomic property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot pair a synthesized` |nbsp| |+------------------+| |nbsp| :diagtext:`with a user defined` |nbsp| |+------------------+| -| ||:diagtext:`getter`|| ||:diagtext:`getter`|| -| |+------------------+| |+------------------+| -| ||:diagtext:`setter`|| ||:diagtext:`setter`|| -| |+------------------+| |+------------------+| -+--------------------------------------------------------------------------------------------------------------------------------------------+--------------------+-----------------------------------------------+--------------------+ - - --Wattribute-packed-for-bitfield -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'packed' attribute was ignored on bit-fields with single-byte alignment in older versions of GCC and Clang`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wattributes ------------- -This diagnostic is enabled by default. - -Controls `-Wignored-attributes`_, `-Wunknown-attributes`_. - - --Wauto-disable-vptr-sanitizer ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicitly disabling vptr sanitizer because rtti wasn't enabled`| -+------------------------------------------------------------------------------------------------------+ - - --Wauto-import -------------- -**Diagnostic text:** - -+-------------------------------------------------+---------------------------------+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`treating #`|+-------------------------------+| |nbsp| :diagtext:`as an import of module '`:placeholder:`B`:diagtext:`'`| -| ||:diagtext:`include` || | -| |+-------------------------------+| | -| ||:diagtext:`import` || | -| |+-------------------------------+| | -| ||:diagtext:`include\_next` || | -| |+-------------------------------+| | -| ||:diagtext:`\_\_include\_macros`|| | -| |+-------------------------------+| | -+-------------------------------------------------+---------------------------------+-------------------------------------------------------------------------+ - - --Wauto-storage-class --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wauto-var-id -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'auto' deduced as 'id' in declaration of` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------+ - - --Wavailability --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'unavailable' availability overrides all other availability information`| -+--------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring availability attribute` |nbsp| |+--------------------------------------+| -| ||:diagtext:`on '+load' method` || -| |+--------------------------------------+| -| ||:diagtext:`with constructor attribute`|| -| |+--------------------------------------+| -| ||:diagtext:`with destructor attribute` || -| |+--------------------------------------+| -+------------------------------------------------------------------------------+----------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`only 'unavailable' and 'deprecated' are supported for Swift availability`| -+---------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown platform` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in availability macro`| -+------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------+------------------------+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`feature cannot be` |nbsp| |+----------------------+| |nbsp| :diagtext:`in` |nbsp| :placeholder:`B` |nbsp| :diagtext:`version` |nbsp| :placeholder:`C` |nbsp| :diagtext:`before it was` |nbsp| |+----------------------+| |nbsp| :diagtext:`in version` |nbsp| :placeholder:`E`:diagtext:`; attribute ignored`| -| ||:diagtext:`introduced`|| ||:diagtext:`introduced`|| | -| |+----------------------+| |+----------------------+| | -| ||:diagtext:`deprecated`|| ||:diagtext:`deprecated`|| | -| |+----------------------+| |+----------------------+| | -| ||:diagtext:`obsoleted` || ||:diagtext:`obsoleted` || | -| |+----------------------+| |+----------------------+| | -+----------------------------------------------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------+------------------------+-------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use same version number separators '\_' or '.'; as in 'major\[.minor\[.subminor\]\]'`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`availability does not match previous declaration`| -+---------------------------------------------------------------------------------------+ - -+---------------------------+--------------------------------+--------------------------+-------------------------------+--------+-----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------+|:diagtext:`method` |nbsp| |+-----------------------------+| |nbsp| |+---------------------------------------------+| |nbsp| :diagtext:`on` |nbsp| :placeholder:`B` |nbsp| :diagtext:`(`:placeholder:`C` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`D`:diagtext:`)`| -| || || ||:diagtext:`introduced after` || ||:diagtext:`the protocol method it implements`|| | -| |+------------------------------+| |+-----------------------------+| |+---------------------------------------------+| | -| ||:diagtext:`overriding` |nbsp| || ||:diagtext:`deprecated before`|| ||:diagtext:`overridden method` || | -| |+------------------------------+| |+-----------------------------+| |+---------------------------------------------+| | -| | | ||:diagtext:`obsoleted before` || | | | -| | | |+-----------------------------+| | | | -+---------------------------+--------------------------------+--------------------------+-------------------------------+--------+-----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------+--------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------+|:diagtext:`method cannot be unavailable on` |nbsp| :placeholder:`A` |nbsp| :diagtext:`when` |nbsp| |+---------------------------------------------+| |nbsp| :diagtext:`is available`| -| || || ||:diagtext:`the protocol method it implements`|| | -| |+------------------------------+| |+---------------------------------------------+| | -| ||:diagtext:`overriding` |nbsp| || ||:diagtext:`its overridden method` || | -| |+------------------------------+| |+---------------------------------------------+| | -+---------------------------+--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------+--------------------------------+ - - --Wavr-rtlib-linking-quirks --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`support for linking stdlibs for microcontroller '`:placeholder:`A`:diagtext:`' is not implemented`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no avr-gcc installation can be found on the system, cannot link standard libraries`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no avr-libc installation can be found on the system, cannot link standard libraries`| -+--------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no target microcontroller specified on command line, cannot link standard libraries, please pass -mmcu=`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`standard library not linked and so no interrupt vector table or compiler runtime routines will be linked`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbackend-plugin ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --Wbackslash-newline-escape --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`backslash and newline separated by space`| -+-------------------------------------------------------------------------------+ - - --Wbad-function-cast -------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast from function call of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to non-matching type` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbinary-literal ----------------- -Controls `-Wc++14-binary-literal`_, `-Wc++98-c++11-compat-binary-literal`_, `-Wgnu-binary-literal`_. - - --Wbind-to-temporary-copy ------------------------- -Also controls `-Wc++98-compat-bind-to-temporary-copy`_. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C++98 requires an accessible copy constructor for class` |nbsp| :placeholder:`C` |nbsp| :diagtext:`when binding a reference to a temporary; was` |nbsp| |+---------------------+| -| ||:diagtext:`private` || -| |+---------------------+| -| ||:diagtext:`protected`|| -| |+---------------------+| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ - -+--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no viable constructor` |nbsp| |+----------------------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B`:diagtext:`; C++98 requires a copy constructor when binding a reference to a temporary`| -| ||:diagtext:`copying variable` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying parameter` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`returning object` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`initializing statement expression result`|| | -| |+----------------------------------------------------+| | -| ||:diagtext:`throwing object` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying member subobject` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying array element` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`allocating object` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying temporary` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`initializing base subobject` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`initializing vector element` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`capturing value` || | -| |+----------------------------------------------------+| | -+--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbinding-in-condition ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++17 does not permit structured binding declaration in a condition`| -+--------------------------------------------------------------------------------------------------------------+ - - --Wbitfield-constant-conversion ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit truncation from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to bit-field changes value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbitfield-enum-conversion --------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`bit-field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not wide enough to store all enumerators of` |nbsp| :placeholder:`B`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`signed bit-field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`needs an extra bit to represent the largest positive enumerators of` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`assigning value of signed enum type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to unsigned bit-field` |nbsp| :placeholder:`A`:diagtext:`; negative enumerators of enum` |nbsp| :placeholder:`B` |nbsp| :diagtext:`will be converted to positive values`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbitfield-width ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+ -|:warning:`warning:` |nbsp| :diagtext:`width of anonymous bit-field (`:placeholder:`A` |nbsp| :diagtext:`bits) exceeds width of its type; value will be truncated to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`bit`|+-------------+| -| || || -| |+-------------+| -| ||:diagtext:`s`|| -| |+-------------+| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+ -|:warning:`warning:` |nbsp| :diagtext:`width of bit-field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`(`:placeholder:`B` |nbsp| :diagtext:`bits) exceeds the width of its type; value will be truncated to` |nbsp| :placeholder:`C` |nbsp| :diagtext:`bit`|+-------------+| -| || || -| |+-------------+| -| ||:diagtext:`s`|| -| |+-------------+| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+ - - --Wbitwise-conditional-parentheses ---------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`operator '?:' has lower precedence than '`:placeholder:`A`:diagtext:`'; '`:placeholder:`A`:diagtext:`' will be evaluated first`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbitwise-op-parentheses ------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' within '`:placeholder:`B`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wblock-capture-autoreleasing ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`block captures an autoreleasing out-parameter, which may result in use-after-free bugs`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wbool-conversion ------------------ -This diagnostic is enabled by default. - -Also controls `-Wpointer-bool-conversion`_, `-Wundefined-bool-conversion`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialization of pointer of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to null from a constant boolean expression`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbool-conversions ------------------- -Synonym for `-Wbool-conversion`_. - - --Wbool-operation ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------+-------------------------------------------------+--------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`bitwise negation of a boolean expression`|+-----------------------------------------------+| |nbsp| :diagtext:`did you mean logical negation?`| -| ||:diagtext:`;` || | -| |+-----------------------------------------------+| | -| || |nbsp| :diagtext:`always evaluates to 'true';`|| | -| |+-----------------------------------------------+| | -+-------------------------------------------------------------------------------+-------------------------------------------------+--------------------------------------------------+ - - --Wbraced-scalar-init --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------+----------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`braces around` |nbsp| |+--------------------------+|:diagtext:`initializer`| -| ||:diagtext:`scalar` |nbsp| || | -| |+--------------------------+| | -| || || | -| |+--------------------------+| | -+------------------------------------------------------------+----------------------------+-----------------------+ - - --Wbridge-cast -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`bridges to` |nbsp| :placeholder:`B`:diagtext:`, not` |nbsp| :placeholder:`C`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot bridge to` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------+ - - --Wbuiltin-assume-aligned-alignment ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`requested alignment must be` |nbsp| :placeholder:`A` |nbsp| :diagtext:`bytes or smaller; maximum alignment assumed`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbuiltin-macro-redefined -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redefining builtin macro`| -+---------------------------------------------------------------+ - -+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`undefining builtin macro`| -+---------------------------------------------------------------+ - - --Wbuiltin-memcpy-chk-size -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will always overflow; destination buffer has size` |nbsp| :placeholder:`B`:diagtext:`, but size argument is` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wbuiltin-requires-header -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration of built-in function '`:placeholder:`B`:diagtext:`' requires inclusion of the header <`:placeholder:`A`:diagtext:`>`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++-compat ------------- -**Diagnostic text:** - -+---------------------------+---------------------------+--------------------+--------------------------------------------+---------------------------+--------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------+|+------------------+| |nbsp| :diagtext:`has size 0 in C,` |nbsp| |+-------------------------+| |nbsp| :diagtext:`in C++`| -| || |||:diagtext:`struct`|| ||:diagtext:`size 1` || | -| |+-------------------------+|+------------------+| |+-------------------------+| | -| ||:diagtext:`empty` |nbsp| |||:diagtext:`union` || ||:diagtext:`non-zero size`|| | -| |+-------------------------+|+------------------+| |+-------------------------+| | -+---------------------------+---------------------------+--------------------+--------------------------------------------+---------------------------+--------------------------+ - - --Wc++0x-compat --------------- -Synonym for `-Wc++11-compat`_. - - --Wc++0x-extensions ------------------- -Synonym for `-Wc++11-extensions`_. - - --Wc++0x-narrowing ------------------ -Synonym for `-Wc++11-narrowing`_. - - --Wc++11-compat --------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++11-compat-deprecated-writable-strings`_, `-Wc++11-compat-reserved-user-defined-literal`_, `-Wc++11-narrowing`_, `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_, `-Wc++98-c++11-compat`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`integer literal is too large to be represented in type 'long' and is subject to undefined behavior under C++98, interpreting as 'unsigned long'; this literal will` |nbsp| |+---------------------------------+| |nbsp| :diagtext:`in C++11 onwards`| -| ||:diagtext:`have type 'long long'`|| | -| |+---------------------------------+| | -| ||:diagtext:`be ill-formed` || | -| |+---------------------------------+| | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'auto' storage class specifier is redundant and incompatible with C++11`| -+--------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`identifier after literal will be treated as a user-defined literal suffix in C++11`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a keyword in C++11`| -+-------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of right-shift operator ('>>') in template argument will require parentheses in C++11`| -+--------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit instantiation cannot be 'inline'`| -+--------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit instantiation of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`must occur at global scope`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit instantiation of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not in a namespace enclosing` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit instantiation of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`must occur in namespace` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`integer literal is too large to be represented in type 'long', interpreting as 'unsigned long' per C++98; this literal will` |nbsp| |+---------------------------------+| |nbsp| :diagtext:`in C++11 onwards`| -| ||:diagtext:`have type 'long long'`|| | -| |+---------------------------------+| | -| ||:diagtext:`be ill-formed` || | -| |+---------------------------------+| | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+------------------------------------+ - - --Wc++11-compat-deprecated-writable-strings ------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conversion from string literal to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated`| -+---------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++11-compat-pedantic ------------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wc++11-compat`_, `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_. - - --Wc++11-compat-reserved-user-defined-literal --------------------------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`identifier after literal will be treated as a reserved user-defined literal suffix in C++11`| -+----------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++11-extensions ------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++11-extra-semi`_, `-Wc++11-inline-namespace`_, `-Wc++11-long-long`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`alias declarations are a C++11 extension`| -+-------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from array size expression of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| |+-----------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`is a C++11 extension`| -| ||:diagtext:`integral` || | -| |+-----------------------+| | -| ||:diagtext:`enumeration`|| | -| |+-----------------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'auto' type specifier is a C++11 extension`| -+---------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are a C++11 extension`| -+-----------------------------------------------------------------------------------------------------------+ - -+---------------------------+-----------------------+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------+| |nbsp| :diagtext:`function definitions are a C++11 extension`| -| ||:diagtext:`defaulted`|| | -| |+---------------------+| | -| ||:diagtext:`deleted` || | -| |+---------------------+| | -+---------------------------+-----------------------+--------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`befriending enumeration type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a C++11 extension`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`commas at the end of enumerator lists are a C++11 extension`| -+--------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit conversion functions are a C++11 extension`| -+------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extern templates are a C++11 extension`| -+-----------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`range-based for loop is a C++11 extension`| -+--------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`generalized initializer lists are a C++11 extension`| -+------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of enumeration in a nested name specifier is a C++11 extension`| -+---------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-class friend type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a C++11 extension`| -+----------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`in-class initialization of non-static data member is a C++11 extension`| -+-------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' keyword is a C++11 extension`| -+--------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reference qualifiers on functions are a C++11 extension`| -+----------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`rvalue references are a C++11 extension`| -+------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`scoped enumerations are a C++11 extension`| -+--------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static data member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in union is a C++11 extension`| -+----------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template argument referring to` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`with internal linkage is a C++11 extension`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`object` || | -| |+--------------------+| | -+--------------------------------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'template' keyword outside of a template`| -+-------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default template arguments for a function template are a C++11 extension`| -+---------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'typename' occurs outside of a template`| -+------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------+-----------------------+-------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unelaborated friend declaration is a C++11 extension; specify '`|+---------------------+|:diagtext:`' to befriend` |nbsp| :placeholder:`B`| -| ||:diagtext:`struct` || | -| |+---------------------+| | -| ||:diagtext:`interface`|| | -| |+---------------------+| | -| ||:diagtext:`union` || | -| |+---------------------+| | -| ||:diagtext:`class` || | -| |+---------------------+| | -| ||:diagtext:`enum` || | -| |+---------------------+| | -+------------------------------------------------------------------------------------------------------+-----------------------+-------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variadic templates are a C++11 extension`| -+-------------------------------------------------------------------------------+ - - --Wc++11-extra-semi ------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra ';' outside of a function is a C++11 extension`| -+-------------------------------------------------------------------------------------------+ - - --Wc++11-inline-namespace ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline namespaces are a C++11 feature`| -+----------------------------------------------------------------------------+ - - --Wc++11-long-long ------------------ -**Diagnostic text:** - -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'long long' is a C++11 extension`| -+-----------------------------------------------------------------------+ - - --Wc++11-narrowing ------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-----------------------+-----------------------------------------+--------+--------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| |+---------------------------------------+| |nbsp| |+------------------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`case value` || ||+--------------------------------------------------------------------------------------------------------------+ || -| |+---------------------------------------+| |||:diagtext:`cannot be narrowed from type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| || -| ||:diagtext:`enumerator value` || ||+--------------------------------------------------------------------------------------------------------------+ || -| |+---------------------------------------+| |+------------------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`non-type template argument` || ||+----------------------------------------------------------------------------------------------------------------------+|| -| |+---------------------------------------+| |||:diagtext:`evaluates to` |nbsp| :placeholder:`C`:diagtext:`, which cannot be narrowed to type` |nbsp| :placeholder:`D`||| -| ||:diagtext:`array size` || ||+----------------------------------------------------------------------------------------------------------------------+|| -| |+---------------------------------------+| |+------------------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`constexpr if condition` || | | -| |+---------------------------------------+| | | -| ||:diagtext:`explicit specifier argument`|| | | -| |+---------------------------------------+| | | -+-----------------------+-----------------------------------------+--------+--------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`constant expression evaluates to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`which cannot be narrowed to type` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot be narrowed to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`in initializer list`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`non-constant-expression cannot be narrowed from type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`in initializer list`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constant expression evaluates to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`which cannot be narrowed to type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`in C++11`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot be narrowed to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`in initializer list in C++11`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-constant-expression cannot be narrowed from type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`in initializer list in C++11`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++14-binary-literal ----------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`binary integer literals are a C++14 extension`| -+------------------------------------------------------------------------------------+ - - --Wc++14-compat --------------- -Controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_. - - --Wc++14-compat-pedantic ------------------------ -Controls `-Wc++14-compat`_, `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_. - - --Wc++14-extensions ------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++14-binary-literal`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of this statement in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++14 extension`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple return statements in constexpr function is a C++14 extension`| -+------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable declaration in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++14 extension`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ - -+-----------------------------------------------------------------------------+-------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type definition in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++14 extension`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------+-------------------------+----------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++14 extension`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'decltype(auto)' type specifier is a C++14 extension`| -+-------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialized lambda captures are a C++14 extension`| -+----------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable templates are a C++14 extension`| -+-------------------------------------------------------------------------------+ - - --Wc++17-compat --------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wc++17-compat-mangling`_, `-Wc++98-c++11-c++14-c++17-compat`_, `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_. - - --Wc++17-compat-mangling ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`mangled name of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will change in C++17 due to non-throwing exception specification in function signature`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++17-compat-pedantic ------------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wc++17-compat`_, `-Wc++98-c++11-c++14-c++17-compat-pedantic`_. - - --Wc++17-extensions ------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ standards before C++17 do not allow new expression for type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to use list-initialization`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr if is a C++17 extension`| -+------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'constexpr' on lambda expressions is a C++17 extension`| -+---------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++17 extension`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`decomposition declarations are a C++17 extension`| -+---------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack fold expression is a C++17 extension`| -+--------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'begin' and 'end' returning different types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is a C++17 extension`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are a C++17 feature`| -+----------------------------------------------------------------------------------------+ - -+----------------------------------------+--------------------+-------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+------------------+|:diagtext:`' initialization statements are a C++17 extension`| -| ||:diagtext:`if` || | -| |+------------------+| | -| ||:diagtext:`switch`|| | -| |+------------------+| | -+----------------------------------------+--------------------+-------------------------------------------------------------+ - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline variables are a C++17 extension`| -+-----------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is a C++17 extension`| -+---------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nested namespace definition is a C++17 extension; define each namespace separately`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------+---------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attributes on` |nbsp| |+-------------------------+| |nbsp| :diagtext:`declaration are a C++17 extension`| -| ||:diagtext:`a namespace` || | -| |+-------------------------+| | -| ||:diagtext:`an enumerator`|| | -| |+-------------------------+| | -+------------------------------------------------------------+---------------------------+-----------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`capture of '\*this' by copy is a C++17 extension`| -+---------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static\_assert with no message is a C++17 extension`| -+------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template template parameter using 'typename' is a C++17 extension`| -+--------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is a C++17 extension`| -+--------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack expansion of using declaration is a C++17 extension`| -+-----------------------------------------------------------------------------------------------+ - - --Wc++1y-extensions ------------------- -Synonym for `-Wc++14-extensions`_. - - --Wc++1z-compat --------------- -Synonym for `-Wc++17-compat`_. - - --Wc++1z-compat-mangling ------------------------ -Synonym for `-Wc++17-compat-mangling`_. - - --Wc++1z-extensions ------------------- -Synonym for `-Wc++17-extensions`_. - - --Wc++20-compat --------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`aggregate initialization of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with user-declared constructors is incompatible with C++20`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'consteval' specifier is incompatible with C++ standards before C++20`| -+------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'constinit' specifier is incompatible with C++ standards before C++20`| -+------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`this expression will be parsed as explicit(bool) in C++20`| -+------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'<=>' is a single token in C++20; add a space to avoid a change in behavior`| -+------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type of UTF-8 string literal will change from array of const char to array of const char8\_t in C++20`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a keyword in C++20`| -+-------------------------------------------------------------------------------------------+ - - --Wc++20-compat-pedantic ------------------------ -Synonym for `-Wc++20-compat`_. - - --Wc++20-designator ------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`designated initializers are a C++20 extension`| -+------------------------------------------------------------------------------------+ - - --Wc++20-extensions ------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++20-designator`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of function template name with no prior declaration in function call with explicit template arguments is a C++20 extension`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default member initializer for bit-field is a C++20 extension`| -+----------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of this statement in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++20 extension`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr constructor that does not initialize all members is a C++20 extension`| -+----------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+-------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function try block in constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++20 extension`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+------------------------------------------------------------------------------+-------------------------+----------------------------------------+ - -+------------------------------------------------------------------------------------+-------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`uninitialized variable in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++20 extension`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+------------------------------------------------------------------------------------+-------------------------+----------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr union constructor that does not initialize any member is a C++20 extension`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++20 extension`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------+--------------------------------------------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`decomposition declaration declared` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`is a C++20 extension`| -| ||+------------------------------------------+ || | -| |||:diagtext:`'`:placeholder:`B`:diagtext:`'`| || | -| ||+------------------------------------------+ || | -| |+------------------------------------------------------------+| | -| ||+----------------------------------------------------------+|| | -| |||:diagtext:`with '`:placeholder:`B`:diagtext:`' specifiers`||| | -| ||+----------------------------------------------------------+|| | -| |+------------------------------------------------------------+| | -+---------------------------------------------------------------------------------+--------------------------------------------------------------+----------------------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`defaulted comparison operators are a C++20 extension`| -+-------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit capture of 'this' with a capture default of '=' is a C++20 extension`| -+--------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit(bool) is a C++20 extension`| -+--------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`range-based for loop initialization statements are a C++20 extension`| -+-----------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialized lambda pack captures are a C++20 extension`| -+---------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline nested namespace definition is a C++20 extension`| -+----------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit template parameter list for lambdas is a C++20 extension`| -+--------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invoking a pointer to a 'const &' member function on an rvalue is a C++20 extension`| -+--------------------------------------------------------------------------------------------------------------------------+ - - --Wc++2a-compat --------------- -Synonym for `-Wc++20-compat`_. - - --Wc++2a-compat-pedantic ------------------------ -Synonym for `-Wc++20-compat-pedantic`_. - - --Wc++2a-extensions ------------------- -Synonym for `-Wc++20-extensions`_. - - --Wc++98-c++11-c++14-c++17-compat --------------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of function template name with no prior function template declaration in function call with explicit template arguments is incompatible with C++ standards before C++20`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default member initializer for bit-field is incompatible with C++ standards before C++20`| -+-------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of this statement in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++20`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr constructor that does not initialize all members is incompatible with C++ standards before C++20`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function try block in constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++20`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`uninitialized variable in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++20`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+------------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr union constructor that does not initialize any member is incompatible with C++ standards before C++20`| -+------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`virtual constexpr functions are incompatible with C++ standards before C++20`| -+-------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`decomposition declaration declared` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++20`| -| ||+------------------------------------------+ || | -| |||:diagtext:`'`:placeholder:`B`:diagtext:`'`| || | -| ||+------------------------------------------+ || | -| |+------------------------------------------------------------+| | -| ||+----------------------------------------------------------+|| | -| |||:diagtext:`with '`:placeholder:`B`:diagtext:`' specifiers`||| | -| ||+----------------------------------------------------------+|| | -| |+------------------------------------------------------------+| | -+---------------------------------------------------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`defaulted comparison operators are incompatible with C++ standards before C++20`| -+----------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------+--------------------------------------+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicitly defaulting this` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`with a type different from the implicit type is incompatible with C++ standards before C++20`| -| ||:diagtext:`default constructor` || | -| |+------------------------------------+| | -| ||:diagtext:`copy constructor` || | -| |+------------------------------------+| | -| ||:diagtext:`move constructor` || | -| |+------------------------------------+| | -| ||:diagtext:`copy assignment operator`|| | -| |+------------------------------------+| | -| ||:diagtext:`move assignment operator`|| | -| |+------------------------------------+| | -| ||:diagtext:`destructor` || | -| |+------------------------------------+| | -+-------------------------------------------------------------------------+--------------------------------------+----------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++20`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit(bool) is incompatible with C++ standards before C++20`| -+-----------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`range-based for loop initialization statements are incompatible with C++ standards before C++20`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialized lambda capture packs are incompatible with C++ standards before C++20`| -+------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline nested namespace definition is incompatible with C++ standards before C++20`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+----------------------------------+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------+| |nbsp| :diagtext:`of lambda is incompatible with C++ standards before C++20`| -| ||:diagtext:`default construction`|| | -| |+--------------------------------+| | -| ||:diagtext:`assignment` || | -| |+--------------------------------+| | -+---------------------------+----------------------------------+-----------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit template parameter list for lambdas is incompatible with C++ standards before C++20`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'<=>' operator is incompatible with C++ standards before C++20`| -+-----------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'char8\_t' type specifier is incompatible with C++ standards before C++20`| -+----------------------------------------------------------------------------------------------------------------+ - - --Wc++98-c++11-c++14-c++17-compat-pedantic ------------------------------------------ -Also controls `-Wc++98-c++11-c++14-c++17-compat`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`designated initializers are incompatible with C++ standards before C++20`| -+---------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invoking a pointer to a 'const &' member function on an rvalue is incompatible with C++ standards before C++20`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++98-c++11-c++14-compat --------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class template argument deduction is incompatible with C++ standards before C++17`|+---------------------------------------------------------------------------------+| -| || || -| |+---------------------------------------------------------------------------------+| -| ||+-------------------------------------------------------------------------------+|| -| |||:diagtext:`; for compatibility, use explicit type name` |nbsp| :placeholder:`B`||| -| ||+-------------------------------------------------------------------------------+|| -| |+---------------------------------------------------------------------------------+| -+------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr if is incompatible with C++ standards before C++17`| -+---------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr on lambda expressions is incompatible with C++ standards before C++17`| -+----------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`decomposition declarations are incompatible with C++ standards before C++17`| -+------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack fold expression is incompatible with C++ standards before C++17`| -+-----------------------------------------------------------------------------------------------------------+ - -+---------------------------+--------------------+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------+| |nbsp| :diagtext:`initialization statements are incompatible with C++ standards before C++17`| -| ||:diagtext:`if` || | -| |+------------------+| | -| ||:diagtext:`switch`|| | -| |+------------------+| | -+---------------------------+--------------------+----------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline variables are incompatible with C++ standards before C++17`| -+--------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nested namespace definition is incompatible with C++ standards before C++17`| -+------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`by value capture of '\*this' is incompatible with C++ standards before C++17`| -+-------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static\_assert with no message is incompatible with C++ standards before C++17`| -+---------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template parameters declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`are incompatible with C++ standards before C++17`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template template parameter using 'typename' is incompatible with C++ standards before C++17`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unicode literals are incompatible with C++ standards before C++17`| -+--------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is incompatible with C++ standards before C++17`| -+-----------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is incompatible with C++ standards before C++17`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack expansion using declaration is incompatible with C++ standards before C++17`| -+-----------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'begin' and 'end' returning different types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is incompatible with C++ standards before C++17`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++98-c++11-c++14-compat-pedantic ------------------------------------ -Also controls `-Wc++98-c++11-c++14-compat`_. - -**Diagnostic text:** - -+------------------------------------------------------------+---------------------------+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attributes on` |nbsp| |+-------------------------+| |nbsp| :diagtext:`declaration are incompatible with C++ standards before C++17`| -| ||:diagtext:`a namespace` || | -| |+-------------------------+| | -| ||:diagtext:`an enumerator`|| | -| |+-------------------------+| | -+------------------------------------------------------------+---------------------------+--------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are incompatible with C++ standards before C++17`| -+---------------------------------------------------------------------------------------------------------------------+ - - --Wc++98-c++11-compat --------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of this statement in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++14`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple return statements in constexpr function is incompatible with C++ standards before C++14`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr function with no return statements is incompatible with C++ standards before C++14`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable declaration in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++14`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type definition in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++14`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'decltype(auto)' type specifier is incompatible with C++ standards before C++14`| -+----------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`return type deduction is incompatible with C++ standards before C++14`| -+------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`digit separators are incompatible with C++ standards before C++14`| -+--------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`generic lambdas are incompatible with C++11`| -+----------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialized lambda captures are incompatible with C++ standards before C++14`| -+-------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable templates are incompatible with C++ standards before C++14`| -+----------------------------------------------------------------------------------------------------------+ - - --Wc++98-c++11-compat-binary-literal ------------------------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`binary integer literals are incompatible with C++ standards before C++14`| -+---------------------------------------------------------------------------------------------------------------+ - - --Wc++98-c++11-compat-pedantic ------------------------------ -Controls `-Wc++98-c++11-compat`_, `-Wc++98-c++11-compat-binary-literal`_. - - --Wc++98-compat --------------- -Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_, `-Wc++98-c++11-compat`_, `-Wc++98-compat-local-type-template-args`_, `-Wc++98-compat-unnamed-type-template-args`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`alias declarations are incompatible with C++98`| -+-------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'alignas' is incompatible with C++98`| -+---------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`alignof expressions are incompatible with C++98`| -+--------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C++11 attribute syntax is incompatible with C++98`| -+----------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'auto' type specifier is incompatible with C++98`| -+---------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'constexpr' specifier is incompatible with C++98`| -+---------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constructor call from initializer list is incompatible with C++98`| -+--------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'decltype' type specifier is incompatible with C++98`| -+-------------------------------------------------------------------------------------------+ - -+---------------------------+-----------------------+--------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------+| |nbsp| :diagtext:`function definitions are incompatible with C++98`| -| ||:diagtext:`defaulted`|| | -| |+---------------------+| | -| ||:diagtext:`deleted` || | -| |+---------------------+| | -+---------------------------+-----------------------+--------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`delegating constructors are incompatible with C++98`| -+------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`scalar initialized from empty initializer list is incompatible with C++98`| -+----------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializing` |nbsp| :placeholder:`A` |nbsp| :diagtext:`from an empty initializer list is incompatible with C++98`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are incompatible with C++98`| -+-----------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`befriending enumeration type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is incompatible with C++98`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration type in nested name specifier is incompatible with C++98`| -+-----------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit conversion functions are incompatible with C++98`| -+------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`range-based for loop is incompatible with C++98`| -+--------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`friend declaration naming a member of the declaring class is incompatible with C++98`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`generalized initializer lists are incompatible with C++98`| -+------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`jump from this goto statement to its label is incompatible with C++98`| -+------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`jump from this` |nbsp| |+--------------------+| |nbsp| :diagtext:`goto statement to one of its possible targets is incompatible with C++98`| -| ||:diagtext:`indirect`|| | -| |+--------------------+| | -| ||:diagtext:`asm` || | -| |+--------------------+| | -+-------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialization of initializer\_list object is incompatible with C++98`| -+------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline namespaces are incompatible with C++98`| -+------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`lambda expressions are incompatible with C++98`| -+-------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'<::' is treated as digraph '<:' (aka '\[') followed by ':' in C++98`| -+-----------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`literal operators are incompatible with C++98`| -+------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`universal character name referring to a control character is incompatible with C++98`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`specifying character '`:placeholder:`A`:diagtext:`' with a universal character name is incompatible with C++98`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`noexcept specifications are incompatible with C++98`| -+------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`noexcept expressions are incompatible with C++98`| -+---------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of non-static data member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in an unevaluated context is incompatible with C++98`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-class friend type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is incompatible with C++98`| -+----------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`in-class initialization of non-static data members is incompatible with C++98`| -+--------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+------------------------------+------------------------------------------------------------------------------------------------+--------------------------------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------------+| |nbsp| :diagtext:`member` |nbsp| :placeholder:`B` |nbsp| :diagtext:`with a non-trivial` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is incompatible with C++98`| -| ||:diagtext:`anonymous struct`|| ||:diagtext:`default constructor` || | -| |+----------------------------+| |+------------------------------------+| | -| ||:diagtext:`union` || ||:diagtext:`copy constructor` || | -| |+----------------------------+| |+------------------------------------+| | -| | | ||:diagtext:`move constructor` || | -| | | |+------------------------------------+| | -| | | ||:diagtext:`copy assignment operator`|| | -| | | |+------------------------------------+| | -| | | ||:diagtext:`move assignment operator`|| | -| | | |+------------------------------------+| | -| | | ||:diagtext:`destructor` || | -| | | |+------------------------------------+| | -+---------------------------+------------------------------+------------------------------------------------------------------------------------------------+--------------------------------------+----------------------------------------------+ - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'nullptr' is incompatible with C++98`| -+---------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' keyword is incompatible with C++98`| -+--------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing object of trivial but non-POD type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`through variadic` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++98`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`block` || | -| |+-----------------------+| | -| ||:diagtext:`method` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`raw string literals are incompatible with C++98`| -+--------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reference qualifiers on functions are incompatible with C++98`| -+----------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reference initialized from initializer list is incompatible with C++98`| -+-------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`rvalue references are incompatible with C++98`| -+------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`scoped enumerations are incompatible with C++98`| -+--------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`substitution failure due to access control is incompatible with C++98`| -+------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static\_assert declarations are incompatible with C++98`| -+----------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static data member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in union is incompatible with C++98`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`jump from switch statement to this case label is incompatible with C++98`| -+---------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redundant parentheses surrounding address non-type template argument are incompatible with C++98`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of null pointer as non-type template argument is incompatible with C++98`| -+-------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template argument referring to` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`with internal linkage is incompatible with C++98`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`object` || | -| |+--------------------+| | -+--------------------------------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of 'template' keyword outside of a template is incompatible with C++98`| -+-----------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default template arguments for a function template are incompatible with C++98`| -+---------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`trailing return types are incompatible with C++98`| -+----------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`consecutive right angle brackets are incompatible with C++98 (use '> >')`| -+---------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of 'typename' outside of a template is incompatible with C++98`| -+---------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+-----------------------+------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`befriending` |nbsp| :placeholder:`B` |nbsp| :diagtext:`without '`|+---------------------+|:diagtext:`' keyword is incompatible with C++98`| -| ||:diagtext:`struct` || | -| |+---------------------+| | -| ||:diagtext:`interface`|| | -| |+---------------------+| | -| ||:diagtext:`union` || | -| |+---------------------+| | -| ||:diagtext:`class` || | -| |+---------------------+| | -| ||:diagtext:`enum` || | -| |+---------------------+| | -+-------------------------------------------------------------------------------------------------------+-----------------------+------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using this character in an identifier is incompatible with C++98`| -+-------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unicode literals are incompatible with C++98`| -+-----------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' type specifier is incompatible with C++98`| -+---------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inheriting constructors are incompatible with C++98`| -+------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variadic templates are incompatible with C++98`| -+-------------------------------------------------------------------------------------+ - - --Wc++98-compat-bind-to-temporary-copy -------------------------------------- -**Diagnostic text:** - -+---------------------------+------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------------------------+ -|:warning:`warning:` |nbsp| |+----------------------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`when binding a reference to a temporary would` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`in C++98`| -| ||:diagtext:`copying variable` || ||:diagtext:`invoke an inaccessible constructor`|| | -| |+----------------------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`copying parameter` || ||:diagtext:`find no viable constructor` || | -| |+----------------------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`returning object` || ||:diagtext:`find ambiguous constructors` || | -| |+----------------------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`initializing statement expression result`|| ||:diagtext:`invoke a deleted constructor` || | -| |+----------------------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`throwing object` || | | | -| |+----------------------------------------------------+| | | | -| ||:diagtext:`copying member subobject` || | | | -| |+----------------------------------------------------+| | | | -| ||:diagtext:`copying array element` || | | | -| |+----------------------------------------------------+| | | | -| ||:diagtext:`allocating object` || | | | -| |+----------------------------------------------------+| | | | -| ||:diagtext:`copying temporary` || | | | -| |+----------------------------------------------------+| | | | -| ||:diagtext:`initializing base subobject` || | | | -| |+----------------------------------------------------+| | | | -| ||:diagtext:`initializing vector element` || | | | -| |+----------------------------------------------------+| | | | -| ||:diagtext:`capturing value` || | | | -| |+----------------------------------------------------+| | | | -+---------------------------+------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------------------------+ - - --Wc++98-compat-extra-semi -------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra ';' outside of a function is incompatible with C++98`| -+-------------------------------------------------------------------------------------------------+ - - --Wc++98-compat-local-type-template-args ---------------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`local type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`as template argument is incompatible with C++98`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wc++98-compat-pedantic ------------------------ -Also controls `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_, `-Wc++98-compat`_, `-Wc++98-compat-bind-to-temporary-copy`_, `-Wc++98-compat-extra-semi`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from array size expression of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| |+-----------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`is incompatible with C++98`| -| ||:diagtext:`integral` || | -| |+-----------------------+| | -| ||:diagtext:`enumeration`|| | -| |+-----------------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast between pointer-to-function and pointer-to-object is incompatible with C++98`| -+------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty macro arguments are incompatible with C++98`| -+----------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`commas at the end of enumerator lists are incompatible with C++98`| -+--------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extern templates are incompatible with C++98`| -+-----------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'long long' is incompatible with C++98`| -+-----------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C++98 requires newline at end of file`| -+----------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#line number greater than 32767 is incompatible with C++98`| -+-------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variadic macros are incompatible with C++98`| -+----------------------------------------------------------------------------------+ - - --Wc++98-compat-unnamed-type-template-args ------------------------------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unnamed type as template argument is incompatible with C++98`| -+---------------------------------------------------------------------------------------------------+ - - --Wc11-extensions ----------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`anonymous unions are a C11 extension`| -+---------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`anonymous structs are a C11 extension`| -+----------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a C11 extension`| -+----------------------------------------------------------------------------------------+ - - --Wc2x-extensions ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`omitting the parameter name in a function definition is a C2x extension`| -+--------------------------------------------------------------------------------------------------------------+ - - --Wc99-compat ------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------------------+| |nbsp| :diagtext:`is incompatible with C99`| -| ||:diagtext:`using this character in an identifier` || | -| |+------------------------------------------------------+| | -| ||:diagtext:`starting an identifier with this character`|| | -| |+------------------------------------------------------+| | -+---------------------------+--------------------------------------------------------+--------------------------------------------+ - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unicode literals are incompatible with C99`| -+---------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+----------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`integer literal is too large to be represented in type 'long', interpreting as 'unsigned long' per C89; this literal will` |nbsp| |+---------------------------------+| |nbsp| :diagtext:`in C99 onwards`| -| ||:diagtext:`have type 'long long'`|| | -| |+---------------------------------+| | -| ||:diagtext:`be ill-formed` || | -| |+---------------------------------+| | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+----------------------------------+ - - --Wc99-designator ----------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++20-designator`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`designated initializers are a C99 feature`| -+--------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array designators are a C99 extension`| -+----------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`mixture of designated and non-designated initializers in the same initializer list is a C99 extension`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nested designators are a C99 extension`| -+-----------------------------------------------------------------------------+ - - --Wc99-extensions ----------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc99-designator`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializer for aggregate is not a compile-time constant`| -+-----------------------------------------------------------------------------------------------+ - -+---------------------------+----------------------------------+------------------------------+-----------------------+----------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------+|:diagtext:`array size` |nbsp| |+---------------------+|:diagtext:`is a C99 feature`| -| ||:diagtext:`qualifier in` |nbsp| || || || | -| |+--------------------------------+| |+---------------------+| | -| ||:diagtext:`static` |nbsp| || || || | -| |+--------------------------------+| |+---------------------+| | -| || || ||:diagtext:`'\[\*\] '`|| | -| |+--------------------------------+| |+---------------------+| | -+---------------------------+----------------------------------+------------------------------+-----------------------+----------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`compound literals are a C99-specific feature`| -+-----------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a C99 extension`| -+----------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flexible array members are a C99 feature`| -+-------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable declaration in for loop is a C99-specific feature`| -+-------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C99 requires whitespace after the macro name`| -+---------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty macro arguments are a C99 feature`| -+------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`commas at the end of enumerator lists are a C99-specific feature`| -+-------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating constants are a C99 feature`| -+---------------------------------------------------------------------------------------+ - - --Wcall-to-pure-virtual-from-ctor-dtor -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`call to pure virtual member function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has undefined behavior; overrides of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in subclasses are not available in the` |nbsp| |+-----------------------+| |nbsp| :diagtext:`of` |nbsp| :placeholder:`C`| -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -| ||:diagtext:`destructor` || | -| |+-----------------------+| | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------+ - - --Wcast-align ------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`increases required alignment from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wcast-calling-convention -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast between incompatible calling conventions '`:placeholder:`A`:diagtext:`' and '`:placeholder:`B`:diagtext:`'; calls through this pointer may abort at runtime`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wcast-of-sel-type ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is deprecated; use sel\_getName instead`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wcast-qual ------------ -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`drops` |nbsp| |+-----------------------------------------+| -| ||:diagtext:`const and volatile qualifiers`|| -| |+-----------------------------------------+| -| ||:diagtext:`const qualifier` || -| |+-----------------------------------------+| -| ||:diagtext:`volatile qualifier` || -| |+-----------------------------------------+| -+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`must have all intermediate pointers const qualified to be safe`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wcast-qual-unrelated ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------+-----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ does not allow` |nbsp| |+---------------------------------+| |nbsp| :diagtext:`from` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to` |nbsp| :placeholder:`C` |nbsp| :diagtext:`because it casts away qualifiers, even though the source and destination types are unrelated`| -| ||:diagtext:`const\_cast` || | -| |+---------------------------------+| | -| ||:diagtext:`static\_cast` || | -| |+---------------------------------+| | -| ||:diagtext:`reinterpret\_cast` || | -| |+---------------------------------+| | -| ||:diagtext:`dynamic\_cast` || | -| |+---------------------------------+| | -| ||:diagtext:`C-style cast` || | -| |+---------------------------------+| | -| ||:diagtext:`functional-style cast`|| | -| |+---------------------------------+| | -+---------------------------------------------------------------------+-----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wchar-align ------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wchar-subscripts ------------------ -**Diagnostic text:** - -+------------------------------------------------------------+-------------------------+-------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array section` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is of type 'char'`| -| ||:diagtext:`lower bound`|| | -| |+-----------------------+| | -| ||:diagtext:`length` || | -| |+-----------------------+| | -+------------------------------------------------------------+-------------------------+-------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array subscript is of type 'char'`| -+------------------------------------------------------------------------+ - - --Wclang-cl-pch --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`support for '/Yc' with more than one source file not implemented yet; flag ignored`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`support for '/Yc' and '/Yu' with different filenames not implemented yet; flags ignored`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma hdrstop filename not supported, /Fp can be used to specify precompiled header filename`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`definition of macro` |nbsp| :placeholder:`A` |nbsp| :diagtext:`does not match definition in precompiled header`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wclass-varargs ---------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wnon-pod-varargs`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing object of class type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`through variadic` |nbsp| |+-----------------------+|+--------------------------------------------------------------------+| -| ||:diagtext:`function` ||| || -| |+-----------------------+|+--------------------------------------------------------------------+| -| ||:diagtext:`block` |||+------------------------------------------------------------------+|| -| |+-----------------------+|||:diagtext:`; did you mean to call '`:placeholder:`D`:diagtext:`'?`||| -| ||:diagtext:`method` |||+------------------------------------------------------------------+|| -| |+-----------------------+|+--------------------------------------------------------------------+| -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------+ - - --Wcmse-union-leak ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------+-------------------------------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing union across security boundary via` |nbsp| |+-----------------------------------------------+| |nbsp| :diagtext:`may leak information`| -| ||+---------------------------------------------+|| | -| |||:diagtext:`parameter` |nbsp| :placeholder:`B`||| | -| ||+---------------------------------------------+|| | -| |+-----------------------------------------------+| | -| ||:diagtext:`return value` || | -| |+-----------------------------------------------+| | -+-----------------------------------------------------------------------------------------+-------------------------------------------------+----------------------------------------+ - - --Wcomma -------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`possible misuse of comma operator here`| -+-----------------------------------------------------------------------------+ - - --Wcomment ---------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`escaped newline between \*/ characters at block comment end`| -+--------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`// comments are not allowed in this language`| -+-----------------------------------------------------------------------------------+ - -+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multi-line // comment`| -+------------------------------------------------------------+ - -+-----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'/\*' within block comment`| -+-----------------------------------------------------------------+ - - --Wcomments ----------- -Synonym for `-Wcomment`_. - - --Wcompare-distinct-pointer-types --------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of distinct pointer types`| -+---------------------------------------------------------------------------+ - - --Wcomplex-component-init ------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`complex initialization specifying real and imaginary components is an extension`| -+----------------------------------------------------------------------------------------------------------------------+ - - --Wconcepts-ts-compat --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 does not permit the 'bool' keyword after 'concept'`| -+---------------------------------------------------------------------------------------------------+ - - --Wconditional-type-mismatch ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pointer/integer type mismatch in conditional expression`| -+----------------------------------------------------------------------------------------------+ - - --Wconditional-uninitialized ---------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------+-------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may be uninitialized when` |nbsp| |+-----------------------------+| -| ||:diagtext:`used here` || -| |+-----------------------------+| -| ||:diagtext:`captured by block`|| -| |+-----------------------------+| -+----------------------------------------------------------------------------------------------------------------------------+-------------------------------+ - - --Wconfig-macros ---------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------+---------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`of configuration macro '`:placeholder:`B`:diagtext:`' has no effect on the import of '`:placeholder:`C`:diagtext:`'; pass '`|+------------------------------------------------+|:diagtext:`' on the command line to configure the module`| -| ||:diagtext:`definition`|| ||+----------------------------------------------+|| | -| |+----------------------+| |||:diagtext:`-D`:placeholder:`B`:diagtext:`=...`||| | -| ||:diagtext:`#undef` || ||+----------------------------------------------+|| | -| |+----------------------+| |+------------------------------------------------+| | -| | | ||+------------------------------+ || | -| | | |||:diagtext:`-U`:placeholder:`B`| || | -| | | ||+------------------------------+ || | -| | | |+------------------------------------------------+| | -+---------------------------+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------+---------------------------------------------------------+ - - --Wconstant-conversion ---------------------- -This diagnostic is enabled by default. - -Also controls `-Wbitfield-constant-conversion`_, `-Wobjc-bool-constant-conversion`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wconstant-evaluated --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will always evaluate to 'true' in a manifestly constant-evaluated expression`| -+--------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wconstant-logical-operand --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of logical '`:placeholder:`A`:diagtext:`' with constant operand`| -+----------------------------------------------------------------------------------------------------------+ - - --Wconstexpr-not-const ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wconsumed ----------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`consumed analysis attribute is attached to member of class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`which isn't marked as consumable`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`state of variable '`:placeholder:`A`:diagtext:`' must match at the entry and exit of loop`| -+--------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parameter '`:placeholder:`A`:diagtext:`' not in expected state when the function returns: expected '`:placeholder:`B`:diagtext:`', observed '`:placeholder:`C`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument not in expected state; expected '`:placeholder:`A`:diagtext:`', observed '`:placeholder:`B`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`return state set for an unconsumable type '`:placeholder:`A`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`return value not in expected state; expected '`:placeholder:`A`:diagtext:`', observed '`:placeholder:`B`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid invocation of method '`:placeholder:`A`:diagtext:`' on object '`:placeholder:`B`:diagtext:`' while it is in the '`:placeholder:`C`:diagtext:`' state`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid invocation of method '`:placeholder:`A`:diagtext:`' on a temporary object while it is in the '`:placeholder:`B`:diagtext:`' state`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wconversion ------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wbitfield-enum-conversion`_, `-Wbool-conversion`_, `-Wconstant-conversion`_, `-Wenum-conversion`_, `-Wfloat-conversion`_, `-Wimplicit-float-conversion`_, `-Wimplicit-int-conversion`_, `-Wint-conversion`_, `-Wliteral-conversion`_, `-Wnon-literal-null-conversion`_, `-Wnull-conversion`_, `-Wobjc-literal-conversion`_, `-Wshorten-64-to-32`_, `-Wsign-conversion`_, `-Wstring-conversion`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion discards imaginary component:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion turns vector to scalar:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing non-generic address space pointer to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may cause dynamic conversion affecting performance`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template argument with value '`:placeholder:`A`:diagtext:`' converted to '`:placeholder:`B`:diagtext:`' for unsigned template parameter of type` |nbsp| :placeholder:`C`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template argument value '`:placeholder:`A`:diagtext:`' truncated to '`:placeholder:`B`:diagtext:`' for template parameter of type` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wconversion-null ------------------ -Synonym for `-Wnull-conversion`_. - - --Wcoroutine ------------ -Synonym for `-Wcoroutine-missing-unhandled-exception`_. - - --Wcoroutine-missing-unhandled-exception ---------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is required to declare the member 'unhandled\_exception()' when exceptions are enabled`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wcovered-switch-default ------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default label in switch which covers all enumeration values`| -+--------------------------------------------------------------------------------------------------+ - - --Wcpp ------ -Synonym for `-W#warnings`_. - - --Wcstring-format-directive --------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using` |nbsp| :placeholder:`A` |nbsp| :diagtext:`directive in` |nbsp| |+--------------------+| |nbsp| :diagtext:`which is being passed as a formatting argument to the formatting` |nbsp| |+----------------------+| -| ||:diagtext:`NSString`|| ||:diagtext:`method` || -| |+--------------------+| |+----------------------+| -| ||:diagtext:`CFString`|| ||:diagtext:`CFfunction`|| -| |+--------------------+| |+----------------------+| -+------------------------------------------------------------------------------------------------------------+----------------------+--------------------------------------------------------------------------------------------+------------------------+ - - --Wctad-maybe-unsupported ------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may not intend to support class template argument deduction`| -+--------------------------------------------------------------------------------------------------------------------------+ - - --Wctor-dtor-privacy -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wctu ------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`imported AST from '`:placeholder:`A`:diagtext:`' had been generated for a different target, current:` |nbsp| :placeholder:`B`:diagtext:`, imported:` |nbsp| :placeholder:`C`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wcuda-compat -------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute parameter` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is negative and will be ignored`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nvcc does not allow '\_\_`:placeholder:`A`:diagtext:`\_\_' to appear after '()' in lambdas`| -+---------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignored 'inline' attribute on kernel function` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`kernel function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a member function; this may not be accepted by nvcc`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument to '#pragma unroll' should not be in parentheses in CUDA C/C++`| -+--------------------------------------------------------------------------------------------------------------+ - - --Wcustom-atomic-properties --------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+--------------------+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`atomic by default property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has a user defined` |nbsp| |+------------------+| |nbsp| :diagtext:`(property should be marked 'atomic' if this is intended)`| -| ||:diagtext:`getter`|| | -| |+------------------+| | -| ||:diagtext:`setter`|| | -| |+------------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------+--------------------+----------------------------------------------------------------------------+ - - --Wdangling ----------- -This diagnostic is enabled by default. - -Also controls `-Wdangling-field`_, `-Wdangling-gsl`_, `-Wdangling-initializer-list`_, `-Wreturn-stack-address`_. - -**Diagnostic text:** - -+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+----------------------------+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| |nbsp| |+--------------------------+|:diagtext:`will be destroyed at the end of the full-expression`| -| ||+-----------------------------+---------------------------------------------------------+--------+------------------------------------------------------------------------+|| ||+------------------------+|| | -| |||:diagtext:`temporary` |nbsp| |+-------------------------------------------------------+| |nbsp| |+----------------------------------------------------------------------+||| |||:placeholder:`D` |nbsp| ||| | -| ||| ||:diagtext:`whose address is used as value of` || ||+-------------------------------+------------------------------------+|||| ||+------------------------+|| | -| ||| |+-------------------------------------------------------+| |||+-----------------------------+|:diagtext:`member of local variable`||||| |+--------------------------+| | -| ||| ||+--------------------------------+--------------------+|| |||| || ||||| || || | -| ||| |||+------------------------------+|:diagtext:`bound to`||| |||+-----------------------------+| ||||| |+--------------------------+| | -| ||| |||| || ||| ||||:diagtext:`reference` |nbsp| || ||||| | | | -| ||| |||+------------------------------+| ||| |||+-----------------------------+| ||||| | | | -| ||| ||||:diagtext:`implicitly` |nbsp| || ||| ||+-------------------------------+------------------------------------+|||| | | | -| ||| |||+------------------------------+| ||| |+----------------------------------------------------------------------+||| | | | -| ||| ||+--------------------------------+--------------------+|| ||+-------------------------+-----------------------+ |||| | | | -| ||| |+-------------------------------------------------------+| |||:diagtext:`local` |nbsp| |+---------------------+| |||| | | | -| ||| | | ||| ||:diagtext:`variable` || |||| | | | -| ||| | | ||| |+---------------------+| |||| | | | -| ||| | | ||| ||:diagtext:`reference`|| |||| | | | -| ||| | | ||| |+---------------------+| |||| | | | -| ||| | | ||+-------------------------+-----------------------+ |||| | | | -| ||| | | |+----------------------------------------------------------------------+||| | | | -| ||+-----------------------------+---------------------------------------------------------+--------+------------------------------------------------------------------------+|| | | | -| |+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| | | | -| ||+---------------------------------+----------------------------------------------------------+ || | | | -| |||:diagtext:`array backing` |nbsp| |+--------------------------------------------------------+| || | | | -| ||| ||:diagtext:`initializer list subobject of local variable`|| || | | | -| ||| |+--------------------------------------------------------+| || | | | -| ||| ||:diagtext:`local initializer list` || || | | | -| ||| |+--------------------------------------------------------+| || | | | -| ||+---------------------------------+----------------------------------------------------------+ || | | | -| |+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| | | | -+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+----------------------------+---------------------------------------------------------------+ - -+---------------------------------------------------------------------------+-----------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`sorry, lifetime extension of` |nbsp| |+---------------------------------------------+| |nbsp| :diagtext:`created by aggregate initialization using default member initializer is not supported; lifetime of` |nbsp| |+-------------------------+| |nbsp| :diagtext:`will end at the end of the full-expression`| -| ||:diagtext:`temporary` || ||:diagtext:`temporary` || | -| |+---------------------------------------------+| |+-------------------------+| | -| ||:diagtext:`backing array of initializer list`|| ||:diagtext:`backing array`|| | -| |+---------------------------------------------+| |+-------------------------+| | -+---------------------------------------------------------------------------+-----------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+ - - --Wdangling-else ---------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`add explicit braces to avoid dangling else`| -+---------------------------------------------------------------------------------+ - - --Wdangling-field ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`binding reference member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to stack allocated` |nbsp| |+---------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`variable` || | -| |+---------------------+| | -| ||:diagtext:`parameter`|| | -| |+---------------------+| | -+-------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ - -+---------------------------+--------------------------------------------------------+--------+----------------------------------+--------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------------------+| |nbsp| |+--------------------------------+|:diagtext:`member` |nbsp| :placeholder:`A` |nbsp| |+--------------------+| |nbsp| :diagtext:`a temporary object whose lifetime is shorter than the lifetime of the constructed object`| -| ||:diagtext:`reference` || || || ||:diagtext:`binds to`|| | -| |+------------------------------------------------------+| |+--------------------------------+| |+--------------------+| | -| ||:diagtext:`backing array for 'std::initializer\_list'`|| ||:diagtext:`subobject of` |nbsp| || ||:diagtext:`is` || | -| |+------------------------------------------------------+| |+--------------------------------+| |+--------------------+| | -+---------------------------+--------------------------------------------------------+--------+----------------------------------+--------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializing pointer member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with the stack address of` |nbsp| |+---------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`variable` || | -| |+---------------------+| | -| ||:diagtext:`parameter`|| | -| |+---------------------+| | -+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`temporary bound to reference member of allocated object will be destroyed at the end of the full-expression`| -+--------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdangling-gsl --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`object backing the pointer will be destroyed at the end of the full-expression`| -+---------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializing pointer member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to point to a temporary object whose lifetime is shorter than the lifetime of the constructed object`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdangling-initializer-list ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array backing` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`will be destroyed at the end of the full-expression`| -| ||:diagtext:`initializer list subobject of the allocated object`|| | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`the allocated initializer list` || | -| |+--------------------------------------------------------------+| | -+------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------------------+ - - --Wdarwin-sdk-settings ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`SDK settings were ignored as 'SDKSettings.json' could not be parsed`| -+----------------------------------------------------------------------------------------------------------+ - - --Wdate-time ------------ -**Diagnostic text:** - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expansion of date or time macro is not reproducible`| -+------------------------------------------------------------------------------------------+ - - --Wdealloc-in-category ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`-dealloc is being overridden in a category`| -+---------------------------------------------------------------------------------+ - - --Wdebug-compression-unavailable -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cannot compress debug sections (zlib not installed)`| -+------------------------------------------------------------------------------------------+ - - --Wdeclaration-after-statement ------------------------------ -**Diagnostic text:** - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C90 forbids mixing declarations and code`| -+-----------------------------------------------------------------------------------+ - - --Wdefaulted-function-deleted ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------+------------------------+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicitly defaulted` |nbsp| |+----------------------+| |nbsp| :diagtext:`comparison operator` |nbsp| :diagtext:`is implicitly deleted`| -| ||:diagtext:`` || | -| |+----------------------+| | -| ||:diagtext:`equality` || | -| |+----------------------+| | -| ||:diagtext:`three-way` || | -| |+----------------------+| | -| ||:diagtext:`equality` || | -| |+----------------------+| | -| ||:diagtext:`relational`|| | -| |+----------------------+| | -+-------------------------------------------------------------------+------------------------+--------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------+--------------------------------------+-----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicitly defaulted` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is implicitly deleted`| -| ||:diagtext:`default constructor` || | -| |+------------------------------------+| | -| ||:diagtext:`copy constructor` || | -| |+------------------------------------+| | -| ||:diagtext:`move constructor` || | -| |+------------------------------------+| | -| ||:diagtext:`copy assignment operator`|| | -| |+------------------------------------+| | -| ||:diagtext:`move assignment operator`|| | -| |+------------------------------------+| | -| ||:diagtext:`destructor` || | -| |+------------------------------------+| | -+-------------------------------------------------------------------+--------------------------------------+-----------------------------------------+ - - --Wdelegating-ctor-cycles ------------------------- -This diagnostic is an error by default, but the flag ``-Wno-delegating-ctor-cycles`` can be used to disable the error. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`constructor for` |nbsp| :placeholder:`A` |nbsp| :diagtext:`creates a delegation cycle`| -+------------------------------------------------------------------------------------------------------------------------+ - - --Wdelete-abstract-non-virtual-dtor ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`called on` |nbsp| :placeholder:`B` |nbsp| :diagtext:`that is abstract but has non-virtual destructor`| -| ||:diagtext:`delete` || | -| |+----------------------+| | -| ||:diagtext:`destructor`|| | -| |+----------------------+| | -+---------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------+ - - --Wdelete-incomplete -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cannot delete expression with pointer-to-'void' type` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`deleting pointer to incomplete type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may cause undefined behavior`| -+--------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdelete-non-abstract-non-virtual-dtor --------------------------------------- -**Diagnostic text:** - -+---------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`called on non-final` |nbsp| :placeholder:`B` |nbsp| :diagtext:`that has virtual functions but non-virtual destructor`| -| ||:diagtext:`delete` || | -| |+----------------------+| | -| ||:diagtext:`destructor`|| | -| |+----------------------+| | -+---------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdelete-non-virtual-dtor -------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wdelete-abstract-non-virtual-dtor`_, `-Wdelete-non-abstract-non-virtual-dtor`_. - - --Wdeprecated ------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wdeprecated-anon-enum-enum-conversion`_, `-Wdeprecated-array-compare`_, `-Wdeprecated-attributes`_, `-Wdeprecated-comma-subscript`_, `-Wdeprecated-copy`_, `-Wdeprecated-copy-dtor`_, `-Wdeprecated-declarations`_, `-Wdeprecated-dynamic-exception-spec`_, `-Wdeprecated-enum-compare`_, `-Wdeprecated-enum-compare-conditional`_, `-Wdeprecated-enum-enum-conversion`_, `-Wdeprecated-enum-float-conversion`_, `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_, `-Wdeprecated-this-capture`_, `-Wdeprecated-volatile`_, `-Wdeprecated-writable-strings`_. - -**Diagnostic text:** - -+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`-O4 is equivalent to -O3`| -+---------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`access declarations are deprecated; use using declarations instead`| -+---------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`out-of-line definition of constexpr static data member is redundant in C++17 and is deprecated`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument '`:placeholder:`A`:diagtext:`' is deprecated, use '`:placeholder:`B`:diagtext:`' instead`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`treating '`:placeholder:`A`:diagtext:`' input as '`:placeholder:`B`:diagtext:`' when in C++ mode, this behavior is deprecated`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`-fconcepts-ts is deprecated - use '-std=c++20' for Concepts support`| -+----------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`OpenCL version` |nbsp| :placeholder:`A` |nbsp| :diagtext:`does not support the option '`:placeholder:`B`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Use of 'long' with '\_\_vector' is deprecated`| -+------------------------------------------------------------------------------------+ - - --Wdeprecated-anon-enum-enum-conversion --------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types` |nbsp| :diagtext:`is deprecated`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ - - --Wdeprecated-array-compare --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison between two arrays is deprecated; to compare array addresses, use unary '+' to decay operands to pointers`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-attributes ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`specifying vector types with the 'mode' attribute is deprecated; use the 'vector\_size' attribute instead`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-comma-subscript ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`top-level comma expression in array subscript is deprecated`| -+--------------------------------------------------------------------------------------------------+ - - --Wdeprecated-copy ------------------ -**Diagnostic text:** - -+--------------------------------------------------------------------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------+---------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`definition of implicit copy` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`for` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated because it has a user-declared copy` |nbsp| |+-------------------------------+| -| ||:diagtext:`constructor` || ||:diagtext:`assignment operator`|| -| |+-------------------------------+| |+-------------------------------+| -| ||:diagtext:`assignment operator`|| ||:diagtext:`constructor` || -| |+-------------------------------+| |+-------------------------------+| -+--------------------------------------------------------------------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------+---------------------------------+ - - --Wdeprecated-copy-dtor ----------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------+---------------------------------+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`definition of implicit copy` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`for` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated because it has a user-declared destructor`| -| ||:diagtext:`constructor` || | -| |+-------------------------------+| | -| ||:diagtext:`assignment operator`|| | -| |+-------------------------------+| | -+--------------------------------------------------------------------------+---------------------------------+--------------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-declarations -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`specifying 'uuid' as an ATL attribute is deprecated; use \_\_declspec instead`| -+--------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of C-style parameters in Objective-C method declarations is deprecated`| -+-----------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated`| -+----------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may be deprecated because the receiver type is unknown`| -+---------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated:` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property access is using` |nbsp| :placeholder:`A` |nbsp| :diagtext:`method which is deprecated`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-dynamic-exception-spec ------------------------------------ -**Diagnostic text:** - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dynamic exception specifications are deprecated`| -+--------------------------------------------------------------------------------------+ - - --Wdeprecated-enum-compare -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types` |nbsp| :diagtext:`is deprecated`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ - - --Wdeprecated-enum-compare-conditional -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types` |nbsp| :diagtext:`is deprecated`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ - - --Wdeprecated-enum-enum-conversion ---------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types` |nbsp| :diagtext:`is deprecated`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+--------------------------------------------------------------------------------+ - - --Wdeprecated-enum-float-conversion ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+--------+----------------------------+--------------------------------------------------------+------------------+--------+----------------------------+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| |+--------------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| |+--------------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`D` |nbsp| :diagtext:`is deprecated`| -| ||:diagtext:`arithmetic between` || ||:diagtext:`floating-point`|| ||:diagtext:`with`|| ||:diagtext:`enumeration` || | -| |+------------------------------------------+| |+--------------------------+| |+----------------+| |+--------------------------+| | -| ||:diagtext:`bitwise operation between` || ||:diagtext:`enumeration` || ||:diagtext:`from`|| ||:diagtext:`floating-point`|| | -| |+------------------------------------------+| |+--------------------------+| |+----------------+| |+--------------------------+| | -| ||:diagtext:`comparison of` || | | ||:diagtext:`and` || | | | -| |+------------------------------------------+| | | |+----------------+| | | | -| ||:diagtext:`conditional expression between`|| | | | | | | | -| |+------------------------------------------+| | | | | | | | -| ||:diagtext:`compound assignment of` || | | | | | | | -| |+------------------------------------------+| | | | | | | | -+---------------------------+--------------------------------------------+--------+----------------------------+--------------------------------------------------------+------------------+--------+----------------------------+---------------------------------------------------------------------------------+ - - --Wdeprecated-implementations ----------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------+----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implementing deprecated` |nbsp| |+--------------------+| -| ||:diagtext:`method` || -| |+--------------------+| -| ||:diagtext:`class` || -| |+--------------------+| -| ||:diagtext:`category`|| -| |+--------------------+| -+----------------------------------------------------------------------+----------------------+ - -+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implementing unavailable method`| -+----------------------------------------------------------------------+ - - --Wdeprecated-increment-bool ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incrementing expression of type bool is deprecated and incompatible with C++17`| -+---------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-objc-isa-usage ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`assignment to Objective-C's isa is deprecated in favor of object\_setClass()`| -+-------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`direct access to Objective-C's isa is deprecated in favor of object\_getClass()`| -+----------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-objc-pointer-introspection ---------------------------------------- -This diagnostic is enabled by default. - -Also controls `-Wdeprecated-objc-pointer-introspection-performSelector`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`bitmasking for introspection of Objective-C object pointers is strongly discouraged`| -+--------------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-objc-pointer-introspection-performSelector -------------------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`bitmasking for introspection of Objective-C object pointers is strongly discouraged`| -+--------------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-register ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'register' storage class specifier is deprecated and incompatible with C++17`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-this-capture -------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit capture of 'this' with a capture default of '=' is deprecated`| -+-------------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-volatile ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`compound assignment to object of volatile-qualified type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+-----------------------+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------+| |nbsp| :diagtext:`of object of volatile-qualified type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is deprecated`| -| ||:diagtext:`decrement`|| | -| |+---------------------+| | -| ||:diagtext:`increment`|| | -| |+---------------------+| | -+---------------------------+-----------------------+-----------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of result of assignment to object of volatile-qualified type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`volatile-qualified parameter type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated`| -+---------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`volatile-qualified return type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is deprecated`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`volatile qualifier in structured binding declaration is deprecated`| -+---------------------------------------------------------------------------------------------------------+ - - --Wdeprecated-writable-strings ------------------------------ -Synonym for `-Wc++11-compat-deprecated-writable-strings`_. - - --Wdirect-ivar-access --------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instance variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is being directly accessed`| -+------------------------------------------------------------------------------------------------------------------------------+ - - --Wdisabled-macro-expansion --------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`disabled expansion of recursive macro`| -+----------------------------------------------------------------------------+ - - --Wdisabled-optimization ------------------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wdiscard-qual --------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wdistributed-object-modifiers ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting distributed object modifiers on parameter type in implementation of` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting distributed object modifiers on return type in implementation of` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdiv-by-zero -------------- -Synonym for `-Wdivision-by-zero`_. - - --Wdivision-by-zero ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+-----------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------+| |nbsp| :diagtext:`by zero is undefined`| -| ||:diagtext:`remainder`|| | -| |+---------------------+| | -| ||:diagtext:`division` || | -| |+---------------------+| | -+---------------------------+-----------------------+----------------------------------------+ - - --Wdll-attribute-on-redeclaration --------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redeclaration of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`should not add` |nbsp| :placeholder:`B` |nbsp| :diagtext:`attribute`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdllexport-explicit-instantiation-decl ---------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit instantiation declaration should not be 'dllexport'`| -+---------------------------------------------------------------------------------------------------+ - - --Wdllimport-static-field-def ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`definition of dllimport static field`| -+---------------------------------------------------------------------------+ - - --Wdocumentation ---------------- -Also controls `-Wdocumentation-deprecated-sync`_, `-Wdocumentation-html`_. - -**Diagnostic text:** - -+----------------------------------------+----------------+-----------------------+------------------------------------------------------------------------+-----------------------+-------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|+---------------------+|:diagtext:`' command should not be used in a comment attached to a non-`|+---------------------+| |nbsp| :diagtext:`declaration`| -| ||:diagtext:`\\`|||:diagtext:`class` || ||:diagtext:`class` || | -| |+--------------+|+---------------------+| |+---------------------+| | -| ||:diagtext:`@` |||:diagtext:`interface`|| ||:diagtext:`interface`|| | -| |+--------------+|+---------------------+| |+---------------------+| | -| | ||:diagtext:`protocol` || ||:diagtext:`protocol` || | -| | |+---------------------+| |+---------------------+| | -| | ||:diagtext:`struct` || ||:diagtext:`struct` || | -| | |+---------------------+| |+---------------------+| | -| | ||:diagtext:`union` || ||:diagtext:`union` || | -| | |+---------------------+| |+---------------------+| | -+----------------------------------------+----------------+-----------------------+------------------------------------------------------------------------+-----------------------+-------------------------------+ - -+-----------------------------------------------------------+----------------+-----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicated command '`|+--------------+|:placeholder:`B`:diagtext:`'`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+-----------------------------------------------------------+----------------+-----------------------------+ - -+------------------------------------------------------------------+----------------+-------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty paragraph passed to '`|+--------------+|:placeholder:`B`:diagtext:`' command`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+------------------------------------------------------------------+----------------+-------------------------------------+ - -+----------------------------------------+----------------+--------------------------+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|+------------------------+|:diagtext:`' command should not be used in a comment attached to a non-container declaration`| -| ||:diagtext:`\\`|||:diagtext:`classdesign` || | -| |+--------------+|+------------------------+| | -| ||:diagtext:`@` |||:diagtext:`coclass` || | -| |+--------------+|+------------------------+| | -| | ||:diagtext:`dependency` || | -| | |+------------------------+| | -| | ||:diagtext:`helper` || | -| | |+------------------------+| | -| | ||:diagtext:`helperclass` || | -| | |+------------------------+| | -| | ||:diagtext:`helps` || | -| | |+------------------------+| | -| | ||:diagtext:`instancesize`|| | -| | |+------------------------+| | -| | ||:diagtext:`ownership` || | -| | |+------------------------+| | -| | ||:diagtext:`performance` || | -| | |+------------------------+| | -| | ||:diagtext:`security` || | -| | |+------------------------+| | -| | ||:diagtext:`superclass` || | -| | |+------------------------+| | -+----------------------------------------+----------------+--------------------------+---------------------------------------------------------------------------------------------+ - -+----------------------------------------+----------------+---------------------------+---------------------------------------------------------------------+-----------------------------------+-------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|+-------------------------+|:diagtext:`' command should be used in a comment attached to` |nbsp| |+---------------------------------+| |nbsp| :diagtext:`declaration`| -| ||:diagtext:`\\`|||:diagtext:`function` || ||:diagtext:`a function` || | -| |+--------------+|+-------------------------+| |+---------------------------------+| | -| ||:diagtext:`@` |||:diagtext:`functiongroup`|| ||:diagtext:`a function` || | -| |+--------------+|+-------------------------+| |+---------------------------------+| | -| | ||:diagtext:`method` || ||:diagtext:`an Objective-C method`|| | -| | |+-------------------------+| |+---------------------------------+| | -| | ||:diagtext:`methodgroup` || ||:diagtext:`an Objective-C method`|| | -| | |+-------------------------+| |+---------------------------------+| | -| | ||:diagtext:`callback` || ||:diagtext:`a pointer to function`|| | -| | |+-------------------------+| |+---------------------------------+| | -+----------------------------------------+----------------+---------------------------+---------------------------------------------------------------------+-----------------------------------+-------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`HTML start tag prematurely ended, expected attribute name or '>'`| -+-------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected quoted string after equals sign`| -+-------------------------------------------------------------------------------+ - -+----------------------------------------+----------------+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|:placeholder:`B`:diagtext:`' command does not have a valid word argument`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+----------------------------------------+----------------+-------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parameter '`:placeholder:`A`:diagtext:`' is already documented`| -+-----------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unrecognized parameter passing direction, valid directions are '\[in\]', '\[out\]' and '\[in,out\]'`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------+----------------+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|:diagtext:`param' command used in a comment that is not attached to a function declaration`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+----------------------------------------+----------------+-------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parameter '`:placeholder:`A`:diagtext:`' not found in the function declaration`| -+---------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------+----------------+-------------------------------------------------------------------------------------+-------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|:placeholder:`B`:diagtext:`' command used in a comment that is attached to a` |nbsp| |+-----------------------------------+| -| ||:diagtext:`\\`|| ||:diagtext:`function returning void`|| -| |+--------------+| |+-----------------------------------+| -| ||:diagtext:`@` || ||:diagtext:`constructor` || -| |+--------------+| |+-----------------------------------+| -| | | ||:diagtext:`destructor` || -| | | |+-----------------------------------+| -| | | ||:diagtext:`method returning void` || -| | | |+-----------------------------------+| -+----------------------------------------+----------------+-------------------------------------------------------------------------------------+-------------------------------------+ - -+----------------------------------------+----------------+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|:placeholder:`B`:diagtext:`' command used in a comment that is not attached to a function or method declaration`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+----------------------------------------+----------------+----------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template parameter '`:placeholder:`A`:diagtext:`' is already documented`| -+--------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------+----------------+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|:diagtext:`tparam' command used in a comment that is not attached to a template declaration`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+----------------------------------------+----------------+--------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template parameter '`:placeholder:`A`:diagtext:`' not found in the template declaration`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`not a Doxygen trailing comment`| -+---------------------------------------------------------------------+ - -+----------------------------------------+----------------+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+--------------+|:placeholder:`B`:diagtext:`' command does not terminate a verbatim text block`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+----------------------------------------+----------------+------------------------------------------------------------------------------+ - - --Wdocumentation-deprecated-sync -------------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------+----------------+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration is marked with '`|+--------------+|:diagtext:`deprecated' command but does not have a deprecation attribute`| -| ||:diagtext:`\\`|| | -| |+--------------+| | -| ||:diagtext:`@` || | -| |+--------------+| | -+-------------------------------------------------------------------+----------------+-------------------------------------------------------------------------+ - - --Wdocumentation-html --------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`HTML end tag '`:placeholder:`A`:diagtext:`' is forbidden`| -+-----------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`HTML end tag does not match any start tag`| -+--------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`HTML tag '`:placeholder:`A`:diagtext:`' requires an end tag`| -+--------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`HTML start tag '`:placeholder:`A`:diagtext:`' closed by '`:placeholder:`B`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wdocumentation-pedantic ------------------------- -Also controls `-Wdocumentation-unknown-command`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`whitespace is not allowed in parameter passing direction`| -+-----------------------------------------------------------------------------------------------+ - - --Wdocumentation-unknown-command -------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown command tag name '`:placeholder:`A`:diagtext:`'; did you mean '`:placeholder:`B`:diagtext:`'?`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown command tag name`| -+---------------------------------------------------------------+ - - --Wdollar-in-identifier-extension --------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'$' in identifier`| -+--------------------------------------------------------+ - - --Wdouble-promotion ------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion increases floating-point precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdtor-name ------------ -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ considers this destructor name lookup to be ambiguous`| -+----------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`qualified destructor name only found in lexical scope; omit the qualifier to find this type name by unqualified lookup`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wdtor-typedef --------------- -This diagnostic is an error by default, but the flag ``-Wno-dtor-typedef`` can be used to disable the error. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------+------------------------+-------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`destructor cannot be declared using a` |nbsp| |+----------------------+| |nbsp| :placeholder:`A` |nbsp| :diagtext:`of the class name`| -| ||:diagtext:`typedef` || | -| |+----------------------+| | -| ||:diagtext:`type alias`|| | -| |+----------------------+| | -+--------------------------------------------------------------------------------+------------------------+-------------------------------------------------------------+ - - --Wduplicate-decl-specifier --------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate '`:placeholder:`A`:diagtext:`' declaration specifier`| -+-----------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate '`:placeholder:`A`:diagtext:`' declaration specifier`| -+-----------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple identical address spaces specified for type`| -+-------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate '`:placeholder:`A`:diagtext:`' declaration specifier`| -+-----------------------------------------------------------------------------------------------------+ - - --Wduplicate-enum ----------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`element` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has been implicitly assigned` |nbsp| :placeholder:`B` |nbsp| :diagtext:`which another element has been assigned`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wduplicate-method-arg ----------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redeclaration of method parameter` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------------------------+ - - --Wduplicate-method-match ------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple declarations of method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`found and ignored`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - - --Wduplicate-protocol --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate protocol definition of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is ignored`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wdynamic-class-memaccess -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+-------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------+---------------------------------------------------------------------------------------------+-------------------------+ -|:warning:`warning:` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`this` |nbsp| :placeholder:`B` |nbsp| :diagtext:`call is a pointer to` |nbsp| |+--------------------------------------+|:diagtext:`dynamic class` |nbsp| :placeholder:`D`:diagtext:`; vtable pointer will be` |nbsp| |+-----------------------+| -| ||:diagtext:`destination for` || || || ||:diagtext:`overwritten`|| -| |+-----------------------------+| |+--------------------------------------+| |+-----------------------+| -| ||:diagtext:`source of` || ||:diagtext:`class containing a` |nbsp| || ||:diagtext:`copied` || -| |+-----------------------------+| |+--------------------------------------+| |+-----------------------+| -| ||:diagtext:`first operand of` || | | ||:diagtext:`moved` || -| |+-----------------------------+| | | |+-----------------------+| -| ||:diagtext:`second operand of`|| | | ||:diagtext:`compared` || -| |+-----------------------------+| | | |+-----------------------+| -+---------------------------+-------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------+---------------------------------------------------------------------------------------------+-------------------------+ - - --Wdynamic-exception-spec ------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wdeprecated-dynamic-exception-spec`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ISO C++17 does not allow dynamic exception specifications`| -+--------------------------------------------------------------------------------------------+ - - --Weffc++ --------- -Synonym for `-Wnon-virtual-dtor`_. - - --Wembedded-directive --------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`embedding a directive within macro arguments has undefined behavior`| -+----------------------------------------------------------------------------------------------------------+ - - --Wempty-body ------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`for loop has empty body`| -+--------------------------------------------------------------+ - -+------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`if statement has empty body`| -+------------------------------------------------------------------+ - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`range-based for loop has empty body`| -+--------------------------------------------------------------------------+ - -+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`switch statement has empty body`| -+----------------------------------------------------------------------+ - -+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`while loop has empty body`| -+----------------------------------------------------------------+ - - --Wempty-decomposition ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++17 does not allow a decomposition group to be empty`| -+-------------------------------------------------------------------------------------------------+ - - --Wempty-init-stmt ------------------ -**Diagnostic text:** - -+--------------------------------------------------------------------------+-----------------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty initialization statement of '`|+---------------------------+|:diagtext:`' has no effect`| -| ||:diagtext:`if` || | -| |+---------------------------+| | -| ||:diagtext:`switch` || | -| |+---------------------------+| | -| ||:diagtext:`range-based for`|| | -| |+---------------------------+| | -+--------------------------------------------------------------------------+-----------------------------+---------------------------+ - - --Wempty-translation-unit ------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C requires a translation unit to contain at least one declaration`| -+------------------------------------------------------------------------------------------------------------+ - - --Wencode-type -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`encoding of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`type is incomplete because` |nbsp| :placeholder:`B` |nbsp| :diagtext:`component has unknown encoding`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wendif-labels --------------- -Synonym for `-Wextra-tokens`_. - - --Wenum-compare --------------- -This diagnostic is enabled by default. - -Also controls `-Wdeprecated-enum-compare`_, `-Wenum-compare-switch`_. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+-----------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+-----------------------------------------------+ - - --Wenum-compare-conditional --------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wdeprecated-enum-compare-conditional`_. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+-----------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+-----------------------------------------------+ - - --Wenum-compare-switch ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of different enumeration types in switch statement`| -+----------------------------------------------------------------------------------------------------+ - - --Wenum-conversion ------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wenum-compare-conditional`_, `-Wenum-enum-conversion`_, `-Wenum-float-conversion`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from enumeration type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to different enumeration type` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wenum-enum-conversion ----------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wdeprecated-enum-enum-conversion`_. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+-----------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| :diagtext:`different enumeration types`| -| ||:diagtext:`arithmetic between` || | -| |+------------------------------------------+| | -| ||:diagtext:`bitwise operation between` || | -| |+------------------------------------------+| | -| ||:diagtext:`comparison of` || | -| |+------------------------------------------+| | -| ||:diagtext:`conditional expression between`|| | -| |+------------------------------------------+| | -| ||:diagtext:`compound assignment of` || | -| |+------------------------------------------+| | -+---------------------------+--------------------------------------------+-----------------------------------------------+ - - --Wenum-float-conversion ------------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wdeprecated-enum-float-conversion`_. - -**Diagnostic text:** - -+---------------------------+--------------------------------------------+--------+----------------------------+--------------------------------------------------------+------------------+--------+----------------------------+------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------+| |nbsp| |+--------------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| |+--------------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`D`| -| ||:diagtext:`arithmetic between` || ||:diagtext:`floating-point`|| ||:diagtext:`with`|| ||:diagtext:`enumeration` || | -| |+------------------------------------------+| |+--------------------------+| |+----------------+| |+--------------------------+| | -| ||:diagtext:`bitwise operation between` || ||:diagtext:`enumeration` || ||:diagtext:`from`|| ||:diagtext:`floating-point`|| | -| |+------------------------------------------+| |+--------------------------+| |+----------------+| |+--------------------------+| | -| ||:diagtext:`comparison of` || | | ||:diagtext:`and` || | | | -| |+------------------------------------------+| | | |+----------------+| | | | -| ||:diagtext:`conditional expression between`|| | | | | | | | -| |+------------------------------------------+| | | | | | | | -| ||:diagtext:`compound assignment of` || | | | | | | | -| |+------------------------------------------+| | | | | | | | -+---------------------------+--------------------------------------------+--------+----------------------------+--------------------------------------------------------+------------------+--------+----------------------------+------------------------------------------------+ - - --Wenum-too-large ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration values exceed range of largest integer`| -+-----------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incremented enumerator value` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not representable in the largest integer type`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wexceptions ------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------+-------------------------+--------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cannot refer to a non-static member from the handler of a` |nbsp| |+-----------------------+| |nbsp| :diagtext:`function try block`| -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -| ||:diagtext:`destructor` || | -| |+-----------------------+| | -+--------------------------------------------------------------------------------------------------------+-------------------------+--------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`exception of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will be caught by earlier handler`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has a non-throwing exception specification but can still throw`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wexcess-initializers ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------+--------------------+-------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`excess elements in` |nbsp| |+------------------+| |nbsp| :diagtext:`initializer`| -| ||:diagtext:`array` || | -| |+------------------+| | -| ||:diagtext:`vector`|| | -| |+------------------+| | -| ||:diagtext:`scalar`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -| ||:diagtext:`struct`|| | -| |+------------------+| | -+-----------------------------------------------------------------+--------------------+-------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`excess elements in initializer for indivisible sizeless type` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`excess elements in char array initializer`| -+--------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializer-string for char array is too long`| -+------------------------------------------------------------------------------------+ - - --Wexit-time-destructors ------------------------ -**Diagnostic text:** - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration requires an exit-time destructor`| -+-----------------------------------------------------------------------------------+ - - --Wexpansion-to-defined ----------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`macro expansion producing 'defined' has undefined behavior`| -+-------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`macro expansion producing 'defined' has undefined behavior`| -+-------------------------------------------------------------------------------------------------+ - - --Wexplicit-initialize-call --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit call to +initialize results in duplicate call to +initialize`| -+------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit call to \[super initialize\] should only be in implementation of +initialize`| -+----------------------------------------------------------------------------------------------------------------------------+ - - --Wexplicit-ownership-type -------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`method parameter of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with no explicit ownership`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - - --Wexport-unnamed ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------+------------------------------+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 does not permit` |nbsp| |+----------------------------+| |nbsp| :diagtext:`declaration to appear in an export block`| -| ||:diagtext:`an empty` || | -| |+----------------------------+| | -| ||:diagtext:`a static\_assert`|| | -| |+----------------------------+| | -+------------------------------------------------------------------------+------------------------------+------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 does not permit a declaration that does not introduce any names to be exported`| -+-------------------------------------------------------------------------------------------------------------------------------+ - - --Wexport-using-directive ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 does not permit using directive to be exported`| -+-----------------------------------------------------------------------------------------------+ - - --Wextern-c-compat ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+---------------------------+--------------------+--------------------------------------------+---------------------------+--------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------+|+------------------+| |nbsp| :diagtext:`has size 0 in C,` |nbsp| |+-------------------------+| |nbsp| :diagtext:`in C++`| -| || |||:diagtext:`struct`|| ||:diagtext:`size 1` || | -| |+-------------------------+|+------------------+| |+-------------------------+| | -| ||:diagtext:`empty` |nbsp| |||:diagtext:`union` || ||:diagtext:`non-zero size`|| | -| |+-------------------------+|+------------------+| |+-------------------------+| | -+---------------------------+---------------------------+--------------------+--------------------------------------------+---------------------------+--------------------------+ - - --Wextern-initializer --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'extern' variable has an initializer`| -+---------------------------------------------------------------------------+ - - --Wextra -------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wdeprecated-copy`_, `-Wempty-init-stmt`_, `-Wignored-qualifiers`_, `-Winitializer-overrides`_, `-Wmissing-field-initializers`_, `-Wmissing-method-return-type`_, `-Wnull-pointer-arithmetic`_, `-Wsemicolon-before-method-body`_, `-Wsign-compare`_, `-Wunused-parameter`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`call to function without interrupt attribute could clobber interruptee's VFP registers`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wextra-qualification ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra qualification on member` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------+ - - --Wextra-semi ------------- -Also controls `-Wc++11-extra-semi`_, `-Wc++98-compat-extra-semi`_. - -**Diagnostic text:** - -+--------------------------------------------------------+------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra ';'` |nbsp| |+----------------------------------------------+| -| ||:diagtext:`outside of a function` || -| |+----------------------------------------------+| -| ||+--------------------------------------------+|| -| |||:diagtext:`inside a` |nbsp| :placeholder:`B`||| -| ||+--------------------------------------------+|| -| |+----------------------------------------------+| -| ||:diagtext:`inside instance variable list` || -| |+----------------------------------------------+| -| ||:diagtext:`after member function definition` || -| |+----------------------------------------------+| -+--------------------------------------------------------+------------------------------------------------+ - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra ';' after member function definition`| -+---------------------------------------------------------------------------------+ - - --Wextra-semi-stmt ------------------ -Also controls `-Wempty-init-stmt`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty expression statement has no effect; remove unnecessary ';' to silence this warning`| -+-------------------------------------------------------------------------------------------------------------------------------+ - - --Wextra-tokens --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra tokens at end of #`:placeholder:`A` |nbsp| :diagtext:`directive`| -+------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra tokens at the end of '#pragma omp` |nbsp| :placeholder:`A`:diagtext:`' are ignored`| -+-------------------------------------------------------------------------------------------------------------------------------+ - - --Wfallback ----------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`falling back to` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------+ - - --Wfinal-dtor-non-final-class ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------+--------------------+--------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class with destructor marked '`|+------------------+|:diagtext:`' cannot be inherited from`| -| ||:diagtext:`final` || | -| |+------------------+| | -| ||:diagtext:`sealed`|| | -| |+------------------+| | -+---------------------------------------------------------------------+--------------------+--------------------------------------+ - - --Wfixed-enum-extension ----------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are a Clang extension`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wflag-enum ------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration value` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is out of range of flags in enumeration type` |nbsp| :placeholder:`B`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wflexible-array-extensions ---------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may not be used as an array element due to flexible array member`| -+-------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may not be nested in a struct due to flexible array member`| -+-------------------------------------------------------------------------------------------------------------------------+ - - --Wfloat-conversion ------------------- -Also controls `-Wfloat-overflow-conversion`_, `-Wfloat-zero-conversion`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion turns floating-point number into integer:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wfloat-equal -------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparing floating point with == or != is unsafe`| -+---------------------------------------------------------------------------------------+ - - --Wfloat-overflow-conversion ---------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion of out of range value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is undefined`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wfloat-zero-conversion ------------------------ -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`changes non-zero value from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wfor-loop-analysis -------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is` |nbsp| |+-----------------------+| |nbsp| :diagtext:`both in the loop header and in the loop body`| -| ||:diagtext:`decremented`|| | -| |+-----------------------+| | -| ||:diagtext:`incremented`|| | -| |+-----------------------+| | -+-----------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------+ - -+-----------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable`|+----------------------------------------------------------------------------------------------------------------------------------------------------------+| |nbsp| :diagtext:`used in loop condition not modified in loop body`| -| ||:diagtext:`s` || | -| |+----------------------------------------------------------------------------------------------------------------------------------------------------------+| | -| ||+------------------------+ || | -| ||| |nbsp| :placeholder:`B`| || | -| ||+------------------------+ || | -| |+----------------------------------------------------------------------------------------------------------------------------------------------------------+| | -| ||+------------------------------------------------------------------------------------+ || | -| |||:diagtext:`s` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C`| || | -| ||+------------------------------------------------------------------------------------+ || | -| |+----------------------------------------------------------------------------------------------------------------------------------------------------------+| | -| ||+-------------------------------------------------------------------------------------------------------------------+ || | -| |||:diagtext:`s` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`, and` |nbsp| :placeholder:`D`| || | -| ||+-------------------------------------------------------------------------------------------------------------------+ || | -| |+----------------------------------------------------------------------------------------------------------------------------------------------------------+| | -| ||+--------------------------------------------------------------------------------------------------------------------------------------------------------+|| | -| |||:diagtext:`s` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`,` |nbsp| :placeholder:`D`:diagtext:`, and` |nbsp| :placeholder:`E`||| | -| ||+--------------------------------------------------------------------------------------------------------------------------------------------------------+|| | -| |+----------------------------------------------------------------------------------------------------------------------------------------------------------+| | -+-----------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+ - - --Wformat --------- -This diagnostic is enabled by default. - -Also controls `-Wformat-extra-args`_, `-Wformat-invalid-specifier`_, `-Wformat-security`_, `-Wformat-y2k`_, `-Wformat-zero-length`_, `-Wnonnull`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using '%%P' format specifier without precision`| -+-------------------------------------------------------------------------------------+ - -+---------------------------+----------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------------------+| |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' should not be used as format arguments; add an explicit cast to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`instead`| -| ||:diagtext:`values of type` || | -| |+--------------------------------------------+| | -| ||:diagtext:`enum values with underlying type`|| | -| |+--------------------------------------------+| | -+---------------------------+----------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using '`:placeholder:`A`:diagtext:`' format specifier, but argument has boolean value`| -+----------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format specifies type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`but the argument has` |nbsp| |+---------------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`type` || | -| |+---------------------------+| | -| ||:diagtext:`underlying type`|| | -| |+---------------------------+| | -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using '`:placeholder:`A`:diagtext:`' format specifier annotation outside of os\_log()/os\_trace()`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------+-----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid position specified for` |nbsp| |+---------------------------+| -| ||:diagtext:`field width` || -| |+---------------------------+| -| ||:diagtext:`field precision`|| -| |+---------------------------+| -+-----------------------------------------------------------------------------+-----------------------------+ - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cannot mix positional and non-positional arguments in format string`| -+----------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`length modifier '`:placeholder:`A`:diagtext:`' results in undefined behavior or no effect with '`:placeholder:`B`:diagtext:`' conversion specifier`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format string should not be a wide string`| -+--------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`position arguments in format strings start counting at 1 (not 0)`| -+-------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format string missing`| -+------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`object format flags cannot be used with '`:placeholder:`A`:diagtext:`' conversion specifier`| -+----------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------+-----------------+-------------------------------------+-----------------------+--------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+---------------+|:diagtext:`' specified field` |nbsp| |+---------------------+| |nbsp| :diagtext:`is missing a matching 'int' argument`| -| ||:diagtext:`\*` || ||:diagtext:`width` || | -| |+---------------+| |+---------------------+| | -| ||:diagtext:`.\*`|| ||:diagtext:`precision`|| | -| |+---------------+| |+---------------------+| | -+----------------------------------------+-----------------+-------------------------------------+-----------------------+--------------------------------------------------------+ - -+----------------------------------------------------+-----------------------+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| |+---------------------+| |nbsp| :diagtext:`should have type` |nbsp| :placeholder:`B`:diagtext:`, but argument has type` |nbsp| :placeholder:`C`| -| ||:diagtext:`width` || | -| |+---------------------+| | -| ||:diagtext:`precision`|| | -| |+---------------------+| | -+----------------------------------------------------+-----------------------+-----------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing object format flag`| -+-----------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format string contains '\\0' within the string body`| -+------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format string is not null-terminated`| -+---------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flag '`:placeholder:`A`:diagtext:`' is ignored when flag '`:placeholder:`B`:diagtext:`' is present`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incomplete format specifier`| -+------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`more '%%' conversions than data arguments`| -+--------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid object format flag`| -+-------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flag '`:placeholder:`A`:diagtext:`' results in undefined behavior with '`:placeholder:`B`:diagtext:`' conversion specifier`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+-------------------------+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-----------------------+| |nbsp| :diagtext:`used with '`:placeholder:`B`:diagtext:`' conversion specifier, resulting in undefined behavior`| -| ||:diagtext:`field width`|| | -| |+-----------------------+| | -| ||:diagtext:`precision` || | -| |+-----------------------+| | -+---------------------------+-------------------------+------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`data argument position '`:placeholder:`A`:diagtext:`' exceeds the number of data arguments (`:placeholder:`B`:diagtext:`)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`zero field width in scanf format string is unused`| -+----------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no closing '\]' for '%%\[' in scanf format string`| -+----------------------------------------------------------------------------------------+ - - --Wformat-extra-args -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`data argument not used by format string`| -+------------------------------------------------------------------------------+ - - --Wformat-invalid-specifier --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid conversion specifier '`:placeholder:`A`:diagtext:`'`| -+--------------------------------------------------------------------------------------------------+ - - --Wformat-non-iso ----------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------+----------------------------------+---------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`'` |nbsp| |+--------------------------------+| |nbsp| :diagtext:`is not supported by ISO C`| -| ||:diagtext:`length modifier` || | -| |+--------------------------------+| | -| ||:diagtext:`conversion specifier`|| | -| |+--------------------------------+| | -+-----------------------------------------------------------------------------+----------------------------------+---------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using length modifier '`:placeholder:`A`:diagtext:`' with conversion specifier '`:placeholder:`B`:diagtext:`' is not supported by ISO C`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`positional arguments are not supported by ISO C`| -+--------------------------------------------------------------------------------------+ - - --Wformat-nonliteral -------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format string is not a string literal`| -+----------------------------------------------------------------------------+ - - --Wformat-pedantic ------------------ -**Diagnostic text:** - -+---------------------------+----------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------------------+| |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' should not be used as format arguments; add an explicit cast to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`instead`| -| ||:diagtext:`values of type` || | -| |+--------------------------------------------+| | -| ||:diagtext:`enum values with underlying type`|| | -| |+--------------------------------------------+| | -+---------------------------+----------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format specifies type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`but the argument has` |nbsp| |+---------------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`type` || | -| |+---------------------------+| | -| ||:diagtext:`underlying type`|| | -| |+---------------------------+| | -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ - - --Wformat-security ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format string is not a string literal (potentially insecure)`| -+---------------------------------------------------------------------------------------------------+ - - --Wformat-type-confusion ------------------------ -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format specifies type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`but the argument has` |nbsp| |+---------------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`type` || | -| |+---------------------------+| | -| ||:diagtext:`underlying type`|| | -| |+---------------------------+| | -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ - - --Wformat-y2k ------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wformat-zero-length --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format string is empty`| -+-------------------------------------------------------------+ - - --Wformat=2 ----------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wformat-nonliteral`_, `-Wformat-security`_, `-Wformat-y2k`_. - - --Wfortify-source ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will always overflow; destination buffer has size` |nbsp| :placeholder:`B`:diagtext:`, but format string expands to at least` |nbsp| :placeholder:`C`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will always overflow; destination buffer has size` |nbsp| :placeholder:`B`:diagtext:`, but size argument is` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' size argument is too large; destination buffer has size` |nbsp| :placeholder:`B`:diagtext:`, but size argument is` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wfour-char-constants ---------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multi-character character constant`| -+-------------------------------------------------------------------------+ - - --Wframe-address ---------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`calling '`:placeholder:`A`:diagtext:`' with a nonzero argument is unsafe`| -+---------------------------------------------------------------------------------------------------------------+ - - --Wframe-larger-than= --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`stack frame size of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`bytes in` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - - --Wframework-include-private-from-public ---------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`public framework header includes private framework header '`:placeholder:`A`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------------------------------+ - - --Wfunction-def-in-objc-container --------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function definition inside an Objective-C container is deprecated`| -+--------------------------------------------------------------------------------------------------------+ - - --Wfunction-multiversion ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`body of cpu\_dispatch function will be ignored`| -+-------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`CPU list contains duplicate entries; attribute ignored`| -+---------------------------------------------------------------------------------------------+ - - --Wfuture-compat ---------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wgcc-compat ------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'diagnose\_if' is a clang extension`| -+--------------------------------------------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'enable\_if' is a clang extension`| -+------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\_\_final is a GNU extension, consider using C++11 final`| -+-----------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`GCC does not allow` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute in this position on a function definition`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'break' is bound to loop, GCC binds it to switch`| -+---------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`GCC does not allow the 'cleanup' attribute argument to be anything other than a simple identifier`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`GCC does not allow an attribute in this position on a function declaration`| -+-----------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`GCC does not allow the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute to be written on a type`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`GCC does not allow variable declarations in for loop initializers before C99`| -+-------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is bound to current loop, GCC binds it to the enclosing loop`| -+----------------------------------------------------------------------------------------------------------------------------------+ - - --Wglobal-constructors ---------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration requires a global constructor`| -+--------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration requires a global destructor`| -+-------------------------------------------------------------------------------+ - - --Wglobal-isel -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`-fglobal-isel support for the '`:placeholder:`A`:diagtext:`' architecture is incomplete`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`-fglobal-isel support is incomplete for this architecture at the current optimization level`| -+----------------------------------------------------------------------------------------------------------------------------------+ - - --Wgnu ------ -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wgnu-alignof-expression`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-designator`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-static-float-init`_, `-Wgnu-string-literal-operator-template`_, `-Wgnu-union-cast`_, `-Wgnu-variable-sized-type-not-at-end`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wredeclared-class-member`_, `-Wvla-extension`_, `-Wzero-length-array`_. - - --Wgnu-alignof-expression ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`applied to an expression is a GNU extension`| -+----------------------------------------------------------------------------------------------------------+ - - --Wgnu-anonymous-struct ----------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`anonymous structs are a GNU extension`| -+----------------------------------------------------------------------------+ - - --Wgnu-array-member-paren-init ------------------------------ -This diagnostic is an error by default, but the flag ``-Wno-gnu-array-member-paren-init`` can be used to disable the error. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`parenthesized initialization of a member array is a GNU extension`| -+----------------------------------------------------------------------------------------------------+ - - --Wgnu-auto-type ---------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'\_\_auto\_type' is a GNU extension`| -+--------------------------------------------------------------------------+ - - --Wgnu-binary-literal --------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`binary integer literals are a GNU extension`| -+----------------------------------------------------------------------------------+ - - --Wgnu-case-range ----------------- -**Diagnostic text:** - -+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU case range extension`| -+----------------------------------------------------------------------+ - - --Wgnu-complex-integer ---------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`complex integer types are a GNU extension`| -+--------------------------------------------------------------------------------+ - - --Wgnu-compound-literal-initializer ----------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialization of an array` |nbsp| :diagtext:`from a compound literal` |nbsp| :diagtext:`is a GNU extension`| -+--------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wgnu-conditional-omitted-operand ---------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU ?: conditional expression extension, omitting middle operand`| -+--------------------------------------------------------------------------------------------------------------+ - - --Wgnu-designator ----------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU array range extension`| -+-----------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU 'missing =' extension in designator`| -+-------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU old-style field designator extension`| -+--------------------------------------------------------------------------------------+ - - --Wgnu-empty-initializer ------------------------ -**Diagnostic text:** - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU empty initializer extension`| -+-----------------------------------------------------------------------------+ - - --Wgnu-empty-struct ------------------- -**Diagnostic text:** - -+----------------------------------------------------+--------------------+--------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty` |nbsp| |+------------------+| |nbsp| :diagtext:`is a GNU extension`| -| ||:diagtext:`struct`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -+----------------------------------------------------+--------------------+--------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+-----------------------+--------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flexible array member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in otherwise empty` |nbsp| |+---------------------+| |nbsp| :diagtext:`is a GNU extension`| -| ||:diagtext:`struct` || | -| |+---------------------+| | -| ||:diagtext:`interface`|| | -| |+---------------------+| | -| ||:diagtext:`union` || | -| |+---------------------+| | -| ||:diagtext:`class` || | -| |+---------------------+| | -| ||:diagtext:`enum` || | -| |+---------------------+| | -+----------------------------------------------------------------------------------------------------------------------------------+-----------------------+--------------------------------------+ - -+---------------------------+--------------------+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------+| |nbsp| :diagtext:`without named members is a GNU extension`| -| ||:diagtext:`struct`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -+---------------------------+--------------------+------------------------------------------------------------+ - - --Wgnu-flexible-array-initializer --------------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flexible array initialization is a GNU extension`| -+---------------------------------------------------------------------------------------+ - - --Wgnu-flexible-array-union-member ---------------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flexible array member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in a union is a GNU extension`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - - --Wgnu-folding-constant ----------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------+----------------------+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression is not an` |nbsp| |+--------------------+| |nbsp| :diagtext:`constant expression; folding it to a constant is a GNU extension`| -| ||:diagtext:`integer` || | -| |+--------------------+| | -| ||:diagtext:`integral`|| | -| |+--------------------+| | -+-------------------------------------------------------------------+----------------------+------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`in-class initializer for static data member is not a constant expression; folding it to a constant is a GNU extension`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable length array folded to constant array as an extension`| -+-----------------------------------------------------------------------------------------------------+ - - --Wgnu-imaginary-constant ------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`imaginary constants are a GNU extension`| -+------------------------------------------------------------------------------+ - - --Wgnu-include-next ------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#include\_next is a language extension`| -+-----------------------------------------------------------------------------+ - - --Wgnu-inline-cpp-without-extern -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'gnu\_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wgnu-label-as-value --------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU address-of-label extension`| -+----------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU indirect-goto extension`| -+-------------------------------------------------------------------------+ - - --Wgnu-redeclared-enum ---------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redeclaration of already-defined enum` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a GNU extension`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wgnu-statement-expression --------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU statement expression extension`| -+--------------------------------------------------------------------------------+ - - --Wgnu-static-float-init ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`in-class initializer for static data member of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a GNU extension`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wgnu-string-literal-operator-template --------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`string literal operator templates are a GNU extension`| -+--------------------------------------------------------------------------------------------+ - - --Wgnu-union-cast ----------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to union type is a GNU extension`| -+----------------------------------------------------------------------------+ - - --Wgnu-variable-sized-type-not-at-end ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with variable sized type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not at the end of a struct or class is a GNU extension`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wgnu-zero-line-directive -------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#line directive with zero argument is a GNU extension`| -+--------------------------------------------------------------------------------------------+ - - --Wgnu-zero-variadic-macro-arguments ------------------------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`must specify at least one argument for '...' parameter of variadic macro`| -+---------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`token pasting of ',' and \_\_VA\_ARGS\_\_ is a GNU extension`| -+---------------------------------------------------------------------------------------------------+ - - --Wheader-guard --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is used as a header guard here, followed by #define of a different macro`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - - --Wheader-hygiene ----------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using namespace directive in global context in header`| -+--------------------------------------------------------------------------------------------+ - - --Whip-only ----------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is ignored since it is only supported for HIP`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Widiomatic-parentheses ------------------------ -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using the result of an assignment as a condition without parentheses`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wignored-attributes --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'trivial\_abi' cannot be applied to` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------+ - -+---------------------------+-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-----------------+| |nbsp| :diagtext:`will always resolve to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`even if weak definition of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is overridden`| -| ||:diagtext:`alias`|| | -| |+-----------------+| | -| ||:diagtext:`ifunc`|| | -| |+-----------------+| | -+---------------------------+-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+-------------------+----------------------------------------------------------------------------------------------------------------+----------------------+ -|:warning:`warning:` |nbsp| |+-----------------+| |nbsp| :diagtext:`will not be in section '`:placeholder:`A`:diagtext:`' but in the same section as the` |nbsp| |+--------------------+| -| ||:diagtext:`alias`|| ||:diagtext:`aliasee` || -| |+-----------------+| |+--------------------+| -| ||:diagtext:`ifunc`|| ||:diagtext:`resolver`|| -| |+-----------------+| |+--------------------+| -+---------------------------+-------------------+----------------------------------------------------------------------------------------------------------------+----------------------+ - -+----------------------------------------------------------------------+------------------------+-------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'abi\_tag' attribute on` |nbsp| |+----------------------+| |nbsp| :diagtext:`namespace ignored`| -| ||:diagtext:`non-inline`|| | -| |+----------------------+| | -| ||:diagtext:`anonymous` || | -| |+----------------------+| | -+----------------------------------------------------------------------+------------------------+-------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`after definition is ignored`| -+-----------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'cmse\_nonsecure\_entry' cannot be applied to functions with internal linkage`| -+--------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'dllexport' attribute ignored on explicit instantiation definition`| -+---------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute can only be applied to instance variables or properties`| -+--------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute ignored`| -+--------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute ignored for field of type` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute ignored on inline function`| -+---------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' attribute cannot be specified on a definition`| -+-------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored, because it is not attached to a declaration`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'nonnull' attribute applied to function with no pointer arguments`| -+--------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'nonnull' attribute when used on parameters takes no arguments`| -+-----------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute ignored when parsing type`| -+--------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to a pointer or reference (`:placeholder:`B` |nbsp| :diagtext:`is invalid)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+------------------------------+-------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to`|+----------------------------+| |nbsp| :diagtext:`pointer arguments`| -| || || | -| |+----------------------------+| | -| || |nbsp| :diagtext:`constant`|| | -| |+----------------------------+| | -+----------------------------------------------------------------------------------------+------------------------------+-------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute declaration must precede definition`| -+------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to return values that are pointers`| -+------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to return values that are pointers or references`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'sentinel' attribute requires named arguments`| -+------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'sentinel' attribute only supported for variadic` |nbsp| |+---------------------+| -| ||:diagtext:`functions`|| -| |+---------------------+| -| ||:diagtext:`blocks` || -| |+---------------------+| -+-----------------------------------------------------------------------------------------------+-----------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute argument not supported:` |nbsp| :placeholder:`B`| -+------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown visibility` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+--------------------------------+----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot be applied to` |nbsp| |+------------------------------+| |nbsp| :diagtext:`without return value`| -| ||:diagtext:`functions` || | -| |+------------------------------+| | -| ||:diagtext:`Objective-C method`|| | -| |+------------------------------+| | -+------------------------------------------------------------------------------------------------------------------------+--------------------------------+----------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\_\_weak attribute cannot be specified on a field declaration`| -+----------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\_\_weak attribute cannot be specified on an automatic variable when ARC is not enabled`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+---------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+-------------------------------------------------+| -| ||:diagtext:`functions` || -| |+-------------------------------------------------+| -| ||:diagtext:`unions` || -| |+-------------------------------------------------+| -| ||:diagtext:`variables and functions` || -| |+-------------------------------------------------+| -| ||:diagtext:`functions and methods` || -| |+-------------------------------------------------+| -| ||:diagtext:`functions, methods and blocks` || -| |+-------------------------------------------------+| -| ||:diagtext:`functions, methods, and parameters` || -| |+-------------------------------------------------+| -| ||:diagtext:`variables` || -| |+-------------------------------------------------+| -| ||:diagtext:`variables and fields` || -| |+-------------------------------------------------+| -| ||:diagtext:`variables, data members and tag types`|| -| |+-------------------------------------------------+| -| ||:diagtext:`types and namespaces` || -| |+-------------------------------------------------+| -| ||:diagtext:`variables, functions and classes` || -| |+-------------------------------------------------+| -| ||:diagtext:`kernel functions` || -| |+-------------------------------------------------+| -| ||:diagtext:`non-K&R-style functions` || -| |+-------------------------------------------------+| -+------------------------------------------------------------------------------------------------+---------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored, because it cannot be applied to omitted return type`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------+---------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`calling convention is not supported` |nbsp| |+-------------------------------------+| -| ||:diagtext:`for this target` || -| |+-------------------------------------+| -| ||:diagtext:`on variadic function` || -| |+-------------------------------------+| -| ||:diagtext:`on constructor/destructor`|| -| |+-------------------------------------+| -| ||:diagtext:`on builtin function` || -| |+-------------------------------------+| -+----------------------------------------------------------------------------------------------------------+---------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored, because it cannot be applied to a type`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring \_\_declspec(allocator) because the function return type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not a pointer or reference type`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+-----------------------+----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is ignored, place it after "`|+---------------------+|:diagtext:`" to apply attribute to type declaration`| -| ||:diagtext:`class` || | -| |+---------------------+| | -| ||:diagtext:`struct` || | -| |+---------------------+| | -| ||:diagtext:`interface`|| | -| |+---------------------+| | -| ||:diagtext:`union` || | -| |+---------------------+| | -| ||:diagtext:`enum` || | -| |+---------------------+| | -+------------------------------------------------------------------------------------------------------------------------+-----------------------+----------------------------------------------------+ - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'deprecated' attribute on anonymous namespace ignored`| -+--------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`redeclared inline;` |nbsp| :placeholder:`B` |nbsp| :diagtext:`attribute ignored`| -+----------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is already applied with different parameters`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is already applied`| -+--------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Objective-C GC does not allow weak variables on the stack`| -+------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'gnu\_inline' attribute requires function to be marked 'inline', attribute ignored`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------+------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inheritance model ignored on` |nbsp| |+----------------------------------+| -| ||:diagtext:`primary template` || -| |+----------------------------------+| -| ||:diagtext:`partial specialization`|| -| |+----------------------------------+| -+---------------------------------------------------------------------------+------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------+-----------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'objc\_externally\_retained' can only be applied to local variables` |nbsp| |+---------------------------------+| -| ||:diagtext:`of retainable type` || -| |+---------------------------------+| -| ||:diagtext:`with strong ownership`|| -| |+---------------------------------+| -+------------------------------------------------------------------------------------------------------------------+-----------------------------------+ - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'internal\_linkage' attribute on a non-static local variable is ignored`| -+--------------------------------------------------------------------------------------------------------------+ - -+---------------------------+--------------------+-------------------------------------------------------------------------------------+----------------------------------+ -|:warning:`warning:` |nbsp| |+------------------+| |nbsp| :diagtext:`'interrupt' attribute only applies to functions that have` |nbsp| |+--------------------------------+| -| ||:diagtext:`MIPS` || ||:diagtext:`no parameters` || -| |+------------------+| |+--------------------------------+| -| ||:diagtext:`MSP430`|| ||:diagtext:`a 'void' return type`|| -| |+------------------+| |+--------------------------------+| -| ||:diagtext:`RISC-V`|| | | -| |+------------------+| | | -+---------------------------+--------------------+-------------------------------------------------------------------------------------+----------------------------------+ - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`qualifiers after comma in declarator list are ignored`| -+--------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'mig\_server\_routine' attribute only applies to routines that return a kern\_return\_t`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown attribute '`:placeholder:`A`:diagtext:`'`| -+---------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'nocf\_check' attribute ignored; use -fcf-protection to enable the attribute`| -+-------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'noderef' can only be used on an array or pointer type`| -+---------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'nothrow' attribute conflicts with exception specification; attribute ignored`| -+--------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+---------------------------------------------------+------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+-------------------------------------------------+| |nbsp| :diagtext:`parameters`| -| ||:diagtext:`Objective-C object` || | -| |+-------------------------------------------------+| | -| ||:diagtext:`pointer` || | -| |+-------------------------------------------------+| | -| ||:diagtext:`pointer-to-CF-pointer` || | -| |+-------------------------------------------------+| | -| ||:diagtext:`pointer/reference-to-OSObject-pointer`|| | -| |+-------------------------------------------------+| | -+------------------------------------------------------------------------------------------------+---------------------------------------------------+------------------------------+ - -+------------------------------------------------------------------------------------------------+------------------------+---------------------------------------+--------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+----------------------+| |nbsp| :diagtext:`that return` |nbsp| |+------------------------------------+| -| ||:diagtext:`functions` || ||:diagtext:`an Objective-C object` || -| |+----------------------+| |+------------------------------------+| -| ||:diagtext:`methods` || ||:diagtext:`a pointer` || -| |+----------------------+| |+------------------------------------+| -| ||:diagtext:`properties`|| ||:diagtext:`a non-retainable pointer`|| -| |+----------------------+| |+------------------------------------+| -+------------------------------------------------------------------------------------------------+------------------------+---------------------------------------+--------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute isn't implemented by this Objective-C runtime`| -+----------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`direct attribute on property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored (not implemented by this Objective-C runtime)`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is deprecated and ignored in OpenCL version` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'require\_constant\_initialization' attribute added after initialization of variable`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`repeated RISC-V 'interrupt' attribute`| -+----------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template parameter of a function template with the 'sycl\_kernel' attribute cannot be a non-type template parameter`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function template with 'sycl\_kernel' attribute must have a single parameter`| -+-------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'sycl\_kernel' attribute only applies to a function template with at least two template parameters`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function template with 'sycl\_kernel' attribute must have a 'void' return type`| -+---------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------+| |nbsp| :diagtext:`of field` |nbsp| :placeholder:`B` |nbsp| :diagtext:`(`:placeholder:`C` |nbsp| :diagtext:`bits) does not match the` |nbsp| |+---------------------+| |nbsp| :diagtext:`of the first field in transparent union; transparent\_union attribute ignored`| -| ||:diagtext:`alignment`|| ||:diagtext:`alignment`|| | -| |+---------------------+| |+---------------------+| | -| ||:diagtext:`size` || ||:diagtext:`size` || | -| |+---------------------+| |+---------------------+| | -+---------------------------+-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+-------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+----------------------------+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`first field of a transparent union cannot have` |nbsp| |+--------------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`B`:diagtext:`; transparent\_union attribute ignored`| -| ||:diagtext:`floating point`|| | -| |+--------------------------+| | -| ||:diagtext:`vector` || | -| |+--------------------------+| | -+---------------------------------------------------------------------------------------------+----------------------------+--------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`transparent\_union attribute can only be applied to a union definition; attribute ignored`| -+--------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`transparent union definition must contain at least one field; transparent\_union attribute ignored`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+-------------------------------------------------+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' only applies to` |nbsp| |+-----------------------------------------------+| |nbsp| :diagtext:`types; type here is` |nbsp| :placeholder:`C`| -| ||:diagtext:`function` || | -| |+-----------------------------------------------+| | -| ||:diagtext:`pointer` || | -| |+-----------------------------------------------+| | -| ||:diagtext:`Objective-C object or block pointer`|| | -| |+-----------------------------------------------+| | -+---------------------------------------------------------------------------------------------+-------------------------------------------------+---------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\_\_declspec attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not supported`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-----------------------+|+--------------------------------+| |nbsp| :diagtext:`'`:placeholder:`C`:diagtext:`' in the 'target' attribute string; 'target' attribute ignored`| -| ||:diagtext:`unsupported`||| || | -| |+-----------------------+|+--------------------------------+| | -| ||:diagtext:`duplicate` ||| |nbsp| :diagtext:`architecture`|| | -| |+-----------------------+|+--------------------------------+| | -+---------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'\_\_clang\_\_' is a predefined macro name, not an attribute scope specifier; did you mean '\_Clang' instead?`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wignored-optimization-argument -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`optimization flag '`:placeholder:`A`:diagtext:`' is not supported for target '`:placeholder:`B`:diagtext:`'`| -+--------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`optimization flag '`:placeholder:`A`:diagtext:`' is not supported`| -+--------------------------------------------------------------------------------------------------------+ - - --Wignored-pragma-intrinsic --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not a recognized builtin`|+----------------------------------------------------------------------------+| -| || || -| |+----------------------------------------------------------------------------+| -| ||:diagtext:`; consider including to access non-builtin intrinsics`|| -| |+----------------------------------------------------------------------------+| -+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+ - - --Wignored-pragma-optimize -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'#pragma optimize' is not supported`| -+--------------------------------------------------------------------------+ - - --Wignored-pragmas ------------------ -This diagnostic is enabled by default. - -Also controls `-Wignored-pragma-intrinsic`_, `-Wignored-pragma-optimize`_. - -**Diagnostic text:** - -+------------------------------------------------------------------------------+---------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected '=' following '#pragma` |nbsp| |+-------------------------+|:diagtext:`' - ignored`| -| ||:diagtext:`align` || | -| |+-------------------------+| | -| ||:diagtext:`options align`|| | -| |+-------------------------+| | -+------------------------------------------------------------------------------+---------------------------+-----------------------+ - -+-----------------------------------------------------------------------------------+---------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid alignment option in '#pragma` |nbsp| |+-------------------------+|:diagtext:`' - ignored`| -| ||:diagtext:`align` || | -| |+-------------------------+| | -| ||:diagtext:`options align`|| | -| |+-------------------------+| | -+-----------------------------------------------------------------------------------+---------------------------+-----------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`OpenCL extension end directive mismatches begin directive - ignoring`| -+-----------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'#pragma comment` |nbsp| :placeholder:`A`:diagtext:`' ignored`| -+----------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing argument to debug command '`:placeholder:`A`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unexpected debug command '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown module '`:placeholder:`A`:diagtext:`'`| -+------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected action or ')' in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing ':' after` |nbsp| :placeholder:`A` |nbsp| :diagtext:`- ignoring`| -+--------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing ':' or ')' after` |nbsp| :placeholder:`A` |nbsp| :diagtext:`- ignoring`| -+---------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected ',' in '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected identifier in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+---------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected 'compiler', 'lib', 'user', or a string literal for the section name in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected integer between` |nbsp| :placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B` |nbsp| :diagtext:`inclusive in '#pragma` |nbsp| :placeholder:`C`:diagtext:`' - ignored`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing '(' after '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignoring`| -+-----------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected non-wide string literal in '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`| -+------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------+---------------------------------------------------+------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected` |nbsp| |+-------------------------------------------------+| |nbsp| :diagtext:`- ignoring`| -| ||:diagtext:`'enable', 'disable', 'begin' or 'end'`|| | -| |+-------------------------------------------------+| | -| ||:diagtext:`'disable'` || | -| |+-------------------------------------------------+| | -+-------------------------------------------------------+---------------------------------------------------+------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected ')' or ',' in '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing ')' after '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignoring`| -+-----------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected a stack label or a string literal for the section name in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected a string literal for the section name in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected push, pop or a string literal for the section name in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected string literal in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignoring`| -+--------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra tokens at end of '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+---------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incorrect use of #pragma clang force\_cuda\_host\_device begin\|end`| -+----------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'#pragma init\_seg' is only supported when targeting a Microsoft environment`| -+-------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown action for '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+-----------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unexpected argument '`:placeholder:`A`:diagtext:`' to '#pragma` |nbsp| :placeholder:`B`:diagtext:`'`|+------------------------------------------------+| -| || || -| |+------------------------------------------------+| -| ||+----------------------------------------------+|| -| |||:diagtext:`; expected` |nbsp| :placeholder:`D`||| -| ||+----------------------------------------------+|| -| |+------------------------------------------------+| -+------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown action '`:placeholder:`B`:diagtext:`' for '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+--------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing argument to '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`|+------------------------------------------------+| -| || || -| |+------------------------------------------------+| -| ||+----------------------------------------------+|| -| |||:diagtext:`; expected` |nbsp| :placeholder:`C`||| -| ||+----------------------------------------------+|| -| |+------------------------------------------------+| -+--------------------------------------------------------------------------------------------------------+--------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incorrect use of '#pragma ms\_struct on\|off' - ignored`| -+----------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma options align=reset failed:` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected 'align' following '#pragma options' - ignored`| -+---------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected #pragma pack parameter to be '1', '2', '4', '8', or '16'`| -+--------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected integer or identifier in '#pragma pack' - ignored`| -+-------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma` |nbsp| :placeholder:`A`:diagtext:`(pop, ...) failed:` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pragma pop\_macro could not pop '`:placeholder:`A`:diagtext:`', no matching push\_macro`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown OpenCL extension` |nbsp| :placeholder:`A` |nbsp| :diagtext:`- ignoring`| -+---------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`known but unsupported action '`:placeholder:`B`:diagtext:`' for '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unsupported OpenCL extension` |nbsp| :placeholder:`A` |nbsp| :diagtext:`- ignoring`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected '#pragma unused' argument to be a variable name`| -+-----------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`only variables can be arguments to '#pragma unused'`| -+------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`undeclared variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`used as an argument for '#pragma unused'`| -+----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wignored-qualifiers --------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------+------------------------------------+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ARC` |nbsp| |+----------------------------------+| |nbsp| :diagtext:`lifetime qualifier on return type is ignored`| -| ||:diagtext:`unused` || | -| |+----------------------------------+| | -| ||:diagtext:`\_\_unsafe\_unretained`|| | -| |+----------------------------------+| | -| ||:diagtext:`\_\_strong` || | -| |+----------------------------------+| | -| ||:diagtext:`\_\_weak` || | -| |+----------------------------------+| | -| ||:diagtext:`\_\_autoreleasing` || | -| |+----------------------------------+| | -+--------------------------------------------------+------------------------------------+----------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' qualifier on omitted return type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has no effect`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+---------------+------------------------------------------+------------------+-----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' type qualifier`|+-------------+| |nbsp| :diagtext:`on return type` |nbsp| |+----------------+| |nbsp| :diagtext:`no effect`| -| || || ||:diagtext:`has` || | -| |+-------------+| |+----------------+| | -| ||:diagtext:`s`|| ||:diagtext:`have`|| | -| |+-------------+| |+----------------+| | -+------------------------------------------------------------------------------------+---------------+------------------------------------------+------------------+-----------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' qualifier on function type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has no effect`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' qualifier on reference type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has no effect`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit ----------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wimplicit-function-declaration`_, `-Wimplicit-int`_. - - --Wimplicit-atomic-properties ----------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property is assumed atomic when auto-synthesizing the property`| -+-----------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property is assumed atomic by default`| -+----------------------------------------------------------------------------+ - - --Wimplicit-const-int-float-conversion -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit-conversion-floating-point-to-bool --------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion turns floating-point number into bool:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit-exception-spec-mismatch ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------+----------------------+----------------------------------------------------------------------+----------------------+-------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function previously declared with an` |nbsp| |+--------------------+| |nbsp| :diagtext:`exception specification redeclared with an` |nbsp| |+--------------------+| |nbsp| :diagtext:`exception specification`| -| ||:diagtext:`explicit`|| ||:diagtext:`implicit`|| | -| |+--------------------+| |+--------------------+| | -| ||:diagtext:`implicit`|| ||:diagtext:`explicit`|| | -| |+--------------------+| |+--------------------+| | -+-----------------------------------------------------------------------------------+----------------------+----------------------------------------------------------------------+----------------------+-------------------------------------------+ - - --Wimplicit-fallthrough ----------------------- -Also controls `-Wimplicit-fallthrough-per-function`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`fallthrough annotation in unreachable code`| -+---------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unannotated fall-through between switch labels`| -+-------------------------------------------------------------------------------------+ - - --Wimplicit-fallthrough-per-function ------------------------------------ -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unannotated fall-through between switch labels in partly-annotated function`| -+------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit-fixed-point-conversion ---------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot fit within the range of values for` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit-float-conversion ---------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wimplicit-int-float-conversion`_, `-Wobjc-signed-char-bool-implicit-float-conversion`_. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion loses floating-point precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion when assigning computation result loses floating-point precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit-function-declaration -------------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit declaration of function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is invalid in C99`| -+------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicitly declaring library function '`:placeholder:`A`:diagtext:`' with type` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`use of unknown builtin` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit declaration of function` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------------+ - - --Wimplicit-int --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type specifier missing, defaults to 'int'`| -+--------------------------------------------------------------------------------+ - - --Wimplicit-int-conversion -------------------------- -Also controls `-Wobjc-signed-char-bool-implicit-int-conversion`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`higher order bits are zeroes after implicit conversion`| -+---------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion loses integer precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit-int-float-conversion -------------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wimplicit-const-int-float-conversion`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`may lose precision`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicit-retain-self ----------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimplicitly-unsigned-literal ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`integer literal is too large to be represented in a signed integer type, interpreting as unsigned`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - - --Wimport --------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wimport-preprocessor-directive-pedantic ----------------------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#import is a language extension`| -+----------------------------------------------------------------------+ - - --Winaccessible-base -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`direct base` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is inaccessible due to ambiguity:`:placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winclude-next-absolute-path ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#include\_next in file found relative to primary source file or found by absolute path; will search from start of include path`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winclude-next-outside-header ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#include\_next in primary source file; will search from start of include path`| -+--------------------------------------------------------------------------------------------------------------------+ - - --Wincompatible-exception-spec ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------+----------------------+--------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`exception specifications of` |nbsp| |+--------------------+| |nbsp| :diagtext:`types differ`| -| ||:diagtext:`return` || | -| |+--------------------+| | -| ||:diagtext:`argument`|| | -| |+--------------------+| | -+--------------------------------------------------------------------------+----------------------+--------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`target exception specification is not superset of source`| -+-----------------------------------------------------------------------------------------------+ - - --Wincompatible-function-pointer-types -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incompatible function pointer types` |nbsp| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`assigning to different types` ||| || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`passing to parameter of different type` |||:diagtext:`; dereference with \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`returning from function with different return type`|||:diagtext:`; take the address with &`|| -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`converting between types` |||:diagtext:`; remove \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`initializing with expression of different type` |||:diagtext:`; remove &` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+----------------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ - - --Wincompatible-library-redeclaration ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incompatible redeclaration of library function` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------+ - - --Wincompatible-ms-struct ------------------------- -This diagnostic is an error by default, but the flag ``-Wno-incompatible-ms-struct`` can be used to disable the error. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ms\_struct may not produce Microsoft-compatible layouts for classes with base classes or virtual functions`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ms\_struct may not produce Microsoft-compatible layouts with fundamental data types with sizes that aren't a power of two`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wincompatible-pointer-types ----------------------------- -This diagnostic is enabled by default. - -Also controls `-Wincompatible-function-pointer-types`_, `-Wincompatible-pointer-types-discards-qualifiers`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incompatible pointer types` |nbsp| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`assigning to different types` ||| || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`passing to parameter of different type` |||:diagtext:`; dereference with \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`returning from function with different return type`|||:diagtext:`; take the address with &`|| -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`converting between types` |||:diagtext:`; remove \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`initializing with expression of different type` |||:diagtext:`; remove &` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+-------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ - - --Wincompatible-pointer-types-discards-qualifiers ------------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+----------------------------------------------------------------+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`discards qualifiers in nested pointer types`| -| ||:diagtext:`assigning to different types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`passing to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`returning from function with different return type`|| | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`converting between types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`initializing with expression of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+---------------------------+----------------------------------------------------------------+---------------------------------------------------------------+ - -+---------------------------+----------------------------------------------------------------+---------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`discards qualifiers`| -| ||:diagtext:`assigning to different types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`passing to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`returning from function with different return type`|| | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`converting between types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`initializing with expression of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+---------------------------+----------------------------------------------------------------+---------------------------------------+ - -+---------------------------+-------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`from` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to` |nbsp| :placeholder:`C` |nbsp| :diagtext:`changes address space of nested pointers`| -| ||:diagtext:`reinterpret\_cast`|| | -| |+-----------------------------+| | -| ||:diagtext:`C-style cast` || | -| |+-----------------------------+| | -+---------------------------+-------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wincompatible-property-type ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is incompatible with type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`inherited from` |nbsp| :placeholder:`C`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wincompatible-sysroot ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using sysroot for '`:placeholder:`A`:diagtext:`' but targeting '`:placeholder:`B`:diagtext:`'`| -+------------------------------------------------------------------------------------------------------------------------------------+ - - --Wincomplete-framework-module-declaration ------------------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`skipping '`:placeholder:`A`:diagtext:`' because module declaration of '`:placeholder:`B`:diagtext:`' lacks the 'framework' qualifier`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wincomplete-implementation ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`method definition for` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not found`| -+-----------------------------------------------------------------------------------------------------------------+ - - --Wincomplete-module -------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wincomplete-umbrella`_, `-Wnon-modular-include-in-module`_. - - --Wincomplete-setjmp-declaration -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration of built-in function '`:placeholder:`A`:diagtext:`' requires the declaration of the 'jmp\_buf' type, commonly provided in the header .`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wincomplete-umbrella ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing submodule '`:placeholder:`A`:diagtext:`'`| -+---------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`umbrella directory '`:placeholder:`A`:diagtext:`' not found`| -+--------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`umbrella header for module '`:placeholder:`A`:diagtext:`' does not include header '`:placeholder:`B`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winconsistent-dllimport ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`redeclared without` |nbsp| :placeholder:`B` |nbsp| :diagtext:`attribute: previous` |nbsp| :placeholder:`B` |nbsp| :diagtext:`ignored`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`redeclared without 'dllimport' attribute: 'dllexport' attribute added`| -+------------------------------------------------------------------------------------------------------------------------------------+ - - --Winconsistent-missing-destructor-override ------------------------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`overrides a destructor but is not marked 'override'`| -+------------------------------------------------------------------------------------------------------------------+ - - --Winconsistent-missing-override -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`overrides a member function but is not marked 'override'`| -+-----------------------------------------------------------------------------------------------------------------------+ - - --Wincrement-bool ----------------- -This diagnostic is enabled by default. - -Also controls `-Wdeprecated-increment-bool`_. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ISO C++17 does not allow incrementing expression of type bool`| -+------------------------------------------------------------------------------------------------+ - - --Winfinite-recursion --------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`all paths through this function will call itself`| -+---------------------------------------------------------------------------------------+ - - --Winit-self ------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Winitializer-overrides ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------+-------------------------------+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializer` |nbsp| |+-----------------------------+|:diagtext:`overrides prior initialization of this subobject`| -| ||:diagtext:`partially` |nbsp| || | -| |+-----------------------------+| | -| || || | -| |+-----------------------------+| | -+----------------------------------------------------------+-------------------------------+------------------------------------------------------------+ - -+----------------------------------------------------------+-------------------------------+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializer` |nbsp| |+-----------------------------+|:diagtext:`overrides prior initialization of this subobject`| -| ||:diagtext:`partially` |nbsp| || | -| |+-----------------------------+| | -| || || | -| |+-----------------------------+| | -+----------------------------------------------------------+-------------------------------+------------------------------------------------------------+ - - --Winjected-class-name ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+------------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ specifies that qualified reference to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a constructor name rather than a` |nbsp| |+-------------------------+| |nbsp| :diagtext:`in this context, despite preceding` |nbsp| |+----------------------+| |nbsp| :diagtext:`keyword`| -| ||:diagtext:`template name`|| ||:diagtext:`'typename'`|| | -| |+-------------------------+| |+----------------------+| | -| ||:diagtext:`type` || ||:diagtext:`'template'`|| | -| |+-------------------------+| |+----------------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+------------------------+---------------------------+ - - --Winline --------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Winline-asm ------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --Winline-new-delete -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`replacement function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot be declared 'inline'`| -+----------------------------------------------------------------------------------------------------------------------------------+ - - --Winstantiation-after-specialization ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit instantiation of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`that occurs after an explicit specialization has no effect`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wint-conversion ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incompatible integer to pointer conversion` |nbsp| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`assigning to different types` ||| || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`passing to parameter of different type` |||:diagtext:`; dereference with \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`returning from function with different return type`|||:diagtext:`; take the address with &`|| -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`converting between types` |||:diagtext:`; remove \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`initializing with expression of different type` |||:diagtext:`; remove &` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+-----------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ - -+-----------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incompatible pointer to integer conversion` |nbsp| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`assigning to different types` ||| || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`passing to parameter of different type` |||:diagtext:`; dereference with \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`returning from function with different return type`|||:diagtext:`; take the address with &`|| -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`converting between types` |||:diagtext:`; remove \*` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`initializing with expression of different type` |||:diagtext:`; remove &` || -| |+--------------------------------------------------------------+|+-------------------------------------+| -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+-----------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------------------------------+ - - --Wint-conversions ------------------ -Synonym for `-Wint-conversion`_. - - --Wint-in-bool-context ---------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`converting the enum constant to a boolean`| -+--------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`converting the result of '<<' to a boolean; did you mean '(`:placeholder:`A`:diagtext:`) != 0'?`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - - --Wint-to-pointer-cast ---------------------- -This diagnostic is enabled by default. - -Also controls `-Wint-to-void-pointer-cast`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from smaller integer type` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wint-to-void-pointer-cast --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from smaller integer type` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winteger-overflow ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overflow in expression; result is` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with type` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winvalid-command-line-argument -------------------------------- -This diagnostic is enabled by default. - -Also controls `-Wignored-optimization-argument`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the given MCU supports` |nbsp| :placeholder:`A` |nbsp| :diagtext:`hardware multiply, but -mhwmult is set to` |nbsp| :placeholder:`B`:diagtext:`.`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no MCU device specified, but '-mhwmult' is set to 'auto', assuming no hardware multiply. Use -mmcu to specify a MSP430 device, or -mhwmult to set hardware multiply type explicitly.`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the given MCU does not support hardware multiply, but -mhwmult is set to` |nbsp| :placeholder:`A`:diagtext:`.`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the object size sanitizer has no effect at -O0, but is explicitly enabled:` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`optimization level '`:placeholder:`A`:diagtext:`' is not supported; using '`:placeholder:`B`:placeholder:`C`:diagtext:`' instead`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring extension '`:placeholder:`A`:diagtext:`' because the '`:placeholder:`B`:diagtext:`' architecture does not support it`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winvalid-constexpr -------------------- -This diagnostic is an error by default, but the flag ``-Wno-invalid-constexpr`` can be used to disable the error. - -**Diagnostic text:** - -+-----------------------+-----------------------+--------+-------------------------+--------------------------------------------------------+ -|:error:`error:` |nbsp| |+---------------------+| |nbsp| |+-----------------------+| |nbsp| :diagtext:`never produces a constant expression`| -| ||:diagtext:`constexpr`|| ||:diagtext:`function` || | -| |+---------------------+| |+-----------------------+| | -| ||:diagtext:`consteval`|| ||:diagtext:`constructor`|| | -| |+---------------------+| |+-----------------------+| | -+-----------------------+-----------------------+--------+-------------------------+--------------------------------------------------------+ - - --Winvalid-iboutlet ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute must be an object type (invalid` |nbsp| :placeholder:`B`:diagtext:`)`| -| ||:diagtext:`instance variable`|| | -| |+-----------------------------+| | -| ||:diagtext:`property` || | -| |+-----------------------------+| | -+---------------------------+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`IBOutletCollection properties should be copy/strong and not assign`| -+---------------------------------------------------------------------------------------------------------+ - - --Winvalid-initializer-from-system-header ----------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid constructor form class in system header, should not be explicit`| -+--------------------------------------------------------------------------------------------------------------+ - - --Winvalid-ios-deployment-target -------------------------------- -This diagnostic is an error by default, but the flag ``-Wno-invalid-ios-deployment-target`` can be used to disable the error. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`invalid iOS deployment version '`:placeholder:`A`:diagtext:`', iOS 10 is the maximum deployment target for 32-bit targets`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winvalid-no-builtin-names --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid builtin name for` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Winvalid-noreturn ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function declared 'noreturn' should not return`| -+-------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared 'noreturn' should not return`| -+--------------------------------------------------------------------------------------------------------------------------------+ - - --Winvalid-offsetof ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`offset of on non-POD type` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`offset of on non-standard-layout type` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------------------------+ - - --Winvalid-or-nonexistent-directory ----------------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`environment variable SCE\_ORBIS\_SDK\_DIR is set, but points to invalid or nonexistent directory '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unable to find` |nbsp| :placeholder:`A` |nbsp| :diagtext:`directory, expected to be in '`:placeholder:`B`:diagtext:`'`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Winvalid-partial-specialization --------------------------------- -This diagnostic is an error by default, but the flag ``-Wno-invalid-partial-specialization`` can be used to disable the error. - -**Diagnostic text:** - -+-----------------------+----------------------+-----------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| |+--------------------+| |nbsp| :diagtext:`template partial specialization is not more specialized than the primary template`| -| ||:diagtext:`class` || | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+-----------------------+----------------------+-----------------------------------------------------------------------------------------------------+ - - --Winvalid-pch -------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Winvalid-pp-token ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty character constant`| -+---------------------------------------------------------------+ - -+------------------------------------------------------------------+-----------------+-----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing terminating` |nbsp| |+---------------+| |nbsp| :diagtext:`character`| -| ||:diagtext:`'` || | -| |+---------------+| | -| ||:diagtext:`'"'`|| | -| |+---------------+| | -+------------------------------------------------------------------+-----------------+-----------------------------+ - - --Winvalid-source-encoding -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`illegal character encoding in character literal`| -+--------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`illegal character encoding in string literal`| -+-----------------------------------------------------------------------------------+ - - --Winvalid-token-paste ---------------------- -This diagnostic is an error by default, but the flag ``-Wno-invalid-token-paste`` can be used to disable the error. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`pasting formed '`:placeholder:`A`:diagtext:`', an invalid preprocessing token`| -+----------------------------------------------------------------------------------------------------------------+ - - --Wjump-seh-finally ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`jump out of \_\_finally block has undefined behavior`| -+-------------------------------------------------------------------------------------------+ - - --Wkeyword-compat ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`keyword '`:placeholder:`A`:diagtext:`' will be made available as an identifier` |nbsp| |+-----------------------------------------------------+| -| ||:diagtext:`here` || -| |+-----------------------------------------------------+| -| ||:diagtext:`for the remainder of the translation unit`|| -| |+-----------------------------------------------------+| -+-----------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------+ - - --Wkeyword-macro ---------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`keyword is hidden by macro definition`| -+----------------------------------------------------------------------------+ - - --Wknr-promoted-parameter ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`promoted type of K&R function parameter is not compatible with parameter type` |nbsp| :diagtext:`declared in a previous prototype`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wlanguage-extension-token --------------------------- -**Diagnostic text:** - -+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extension used`| -+-----------------------------------------------------+ - - --Wlarge-by-value-copy ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a large (`:placeholder:`B` |nbsp| :diagtext:`bytes) pass-by-value argument; pass it by reference instead ?`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`return value of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a large (`:placeholder:`B` |nbsp| :diagtext:`bytes) pass-by-value object; pass it by reference instead ?`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wliblto --------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wliteral-conversion --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion of out of range value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is undefined`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wliteral-range ---------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`magnitude of floating-point constant too large for type` |nbsp| :placeholder:`A`:diagtext:`; maximum is` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`magnitude of floating-point constant too small for type` |nbsp| :placeholder:`A`:diagtext:`; minimum is` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wlocal-type-template-args --------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++98-compat-local-type-template-args`_. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template argument uses local type` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------------------------+ - - --Wlogical-not-parentheses -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------+------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`logical not is only applied to the left hand side of this` |nbsp| |+----------------------------+| -| ||:diagtext:`comparison` || -| |+----------------------------+| -| ||:diagtext:`bitwise operator`|| -| |+----------------------------+| -+--------------------------------------------------------------------------------------------------------+------------------------------+ - - --Wlogical-op-parentheses ------------------------- -**Diagnostic text:** - -+---------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'&&' within '\|\|'`| -+---------------------------------------------------------+ - - --Wlong-long ------------ -Also controls `-Wc++11-long-long`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'long long' is an extension when C99 mode is not enabled`| -+-----------------------------------------------------------------------------------------------+ - - --Wloop-analysis ---------------- -Controls `-Wfor-loop-analysis`_, `-Wrange-loop-analysis`_. - - --Wmacro-redefined ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`macro redefined`| -+------------------------------------------------------------------------------+ - - --Wmain ------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ does not allow 'main' to be used by a program`| -+--------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'main' is not allowed to be declared \_Noreturn`| -+--------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'main' is not allowed to be declared variadic`| -+------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`only one parameter on 'main' declaration`| -+-------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable named 'main' with external linkage has undefined behavior`| -+---------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`bool literal returned from 'main'`| -+------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'main' should not be declared static`| -+---------------------------------------------------------------------------+ - - --Wmain-return-type ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`return type of 'main' is not 'int'`| -+-------------------------------------------------------------------------+ - - --Wmalformed-warning-check -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\_\_has\_warning expected option name (e.g. "-Wundef")`| -+---------------------------------------------------------------------------------------------+ - - --Wmany-braces-around-scalar-init --------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------+----------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`too many braces around` |nbsp| |+--------------------------+|:diagtext:`initializer`| -| ||:diagtext:`scalar` |nbsp| || | -| |+--------------------------+| | -| || || | -| |+--------------------------+| | -+---------------------------------------------------------------------+----------------------------+-----------------------+ - - --Wmax-tokens ------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the number of preprocessor source tokens (`:placeholder:`A`:diagtext:`) exceeds this token limit (`:placeholder:`B`:diagtext:`)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the total number of preprocessor source tokens (`:placeholder:`A`:diagtext:`) exceeds the token limit (`:placeholder:`B`:diagtext:`)`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - -The warning is issued if the number of pre-processor tokens exceeds -the token limit, which can be set in three ways: - -1. As a limit at a specific point in a file, using the ``clang max_tokens_here`` - pragma: - - .. code-block: c++ - #pragma clang max_tokens_here 1234 - -2. As a per-translation unit limit, using the ``-fmax-tokens=`` command-line - flag: - - .. code-block: console - clang -c a.cpp -fmax-tokens=1234 - -3. As a per-translation unit limit using the ``clang max_tokens_total`` pragma, - which works like and overrides the ``-fmax-tokens=`` flag: - - .. code-block: c++ - #pragma clang max_tokens_total 1234 - -These limits can be helpful in limiting code growth through included files. - -Setting a token limit of zero means no limit. - --Wmax-unsigned-zero -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------+---------------------------------------+------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`taking the max of` |nbsp| |+-------------------------------------+| |nbsp| :diagtext:`is always equal to the other value`| -| ||:diagtext:`a value and unsigned zero`|| | -| |+-------------------------------------+| | -| ||:diagtext:`unsigned zero and a value`|| | -| |+-------------------------------------+| | -+----------------------------------------------------------------+---------------------------------------+------------------------------------------------------+ - - --Wmemset-transposed-args ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+-----------------------------------------------------+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------------------------------------+|:diagtext:`; did you mean to transpose the last two arguments?`| -| ||:diagtext:`'size' argument to memset is '0'` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`setting buffer to a 'sizeof' expression`|| | -| |+---------------------------------------------------+| | -+---------------------------+-----------------------------------------------------+---------------------------------------------------------------+ - - --Wmemsize-comparison --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`size argument in` |nbsp| :placeholder:`A` |nbsp| :diagtext:`call is a comparison`| -+-----------------------------------------------------------------------------------------------------------------------+ - - --Wmethod-signatures -------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting parameter types in implementation of` |nbsp| :placeholder:`A`:diagtext:`:` |nbsp| :placeholder:`B` |nbsp| :diagtext:`vs` |nbsp| :placeholder:`C`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting return type in implementation of` |nbsp| :placeholder:`A`:diagtext:`:` |nbsp| :placeholder:`B` |nbsp| :diagtext:`vs` |nbsp| :placeholder:`C`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft ------------ -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Winconsistent-dllimport`_, `-Wmicrosoft-anon-tag`_, `-Wmicrosoft-cast`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-const-init`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-default-arg-redefinition`_, `-Wmicrosoft-drectve-section`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-forward-reference`_, `-Wmicrosoft-enum-value`_, `-Wmicrosoft-exception-spec`_, `-Wmicrosoft-explicit-constructor-call`_, `-Wmicrosoft-extra-qualification`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-goto`_, `-Wmicrosoft-include`_, `-Wmicrosoft-mutable-reference`_, `-Wmicrosoft-pure-definition`_, `-Wmicrosoft-redeclare-static`_, `-Wmicrosoft-sealed`_, `-Wmicrosoft-template`_, `-Wmicrosoft-union-member-reference`_, `-Wmicrosoft-unqualified-friend`_, `-Wmicrosoft-using-decl`_, `-Wmicrosoft-void-pseudo-dtor`_. - - --Wmicrosoft-anon-tag --------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------+--------------------+---------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`types declared in an anonymous` |nbsp| |+------------------+| |nbsp| :diagtext:`are a Microsoft extension`| -| ||:diagtext:`struct`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -+-----------------------------------------------------------------------------+--------------------+---------------------------------------------+ - -+--------------------------------------------------------+---------------------+---------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`anonymous` |nbsp| |+-------------------+| |nbsp| :diagtext:`are a Microsoft extension`| -| ||:diagtext:`structs`|| | -| |+-------------------+| | -| ||:diagtext:`unions` || | -| |+-------------------+| | -+--------------------------------------------------------+---------------------+---------------------------------------------+ - - --Wmicrosoft-cast ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static\_cast between pointer-to-function and pointer-to-object is a Microsoft extension`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-charize -------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`charizing operator #@ is a Microsoft extension`| -+-------------------------------------------------------------------------------------+ - - --Wmicrosoft-comment-paste -------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pasting two '/' tokens into a '//' comment is a Microsoft extension`| -+----------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-const-init ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default initialization of an object of const type` |nbsp| :placeholder:`A`|+---------------------------------------------------------------+| |nbsp| :diagtext:`is a Microsoft extension`| -| || || | -| |+---------------------------------------------------------------+| | -| || |nbsp| :diagtext:`without a user-provided default constructor`|| | -| |+---------------------------------------------------------------+| | -+----------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+--------------------------------------------+ - - --Wmicrosoft-cpp-macro ---------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C++ operator` |nbsp| :placeholder:`A` |nbsp| :diagtext:`(aka` |nbsp| :placeholder:`B`:diagtext:`) used as a macro name`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-default-arg-redefinition ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redefinition of default argument`| -+-----------------------------------------------------------------------+ - - --Wmicrosoft-drectve-section ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma` |nbsp| :placeholder:`A`:diagtext:`(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-end-of-file ------------------------ -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`treating Ctrl-Z as end-of-file is a Microsoft extension`| -+----------------------------------------------------------------------------------------------+ - - --Wmicrosoft-enum-forward-reference ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`forward references to 'enum' types are a Microsoft extension`| -+---------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-enum-value ----------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumerator value is not representable in the underlying type` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-exception-spec --------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`exception specification of '...' is a Microsoft extension`| -+------------------------------------------------------------------------------------------------+ - -+---------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------+|:diagtext:`incomplete type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is not allowed in exception specification`| -| || || | -| |+--------------------------------+| | -| ||:diagtext:`pointer to` |nbsp| || | -| |+--------------------------------+| | -| ||:diagtext:`reference to` |nbsp| || | -| |+--------------------------------+| | -+---------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`exception specification in declaration does not match previous declaration`| -+-----------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`exception specification in explicit instantiation does not match instantiated one`| -+------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is missing exception specification '`:placeholder:`B`:diagtext:`'`| -+--------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`exception specification of overriding function is more lax than base version`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-exists ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------+---------------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dependent` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`declarations are ignored`| -| ||:diagtext:`\_\_if\_not\_exists`|| | -| |+-------------------------------+| | -| ||:diagtext:`\_\_if\_exists` || | -| |+-------------------------------+| | -+--------------------------------------------------------+---------------------------------+--------------------------------------------+ - - --Wmicrosoft-explicit-constructor-call -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit constructor calls are a Microsoft extension`| -+-------------------------------------------------------------------------------------------+ - - --Wmicrosoft-extra-qualification -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra qualification on member` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------+ - - --Wmicrosoft-fixed-enum ----------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are a Microsoft extension`| -+---------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-flexible-array --------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------+-----------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flexible array member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in otherwise empty` |nbsp| |+---------------------+| |nbsp| :diagtext:`is a Microsoft extension`| -| ||:diagtext:`struct` || | -| |+---------------------+| | -| ||:diagtext:`interface`|| | -| |+---------------------+| | -| ||:diagtext:`union` || | -| |+---------------------+| | -| ||:diagtext:`class` || | -| |+---------------------+| | -| ||:diagtext:`enum` || | -| |+---------------------+| | -+----------------------------------------------------------------------------------------------------------------------------------+-----------------------+--------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flexible array member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in a union is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-goto ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`jump from this goto statement to its label is a Microsoft extension`| -+----------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-inaccessible-base ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`accessing inaccessible direct base` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-include -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#include resolved using non-portable Microsoft search rules as:` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-mutable-reference ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'mutable' on a reference type is a Microsoft extension`| -+---------------------------------------------------------------------------------------------+ - - --Wmicrosoft-pure-definition ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function definition with pure-specifier is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-redeclare-static ----------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redeclaring non-static` |nbsp| :placeholder:`A` |nbsp| :diagtext:`as static is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-sealed ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'sealed' keyword is a Microsoft extension`| -+--------------------------------------------------------------------------------+ - - --Wmicrosoft-template --------------------- -This diagnostic is enabled by default. - -Also controls `-Wmicrosoft-template-shadow`_. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate explicit instantiation of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored as a Microsoft extension`| -+------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of identifier` |nbsp| :placeholder:`A` |nbsp| :diagtext:`found via unqualified lookup into dependent bases of class templates is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using the undeclared type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`as a default template argument is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template argument containing a dereference operation is a Microsoft extension`| -+-----------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+---------------------------------------+-----------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------------------+| |nbsp| :diagtext:`specialization of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not in` |nbsp| |+----------------------------------------------------------------------------------------+| |nbsp| :diagtext:`is a Microsoft extension`| -| ||:diagtext:`class template` || ||+---------------------------------------------------------+ || | -| |+-------------------------------------+| |||:diagtext:`a namespace enclosing` |nbsp| :placeholder:`C`| || | -| ||:diagtext:`class template partial` || ||+---------------------------------------------------------+ || | -| |+-------------------------------------+| |+----------------------------------------------------------------------------------------+| | -| ||:diagtext:`variable template` || ||+--------------------------------------------------------------------------------------+|| | -| |+-------------------------------------+| |||:diagtext:`class` |nbsp| :placeholder:`C` |nbsp| :diagtext:`or an enclosing namespace`||| | -| ||:diagtext:`variable template partial`|| ||+--------------------------------------------------------------------------------------+|| | -| |+-------------------------------------+| |+----------------------------------------------------------------------------------------+| | -| ||:diagtext:`function template` || | | | -| |+-------------------------------------+| | | | -| ||:diagtext:`member function` || | | | -| |+-------------------------------------+| | | | -| ||:diagtext:`static data member` || | | | -| |+-------------------------------------+| | | | -| ||:diagtext:`member class` || | | | -| |+-------------------------------------+| | | | -| ||:diagtext:`member enumeration` || | | | -| |+-------------------------------------+| | | | -+---------------------------+---------------------------------------+-----------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+--------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template argument for template type parameter must be a type; omitted 'typename' is a Microsoft extension`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'static' can only be specified inside the class definition`| -+-------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of undeclared identifier` |nbsp| :placeholder:`A`:diagtext:`; unqualified lookup into dependent bases of class template` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is a Microsoft extension`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-template-shadow ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`shadows template parameter`| -+---------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-union-member-reference ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`union member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has reference type` |nbsp| :placeholder:`B`:diagtext:`, which is a Microsoft extension`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-unqualified-friend ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unqualified friend declaration referring to type outside of the nearest enclosing namespace is a Microsoft extension; add a nested name specifier`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-using-decl ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using declaration referring to inaccessible member '`:placeholder:`A`:diagtext:`' (which refers to accessible member '`:placeholder:`B`:diagtext:`') is a Microsoft compatibility extension`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmicrosoft-void-pseudo-dtor ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pseudo-destructors on type void are a Microsoft extension`| -+------------------------------------------------------------------------------------------------+ - - --Wmisleading-indentation ------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------+-------------------+-------------+ -|:warning:`warning:` |nbsp| :diagtext:`misleading indentation; statement is not part of the previous '`|+-----------------+|:diagtext:`'`| -| ||:diagtext:`if` || | -| |+-----------------+| | -| ||:diagtext:`else` || | -| |+-----------------+| | -| ||:diagtext:`for` || | -| |+-----------------+| | -| ||:diagtext:`while`|| | -| |+-----------------+| | -+------------------------------------------------------------------------------------------------------+-------------------+-------------+ - - --Wmismatched-new-delete ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------+------------------+---------------------------------------------------------------+------------------+-----------------------------------+------------------+--------------+ -|:warning:`warning:` |nbsp| :diagtext:`'delete`|+----------------+|:diagtext:`' applied to a pointer that was allocated with 'new`|+----------------+|:diagtext:`'; did you mean 'delete`|+----------------+|:diagtext:`'?`| -| || || ||:diagtext:`\[\]`|| ||:diagtext:`\[\]`|| | -| |+----------------+| |+----------------+| |+----------------+| | -| ||:diagtext:`\[\]`|| || || || || | -| |+----------------+| |+----------------+| |+----------------+| | -+----------------------------------------------+------------------+---------------------------------------------------------------+------------------+-----------------------------------+------------------+--------------+ - - --Wmismatched-parameter-types ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting parameter types in implementation of` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------+ - - --Wmismatched-return-types -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting return type in implementation of` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wmismatched-tags ------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------------------+--------------------------+------------------------------+-----------------------------------------------------------+--------------------------+------------------------------+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`C` |nbsp| :diagtext:`defined as` |nbsp| |+------------------------+|+----------------------------+| |nbsp| :diagtext:`here but previously declared as` |nbsp| |+------------------------+|+----------------------------+|:diagtext:`; this is valid, but may result in linker errors under the Microsoft C++ ABI`| -| ||:diagtext:`a struct` ||| || ||:diagtext:`a struct` ||| || | -| |+------------------------+|+----------------------------+| |+------------------------+|+----------------------------+| | -| ||:diagtext:`an interface`||| |nbsp| :diagtext:`template`|| ||:diagtext:`an interface`||| |nbsp| :diagtext:`template`|| | -| |+------------------------+|+----------------------------+| |+------------------------+|+----------------------------+| | -| ||:diagtext:`a class` || | ||:diagtext:`a class` || | | -| |+------------------------+| | |+------------------------+| | | -+---------------------------------------------------------------------------------+--------------------------+------------------------------+-----------------------------------------------------------+--------------------------+------------------------------+----------------------------------------------------------------------------------------+ - -+---------------------------+-----------------------+------------------------------+--------------------------------------------------------------------------------+-----------------------+------------------------------+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------+|+----------------------------+| |nbsp| :placeholder:`C` |nbsp| :diagtext:`was previously declared as a` |nbsp| |+---------------------+|+----------------------------+|:diagtext:`; this is valid, but may result in linker errors under the Microsoft C++ ABI`| -| ||:diagtext:`struct` ||| || ||:diagtext:`struct` ||| || | -| |+---------------------+|+----------------------------+| |+---------------------+|+----------------------------+| | -| ||:diagtext:`interface`||| |nbsp| :diagtext:`template`|| ||:diagtext:`interface`||| |nbsp| :diagtext:`template`|| | -| |+---------------------+|+----------------------------+| |+---------------------+|+----------------------------+| | -| ||:diagtext:`class` || | ||:diagtext:`class` || | | -| |+---------------------+| | |+---------------------+| | | -+---------------------------+-----------------------+------------------------------+--------------------------------------------------------------------------------+-----------------------+------------------------------+----------------------------------------------------------------------------------------+ - - --Wmissing-braces ----------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`suggest braces around initialization of subobject`| -+----------------------------------------------------------------------------------------+ - - --Wmissing-constinit -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'constinit' specifier missing on initializing declaration of` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------------------+ - - --Wmissing-declarations ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration does not declare anything`| -+----------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not permitted on a declaration of a type`| -+-----------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`typedef requires a name`| -+--------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' ignored on this declaration`| -+-------------------------------------------------------------------------------------------------+ - - --Wmissing-exception-spec ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is missing exception specification '`:placeholder:`B`:diagtext:`'`| -+--------------------------------------------------------------------------------------------------------------------------------+ - - --Wmissing-field-initializers ----------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`initializer`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wmissing-format-attribute --------------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wmissing-include-dirs ----------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wmissing-method-return-type ----------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`method has no return type specified; defaults to 'id'`| -+--------------------------------------------------------------------------------------------+ - - --Wmissing-noescape ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parameter of overriding method should be annotated with \_\_attribute\_\_((noescape))`| -+----------------------------------------------------------------------------------------------------------------------------+ - - --Wmissing-noreturn ------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`block could be declared with attribute 'noreturn'`| -+----------------------------------------------------------------------------------------+ - -+---------------------------+----------------------+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`could be declared with attribute 'noreturn'`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`method` || | -| |+--------------------+| | -+---------------------------+----------------------+---------------------------------------------------------------------------------------+ - - --Wmissing-prototype-for-cc --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function with no prototype cannot use the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`calling convention`| -+----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmissing-prototypes --------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no previous prototype for function` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------+ - - --Wmissing-selector-name ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`used as the name of the previous parameter rather than as part of the selector`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmissing-sysroot ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no such sysroot directory: '`:placeholder:`A`:diagtext:`'`| -+------------------------------------------------------------------------------------------------+ - - --Wmissing-variable-declarations -------------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no previous extern declaration for non-static variable` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------------+ - - --Rmodule-build --------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------+ -|:remark:`remark:` |nbsp| :diagtext:`building module '`:placeholder:`A`:diagtext:`' as '`:placeholder:`B`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------+ -|:remark:`remark:` |nbsp| :diagtext:`finished building module '`:placeholder:`A`:diagtext:`'`| -+--------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:remark:`remark:` |nbsp| :diagtext:`could not acquire lock file for module '`:placeholder:`A`:diagtext:`':` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:remark:`remark:` |nbsp| :diagtext:`timed out waiting to acquire lock file for module '`:placeholder:`A`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------------+ - - --Wmodule-conflict ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`module '`:placeholder:`A`:diagtext:`' conflicts with already-imported module '`:placeholder:`B`:diagtext:`':` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`module file '`:placeholder:`A`:diagtext:`' was validated as a system module and is now being imported as a non-system module; any difference in diagnostic options will be ignored`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmodule-file-config-mismatch ------------------------------ -This diagnostic is an error by default, but the flag ``-Wno-module-file-config-mismatch`` can be used to disable the error. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`module file` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot be loaded due to a configuration mismatch with the current compilation`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmodule-file-extension ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate module file extension block name '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------------------+ - - --Rmodule-import ---------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------+-----------------------------------------------------------+-------------------------------------------------------+ -|:remark:`remark:` |nbsp| :diagtext:`importing module '`:placeholder:`A`:diagtext:`'`|+---------------------------------------------------------+| |nbsp| :diagtext:`from '`:placeholder:`B`:diagtext:`'`| -| || || | -| |+---------------------------------------------------------+| | -| ||+-------------------------------------------------------+|| | -| ||| |nbsp| :diagtext:`into '`:placeholder:`D`:diagtext:`'`||| | -| ||+-------------------------------------------------------+|| | -| |+---------------------------------------------------------+| | -+------------------------------------------------------------------------------------+-----------------------------------------------------------+-------------------------------------------------------+ - - --Wmodule-import-in-extern-c ---------------------------- -This diagnostic is an error by default, but the flag ``-Wno-module-import-in-extern-c`` can be used to disable the error. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`import of C++ module '`:placeholder:`A`:diagtext:`' appears within extern "C" language linkage specification`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmodules-ambiguous-internal-linkage ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ambiguous use of internal linkage declaration` |nbsp| :placeholder:`A` |nbsp| :diagtext:`defined in multiple modules`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmodules-import-nested-redundant ---------------------------------- -This diagnostic is an error by default, but the flag ``-Wno-modules-import-nested-redundant`` can be used to disable the error. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`redundant #include of module '`:placeholder:`A`:diagtext:`' appears within` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmost ------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-non-virtual-dtor`_, `-Wextern-c-compat`_, `-Wfor-loop-analysis`_, `-Wformat`_, `-Wframe-address`_, `-Wimplicit`_, `-Winfinite-recursion`_, `-Wint-in-bool-context`_, `-Wmismatched-tags`_, `-Wmissing-braces`_, `-Wmove`_, `-Wmultichar`_, `-Wobjc-designated-initializers`_, `-Wobjc-flexible-array`_, `-Wobjc-missing-super-calls`_, `-Woverloaded-virtual`_, `-Wprivate-extern`_, `-Wrange-loop-construct`_, `-Wreorder`_, `-Wreturn-type`_, `-Wself-assign`_, `-Wself-move`_, `-Wsizeof-array-argument`_, `-Wsizeof-array-decay`_, `-Wstring-plus-int`_, `-Wtautological-compare`_, `-Wtrigraphs`_, `-Wuninitialized`_, `-Wunknown-pragmas`_, `-Wunused`_, `-Wuser-defined-warnings`_, `-Wvolatile-register-var`_. - - --Wmove ------- -Controls `-Wpessimizing-move`_, `-Wredundant-move`_, `-Wreturn-std-move`_, `-Wself-move`_. - - --Wmsvc-include --------------- -Synonym for `-Wmicrosoft-include`_. - - --Wmsvc-not-found ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unable to find a Visual Studio installation; try running Clang from a developer command prompt`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - - --Wmultichar ------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multi-character character constant`| -+-------------------------------------------------------------------------+ - - --Wmultiple-move-vbase ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`defaulted move assignment operator of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will move assign virtual base class` |nbsp| :placeholder:`B` |nbsp| :diagtext:`multiple times`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wnarrowing ------------ -Synonym for `-Wc++11-narrowing`_. - - --Wnested-anon-types -------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------+--------------------+------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`anonymous types declared in an anonymous` |nbsp| |+------------------+| |nbsp| :diagtext:`are an extension`| -| ||:diagtext:`struct`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -+---------------------------------------------------------------------------------------+--------------------+------------------------------------+ - - --Wnested-externs ----------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wnew-returns-null ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`should not return a null pointer unless it is declared 'throw()'`|+---------------------------------+| -| || || -| |+---------------------------------+| -| || |nbsp| :diagtext:`or 'noexcept'`|| -| |+---------------------------------+| -+-------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+ - - --Wnewline-eof -------------- -**Diagnostic text:** - -+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no newline at end of file`| -+----------------------------------------------------------------+ - -+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no newline at end of file`| -+----------------------------------------------------------------+ - - --Wnoderef ---------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dereferencing` |nbsp| :placeholder:`A`:diagtext:`; was declared with a 'noderef' type`| -+----------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dereferencing expression marked as 'noderef'`| -+-----------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`casting to dereferenceable pointer removes 'noderef' attribute`| -+-----------------------------------------------------------------------------------------------------+ - - --Wnoexcept-type ---------------- -Synonym for `-Wc++17-compat-mangling`_. - - --Wnon-c-typedef-for-linkage ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------+---------------------+----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`anonymous non-C-compatible type given name for linkage purposes by` |nbsp| |+-------------------+| |nbsp| :diagtext:`declaration; add a tag name here`| -| ||:diagtext:`typedef`|| | -| |+-------------------+| | -| ||:diagtext:`alias` || | -| |+-------------------+| | -+-----------------------------------------------------------------------------------------------------------------+---------------------+----------------------------------------------------+ - - --Wnon-gcc ---------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wconversion`_, `-Wliteral-range`_, `-Wsign-compare`_. - - --Wnon-literal-null-conversion ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression which evaluates to zero treated as a null pointer constant of type` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wnon-modular-include-in-framework-module ------------------------------------------ -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`include of non-modular header inside framework module '`:placeholder:`A`:diagtext:`': '`:placeholder:`B`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wnon-modular-include-in-module -------------------------------- -Also controls `-Wnon-modular-include-in-framework-module`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`include of non-modular header inside module '`:placeholder:`A`:diagtext:`': '`:placeholder:`B`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wnon-pod-varargs ------------------ -This diagnostic is an error by default, but the flag ``-Wno-non-pod-varargs`` can be used to disable the error. - -**Diagnostic text:** - -+----------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------+-------------------------+----------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`cannot pass object of` |nbsp| |+-----------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`through variadic` |nbsp| |+-----------------------+|:diagtext:`; call will abort at runtime`| -| ||:diagtext:`non-POD` || ||:diagtext:`function` || | -| |+-----------------------+| |+-----------------------+| | -| ||:diagtext:`non-trivial`|| ||:diagtext:`block` || | -| |+-----------------------+| |+-----------------------+| | -| | | ||:diagtext:`method` || | -| | | |+-----------------------+| | -| | | ||:diagtext:`constructor`|| | -| | | |+-----------------------+| | -+----------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------+-------------------------+----------------------------------------+ - -+------------------------------------------------------+-------------------------+-------------------------------------------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`cannot pass` |nbsp| |+-----------------------+| |nbsp| :diagtext:`object of type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to variadic` |nbsp| |+-----------------------+|:diagtext:`; expected type from format string was` |nbsp| :placeholder:`D`| -| ||:diagtext:`non-POD` || ||:diagtext:`function` || | -| |+-----------------------+| |+-----------------------+| | -| ||:diagtext:`non-trivial`|| ||:diagtext:`block` || | -| |+-----------------------+| |+-----------------------+| | -| | | ||:diagtext:`method` || | -| | | |+-----------------------+| | -| | | ||:diagtext:`constructor`|| | -| | | |+-----------------------+| | -+------------------------------------------------------+-------------------------+-------------------------------------------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`second argument to 'va\_arg' is of non-POD type` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`second argument to 'va\_arg' is of ARC ownership-qualified type` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------------------------------+ - - --Wnon-power-of-two-alignment ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`requested alignment is not a power of 2`| -+------------------------------------------------------------------------------+ - - --Wnon-virtual-dtor ------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has virtual functions but non-virtual destructor`| -+---------------------------------------------------------------------------------------------------------------+ - - --Wnonnull ---------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`null passed to a callee that requires a non-null argument`| -+------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------+----------------------+---------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`null returned from` |nbsp| |+--------------------+| |nbsp| :diagtext:`that requires a non-null return value`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`method` || | -| |+--------------------+| | -+-----------------------------------------------------------------+----------------------+---------------------------------------------------------+ - - --Wnonportable-cfstrings ------------------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wnonportable-include-path --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-portable path to file '`:placeholder:`A`:diagtext:`'; specified path differs in case from file name on disk`| -+------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wnonportable-system-include-path ---------------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-portable path to file '`:placeholder:`A`:diagtext:`'; specified path differs in case from file name on disk`| -+------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wnonportable-vector-initialization ------------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`vector initializers are not compatible with NEON intrinsics in big endian mode`| -+---------------------------------------------------------------------------------------------------------------------+ - - --Wnontrivial-memaccess ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------+ -|:warning:`warning:` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`this` |nbsp| :placeholder:`B` |nbsp| :diagtext:`call is a pointer to record` |nbsp| :placeholder:`C` |nbsp| :diagtext:`that is not trivial to` |nbsp| |+----------------------------------------+| -| ||:diagtext:`destination for` || ||:diagtext:`primitive-default-initialize`|| -| |+-----------------------------+| |+----------------------------------------+| -| ||:diagtext:`source of` || ||:diagtext:`primitive-copy` || -| |+-----------------------------+| |+----------------------------------------+| -| ||:diagtext:`first operand of` || | | -| |+-----------------------------+| | | -| ||:diagtext:`second operand of`|| | | -| |+-----------------------------+| | | -+---------------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------+ - - --Wnsconsumed-mismatch ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overriding method has mismatched ns\_consumed attribute on its parameter`| -+---------------------------------------------------------------------------------------------------------------+ - - --Wnsreturns-mismatch --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+---------------------------+------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overriding method has mismatched ns\_returns\_`|+-------------------------+| |nbsp| :diagtext:`attributes`| -| ||:diagtext:`not\_retained`|| | -| |+-------------------------+| | -| ||:diagtext:`retained` || | -| |+-------------------------+| | -+-------------------------------------------------------------------------------------+---------------------------+------------------------------+ - - --Wnull-arithmetic ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of NULL in arithmetic operation`| -+--------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison between NULL and non-pointer` |nbsp| |+------------------------------------------------------------+| -| ||+----------------------------------------------------------+|| -| |||:diagtext:`(`:placeholder:`B` |nbsp| :diagtext:`and NULL)`||| -| ||+----------------------------------------------------------+|| -| |+------------------------------------------------------------+| -| ||+----------------------------------------------------------+|| -| |||:diagtext:`(NULL and` |nbsp| :placeholder:`B`:diagtext:`)`||| -| ||+----------------------------------------------------------+|| -| |+------------------------------------------------------------+| -+--------------------------------------------------------------------------------------+--------------------------------------------------------------+ - - --Wnull-character ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------+--------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`null character(s) preserved in` |nbsp| |+------------------+| |nbsp| :diagtext:`literal`| -| ||:diagtext:`char` || | -| |+------------------+| | -| ||:diagtext:`string`|| | -| |+------------------+| | -+-----------------------------------------------------------------------------+--------------------+---------------------------+ - -+-------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`null character ignored`| -+-------------------------------------------------------------+ - - --Wnull-conversion ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------+---------------------+-------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion of` |nbsp| |+-------------------+| |nbsp| :diagtext:`constant to` |nbsp| :placeholder:`B`| -| ||:diagtext:`NULL` || | -| |+-------------------+| | -| ||:diagtext:`nullptr`|| | -| |+-------------------+| | -+---------------------------------------------------------------------+---------------------+-------------------------------------------------------+ - - --Wnull-dereference ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`binding dereferenced null pointer to reference has undefined behavior`| -+------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`indirection of non-volatile null pointer will be deleted, not trap`| -+---------------------------------------------------------------------------------------------------------+ - - --Wnull-pointer-arithmetic -------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension`| -+--------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`performing pointer arithmetic on a null pointer has undefined behavior`|+--------------------------------------------+| -| || || -| |+--------------------------------------------+| -| || |nbsp| :diagtext:`if the offset is nonzero`|| -| |+--------------------------------------------+| -+-------------------------------------------------------------------------------------------------------------+----------------------------------------------+ - - --Wnullability -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting nullability specifier on parameter types,` |nbsp| :placeholder:`A` |nbsp| :diagtext:`conflicts with existing specifier` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting nullability specifier on return types,` |nbsp| :placeholder:`A` |nbsp| :diagtext:`conflicts with existing specifier` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nullability specifier` |nbsp| :placeholder:`A` |nbsp| :diagtext:`conflicts with existing specifier` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`synthesized setter` |nbsp| :placeholder:`A` |nbsp| :diagtext:`for null\_resettable property` |nbsp| :placeholder:`B` |nbsp| :diagtext:`does not handle nil`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate nullability specifier` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------------------+ - - --Wnullability-completeness --------------------------- -This diagnostic is enabled by default. - -Also controls `-Wnullability-completeness-on-arrays`_. - -**Diagnostic text:** - -+---------------------------+----------------------------+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------+| |nbsp| :diagtext:`is missing a nullability type specifier (\_Nonnull, \_Nullable, or \_Null\_unspecified)`| -| ||:diagtext:`pointer` || | -| |+--------------------------+| | -| ||:diagtext:`block pointer` || | -| |+--------------------------+| | -| ||:diagtext:`member pointer`|| | -| |+--------------------------+| | -+---------------------------+----------------------------+-----------------------------------------------------------------------------------------------------------+ - - --Wnullability-completeness-on-arrays ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array parameter is missing a nullability type specifier (\_Nonnull, \_Nullable, or \_Null\_unspecified)`| -+----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wnullability-declspec ----------------------- -This diagnostic is an error by default, but the flag ``-Wno-nullability-declspec`` can be used to disable the error. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------+-------------+ -|:error:`error:` |nbsp| :diagtext:`nullability specifier` |nbsp| :placeholder:`A` |nbsp| :diagtext:`cannot be applied to non-pointer type` |nbsp| :placeholder:`B`:diagtext:`; did you mean to apply the specifier to the` |nbsp| |+-----------------------------------+|:diagtext:`?`| -| ||:diagtext:`pointer` || | -| |+-----------------------------------+| | -| ||:diagtext:`block pointer` || | -| |+-----------------------------------+| | -| ||:diagtext:`member pointer` || | -| |+-----------------------------------+| | -| ||:diagtext:`function pointer` || | -| |+-----------------------------------+| | -| ||:diagtext:`member function pointer`|| | -| |+-----------------------------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------+-------------+ - - --Wnullability-extension ------------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type nullability specifier` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a Clang extension`| -+---------------------------------------------------------------------------------------------------------------------------------+ - - --Wnullability-inferred-on-nested-type -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+-----------------------+---------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inferring '\_Nonnull' for pointer type within` |nbsp| |+---------------------+| |nbsp| :diagtext:`is deprecated`| -| ||:diagtext:`array` || | -| |+---------------------+| | -| ||:diagtext:`reference`|| | -| |+---------------------+| | -+--------------------------------------------------------------------------------------------+-----------------------+---------------------------------+ - - --Wnullable-to-nonnull-conversion --------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from nullable pointer` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to non-nullable pointer type` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-autosynthesis-property-ivar-name-match ---------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------+-------------------------+---------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`autosynthesized property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will use` |nbsp| |+-----------------------+| |nbsp| :diagtext:`instance variable` |nbsp| :placeholder:`C`:diagtext:`, not existing instance variable` |nbsp| :placeholder:`D`| -| || || | -| |+-----------------------+| | -| ||:diagtext:`synthesized`|| | -| |+-----------------------+| | -+---------------------------------------------------------------------------------------------------------------------------+-------------------------+---------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-bool-constant-conversion -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from constant value` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to 'BOOL'; the only well defined values for 'BOOL' are YES and NO`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-boxing -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`string is ill-formed as UTF-8 and will become a null` |nbsp| :placeholder:`A` |nbsp| :diagtext:`when boxed`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-circular-container -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`adding` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`might cause circular dependency in container`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-cocoa-api ----------------- -Synonym for `-Wobjc-redundant-api-use`_. - - --Wobjc-designated-initializers ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`designated initializer missing a 'super' call to a designated initializer of the super class`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`designated initializer invoked a non-designated initializer`| -+--------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`designated initializer should only invoke a designated initializer on 'super'`| -+--------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`method override for the designated initializer of the superclass` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not found`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`convenience initializer missing a 'self' call to another initializer`| -+-----------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`convenience initializer should not invoke an initializer on 'super'`| -+----------------------------------------------------------------------------------------------------------+ - - --Wobjc-flexible-array ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`can overwrite instance variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`with variable sized type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`in superclass` |nbsp| :placeholder:`D`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with variable sized type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is not visible to subclasses and can conflict with their instance variables`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-forward-class-redefinition ---------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redefinition of forward class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of a typedef name of an object type is ignored`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-interface-ivars ----------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration of instance variables in the interface is deprecated`| -+-------------------------------------------------------------------------------------------------------+ - - --Wobjc-literal-compare ----------------------- -This diagnostic is enabled by default. - -Also controls `-Wobjc-string-compare`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------+----------------------------------+------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`direct comparison of` |nbsp| |+--------------------------------+| |nbsp| :diagtext:`has undefined behavior`| -| ||:diagtext:`an array literal` || | -| |+--------------------------------+| | -| ||:diagtext:`a dictionary literal`|| | -| |+--------------------------------+| | -| ||:diagtext:`a numeric literal` || | -| |+--------------------------------+| | -| ||:diagtext:`a boxed expression` || | -| |+--------------------------------+| | -| || || | -| |+--------------------------------+| | -+-------------------------------------------------------------------+----------------------------------+------------------------------------------+ - - --Wobjc-literal-conversion -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit boolean conversion of Objective-C object literal always evaluates to true`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`object of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not compatible with` |nbsp| |+---------------------------------+| |nbsp| :placeholder:`C`| -| ||:diagtext:`array element type` || | -| |+---------------------------------+| | -| ||:diagtext:`dictionary key type` || | -| |+---------------------------------+| | -| ||:diagtext:`dictionary value type`|| | -| |+---------------------------------+| | -+-------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+------------------------+ - - --Wobjc-macro-redefinition -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring redefinition of Objective-C qualifier macro`| -+-------------------------------------------------------------------------------------------+ - - --Wobjc-messaging-id -------------------- -**Diagnostic text:** - -+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`messaging unqualified id`| -+---------------------------------------------------------------+ - - --Wobjc-method-access --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not found (return type defaults to 'id')`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not found (return type defaults to 'id'); did you mean` |nbsp| :placeholder:`C`:diagtext:`?`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instance method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not found (return type defaults to 'id')`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instance method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not found (return type defaults to 'id'); did you mean` |nbsp| :placeholder:`C`:diagtext:`?`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instance method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`found instead of class method` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instance method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is being used on 'Class' which is not in the root class`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-missing-property-synthesis ---------------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`auto property synthesis is synthesizing property not explicitly synthesized`| -+------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-missing-super-calls --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`method possibly missing a \[super` |nbsp| :placeholder:`A`:diagtext:`\] call`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-multiple-method-names ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple methods named` |nbsp| :placeholder:`A` |nbsp| :diagtext:`found`| -+--------------------------------------------------------------------------------------------------------------+ - - --Wobjc-noncopy-retain-block-property ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`retain'ed block property does not copy the block - use copy attribute instead`| -+--------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-nonunified-exceptions ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cannot catch an exception thrown with @throw in C++ in the non-unified exception model`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-property-assign-on-object-type -------------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'assign' property of object type may become a dangling reference; consider using 'unsafe\_unretained'`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-property-implementation ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to be defined - use @dynamic or provide a method implementation in this class implementation`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to be defined - use @dynamic or provide a method implementation in this category`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to be defined - use @dynamic or provide a method implementation in this category`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-property-implicit-mismatch ---------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`primary property declaration is implicitly strong while redeclaration in class extension is weak`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-property-matches-cocoa-ownership-rule --------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property follows Cocoa naming convention for returning 'owned' objects`| -+-------------------------------------------------------------------------------------------------------------+ - - --Wobjc-property-no-attribute ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default property attribute 'assign' not appropriate for object`| -+-----------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed`| -+--------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-property-synthesis -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`auto property synthesis will not synthesize property` |nbsp| :placeholder:`A`:diagtext:`; it will be implemented by its superclass, use @dynamic to acknowledge intention`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`auto property synthesis will not synthesize property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`because it is 'readwrite' but it will be synthesized 'readonly' via another property`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`auto property synthesis will not synthesize property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`because it cannot share an ivar with another synthesized property`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-protocol-method-implementation -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`category is implementing a method which will also be implemented by its primary class`| -+----------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-protocol-property-synthesis ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`auto property synthesis will not synthesize property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared in protocol` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-protocol-qualifiers --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parameterized class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`already conforms to the protocols listed; did you forget a '\*'?`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-readonly-with-setter-property ------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`setter cannot be specified for a readonly property`| -+-----------------------------------------------------------------------------------------+ - - --Wobjc-redundant-api-use ------------------------- -Synonym for `-Wobjc-redundant-literal-use`_. - - --Wobjc-redundant-literal-use ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with a literal is redundant`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-root-class ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`defined without specifying a base class`| -+-------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-signed-char-bool ------------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wobjc-bool-constant-conversion`_, `-Wobjc-signed-char-bool-implicit-float-conversion`_, `-Wobjc-signed-char-bool-implicit-int-conversion`_, `-Wtautological-objc-bool-compare`_. - - --Wobjc-signed-char-bool-implicit-float-conversion -------------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from floating-point type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to 'BOOL'`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-signed-char-bool-implicit-int-conversion ------------------------------------------------ -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from integral type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to 'BOOL'`| -+----------------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-string-compare ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`direct comparison of a string literal has undefined behavior`| -+---------------------------------------------------------------------------------------------------+ - - --Wobjc-string-concatenation ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`concatenated NSString literal for an NSArray expression - possibly missing a comma`| -+-------------------------------------------------------------------------------------------------------------------------+ - - --Wobjc-unsafe-perform-selector ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+--------------------+------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is incompatible with selectors that return a` |nbsp| |+------------------+| |nbsp| :diagtext:`type`| -| ||:diagtext:`struct`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -| ||:diagtext:`vector`|| | -| |+------------------+| | -+-------------------------------------------------------------------------------------------------------------------+--------------------+------------------------+ - - --Wodr ------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template parameter lists have a different number of parameters (`:placeholder:`A` |nbsp| :diagtext:`vs` |nbsp| :placeholder:`B`:diagtext:`)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template parameter has different kinds in different translation units`| -+------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared with incompatible types in different translation units (`:placeholder:`B` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`C`:diagtext:`)`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`external function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared with incompatible types in different translation units (`:placeholder:`B` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`C`:diagtext:`)`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instance variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared with incompatible types in different translation units (`:placeholder:`B` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`C`:diagtext:`)`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template parameter declared with incompatible types in different translation units (`:placeholder:`A` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`B`:diagtext:`)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------+| |nbsp| :diagtext:`method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has a different number of parameters in different translation units (`:placeholder:`C` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`D`:diagtext:`)`| -| ||:diagtext:`class` || | -| |+--------------------+| | -| ||:diagtext:`instance`|| | -| |+--------------------+| | -+---------------------------+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------+| |nbsp| :diagtext:`method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has a parameter with a different types in different translation units (`:placeholder:`C` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`D`:diagtext:`)`| -| ||:diagtext:`class` || | -| |+--------------------+| | -| ||:diagtext:`instance`|| | -| |+--------------------+| | -+---------------------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------+| |nbsp| :diagtext:`method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has incompatible result types in different translation units (`:placeholder:`C` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`D`:diagtext:`)`| -| ||:diagtext:`class` || | -| |+--------------------+| | -| ||:diagtext:`instance`|| | -| |+--------------------+| | -+---------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------+| |nbsp| :diagtext:`method` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is variadic in one translation unit and not variadic in another`| -| ||:diagtext:`class` || | -| |+--------------------+| | -| ||:diagtext:`instance`|| | -| |+--------------------+| | -+---------------------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+-------------------------+--------------------------------------------------+-------------------------+-----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is implemented with` |nbsp| |+-----------------------+| |nbsp| :diagtext:`in one translation but` |nbsp| |+-----------------------+| |nbsp| :diagtext:`in another translation unit`| -| ||:diagtext:`@synthesize`|| ||:diagtext:`@dynamic` || | -| |+-----------------------+| |+-----------------------+| | -| ||:diagtext:`@dynamic` || ||:diagtext:`@synthesize`|| | -| |+-----------------------+| |+-----------------------+| | -+----------------------------------------------------------------------------------------------------------------------+-------------------------+--------------------------------------------------+-------------------------+-----------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared with incompatible types in different translation units (`:placeholder:`B` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`C`:diagtext:`)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has incompatible superclasses`| -+---------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is synthesized to different ivars in different translation units (`:placeholder:`B` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`C`:diagtext:`)`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------+-------------------+----------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parameter kind mismatch; parameter is` |nbsp| |+-----------------+| |nbsp| :diagtext:`parameter pack`| -| ||:diagtext:`not a`|| | -| |+-----------------+| | -| ||:diagtext:`a` || | -| |+-----------------+| | -+------------------------------------------------------------------------------------+-------------------+----------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has incompatible definitions in different translation units`| -+--------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`external variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`defined in multiple translation units`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`external variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared with incompatible types in different translation units (`:placeholder:`B` |nbsp| :diagtext:`vs.` |nbsp| :placeholder:`C`:diagtext:`)`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wold-style-cast ----------------- -**Diagnostic text:** - -+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of old-style cast`| -+------------------------------------------------------------+ - - --Wold-style-definition ----------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wopencl-unsupported-rgba -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`vector component name '`:placeholder:`A`:diagtext:`' is an OpenCL version 2.2 feature`| -+----------------------------------------------------------------------------------------------------------------------------+ - - --Wopenmp --------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wopenmp-clauses`_, `-Wopenmp-loop-form`_, `-Wopenmp-mapping`_, `-Wopenmp-target`_, `-Wsource-uses-openmp`_. - - --Wopenmp-clauses ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`aligned clause will be ignored because the requested alignment is not a power of 2`| -+-------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`allocator with the 'thread' trait access has unspecified behavior on '`:placeholder:`A`:diagtext:`' directive`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the context property '`:placeholder:`A`:diagtext:`' is not valid for the context selector '`:placeholder:`B`:diagtext:`' and the context set '`:placeholder:`C`:diagtext:`'; property ignored`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the context selector '`:placeholder:`A`:diagtext:`' in the context set '`:placeholder:`B`:diagtext:`' cannot have a score ('`:placeholder:`C`:diagtext:`'); score ignored`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the context selector '`:placeholder:`A`:diagtext:`' is not valid for the context set '`:placeholder:`B`:diagtext:`'; selector ignored`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the context selector '`:placeholder:`A`:diagtext:`' in context set '`:placeholder:`B`:diagtext:`' requires a context property defined in parentheses; selector ignored`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the context` |nbsp| |+--------------------+| |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' was used already in the same 'omp declare variant' directive;` |nbsp| |+--------------------+| |nbsp| :diagtext:`ignored`| -| ||:diagtext:`set` || ||:diagtext:`set` || | -| |+--------------------+| |+--------------------+| | -| ||:diagtext:`selector`|| ||:diagtext:`selector`|| | -| |+--------------------+| |+--------------------+| | -| ||:diagtext:`property`|| ||:diagtext:`property`|| | -| |+--------------------+| |+--------------------+| | -+----------------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid context property for the context selector '`:placeholder:`B`:diagtext:`' and the context set '`:placeholder:`C`:diagtext:`'; property ignored`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid context selector for the context set '`:placeholder:`B`:diagtext:`'; selector ignored`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid context set in a \`declare variant\`; set ignored`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected '`:placeholder:`A`:diagtext:`' after the` |nbsp| :placeholder:`B`:diagtext:`; '`:placeholder:`A`:diagtext:`' assumed`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+----------------------+---------------------+----------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected identifier or string literal describing a context` |nbsp| |+--------------------+|:diagtext:`;` |nbsp| |+--------------------+| |nbsp| :diagtext:`skipped`| -| ||:diagtext:`set` || ||:diagtext:`set` || | -| |+--------------------+| |+--------------------+| | -| ||:diagtext:`selector`|| ||:diagtext:`selector`|| | -| |+--------------------+| |+--------------------+| | -| ||:diagtext:`property`|| ||:diagtext:`property`|| | -| |+--------------------+| |+--------------------+| | -+---------------------------------------------------------------------------------------------------------+----------------------+---------------------+----------------------+---------------------------+ - -+---------------------------------------------------------------------------------+---------------------------------------------------+-------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`zero linear step (`:placeholder:`A` |nbsp| |+-------------------------------------------------+|:diagtext:`should probably be const)`| -| || || | -| |+-------------------------------------------------+| | -| ||:diagtext:`and other variables in clause` |nbsp| || | -| |+-------------------------------------------------+| | -+---------------------------------------------------------------------------------+---------------------------------------------------+-------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`more than one 'device\_type' clause is specified`| -+---------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`allocate directive specifies` |nbsp| |+--------------------------------------------+| |nbsp| :diagtext:`allocator while previously used` |nbsp| |+--------------------------------------------+| -| ||:diagtext:`default` || ||:diagtext:`default` || -| |+--------------------------------------------+| |+--------------------------------------------+| -| ||+------------------------------------------+|| ||+------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`B`:diagtext:`'`||| |||:diagtext:`'`:placeholder:`D`:diagtext:`'`||| -| ||+------------------------------------------+|| ||+------------------------------------------+|| -| |+--------------------------------------------+| |+--------------------------------------------+| -+---------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------+----------------------------------------------+ - - --Wopenmp-loop-form ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')`| -+-----------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed`| -+-----------------------------------------------------------------------------------------------------------------------------+ - - --Wopenmp-mapping ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not trivially copyable and not guaranteed to be mapped correctly`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wopenmp-target ---------------- -This diagnostic is enabled by default. - -Also controls `-Wopenmp-mapping`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`The OpenMP offloading target '`:placeholder:`A`:diagtext:`' is similar to target '`:placeholder:`B`:diagtext:`' already specified - will be ignored.`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`No library '`:placeholder:`A`:diagtext:`' found in the default clang lib directory or in LIBRARY\_PATH. Expect degraded performance due to no inlining of runtime functions on target devices.`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration marked as declare target after first use, it may lead to incorrect results`| -+-----------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration is not declared in any declare target region`| -+-----------------------------------------------------------------------------------------------+ - - --Woption-ignored ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`The '`:placeholder:`A`:diagtext:`' architecture does not support -moutline; flag ignored`| -+-------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`option '`:placeholder:`A`:diagtext:`' was ignored by the PS4 toolchain, using '-fPIC'`| -+----------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mlong-calls' option as it is not currently supported with` |nbsp| |+-----------------------------------------+|:diagtext:`-mabicalls`| -| || || | -| |+-----------------------------------------+| | -| ||:diagtext:`the implicit usage of` |nbsp| || | -| |+-----------------------------------------+| | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ - -+-----------------------------------------------------------------------------------------------------------------------+-------------------------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '`:placeholder:`A`:diagtext:`' option as it cannot be used with` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`-mabicalls and the N64 ABI`| -| ||:diagtext:`implicit usage of`|| | -| |+-----------------------------+| | -| || || | -| |+-----------------------------+| | -+-----------------------------------------------------------------------------------------------------------------------+-------------------------------+----------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64`| -+-----------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`auto-vectorization requires HVX, use -mhvx to enable it`| -+----------------------------------------------------------------------------------------------+ - - --Wordered-compare-function-pointers ------------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ordered comparison of function pointers (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`)`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wout-of-line-declaration -------------------------- -This diagnostic is an error by default, but the flag ``-Wno-out-of-line-declaration`` can be used to disable the error. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`out-of-line declaration of a member must be a definition`| -+-------------------------------------------------------------------------------------------+ - - --Wout-of-scope-function ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of out-of-scope declaration of` |nbsp| :placeholder:`A`|+-------------------------------------------------------------------------------------+| -| || || -| |+-------------------------------------------------------------------------------------+| -| || |nbsp| :diagtext:`whose type is not compatible with that of an implicit declaration`|| -| |+-------------------------------------------------------------------------------------+| -+-------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------+ - - --Wover-aligned --------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires` |nbsp| :placeholder:`B` |nbsp| :diagtext:`bytes of alignment and the default allocator only guarantees` |nbsp| :placeholder:`C` |nbsp| :diagtext:`bytes`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Woverflow ----------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Woverlength-strings --------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`string literal of length` |nbsp| :placeholder:`A` |nbsp| :diagtext:`exceeds maximum length` |nbsp| :placeholder:`B` |nbsp| :diagtext:`that` |nbsp| |+-------------------+| |nbsp| :diagtext:`compilers are required to support`| -| ||:diagtext:`C90` || | -| |+-------------------+| | -| ||:diagtext:`ISO C99`|| | -| |+-------------------+| | -| ||:diagtext:`C++` || | -| |+-------------------+| | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+-----------------------------------------------------+ - - --Woverloaded-shift-op-parentheses ---------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------+----------------+------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overloaded operator` |nbsp| |+--------------+| |nbsp| :diagtext:`has higher precedence than comparison operator`| -| ||:diagtext:`>>`|| | -| |+--------------+| | -| ||:diagtext:`<<`|| | -| |+--------------+| | -+------------------------------------------------------------------+----------------+------------------------------------------------------------------+ - - --Woverloaded-virtual --------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`hides overloaded virtual` |nbsp| |+---------------------+| -| ||:diagtext:`function` || -| |+---------------------+| -| ||:diagtext:`functions`|| -| |+---------------------+| -+-----------------------------------------------------------------------------------------------+-----------------------+ - - --Woverride-init ---------------- -Synonym for `-Winitializer-overrides`_. - - --Woverride-module ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overriding the module target triple with` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------+ - - --Woverriding-method-mismatch ----------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting distributed object modifiers on parameter type in declaration of` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting parameter types in declaration of` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting distributed object modifiers on return type in declaration of` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting return type in declaration of` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting variadic declaration of method and its implementation`| -+--------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting parameter types in declaration of` |nbsp| :placeholder:`A`:diagtext:`:` |nbsp| :placeholder:`B` |nbsp| :diagtext:`vs` |nbsp| :placeholder:`C`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`conflicting return type in declaration of` |nbsp| :placeholder:`A`:diagtext:`:` |nbsp| :placeholder:`B` |nbsp| :diagtext:`vs` |nbsp| :placeholder:`C`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Woverriding-t-option ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overriding '`:placeholder:`A`:diagtext:`' option with '`:placeholder:`B`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------------------+ - - --Wpacked --------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`packed attribute is unnecessary for` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------+ - - --Wpadded --------- -**Diagnostic text:** - -+------------------------------------------------------+-----------------------+--------------------------------------------------------------------------------+------------------+---------------+------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`padding` |nbsp| |+---------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`with` |nbsp| :placeholder:`C` |nbsp| |+----------------+|+-------------+| |nbsp| :diagtext:`to align anonymous bit-field`| -| ||:diagtext:`struct` || ||:diagtext:`byte`||| || | -| |+---------------------+| |+----------------+|+-------------+| | -| ||:diagtext:`interface`|| ||:diagtext:`bit` |||:diagtext:`s`|| | -| |+---------------------+| |+----------------+|+-------------+| | -| ||:diagtext:`class` || | | | | -| |+---------------------+| | | | | -+------------------------------------------------------+-----------------------+--------------------------------------------------------------------------------+------------------+---------------+------------------------------------------------+ - -+------------------------------------------------------+-----------------------+--------------------------------------------------------------------------------+------------------+---------------+----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`padding` |nbsp| |+---------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`with` |nbsp| :placeholder:`C` |nbsp| |+----------------+|+-------------+| |nbsp| :diagtext:`to align` |nbsp| :placeholder:`E`| -| ||:diagtext:`struct` || ||:diagtext:`byte`||| || | -| |+---------------------+| |+----------------+|+-------------+| | -| ||:diagtext:`interface`|| ||:diagtext:`bit` |||:diagtext:`s`|| | -| |+---------------------+| |+----------------+|+-------------+| | -| ||:diagtext:`class` || | | | | -| |+---------------------+| | | | | -+------------------------------------------------------+-----------------------+--------------------------------------------------------------------------------+------------------+---------------+----------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+------------------+---------------+-----------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`padding size of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with` |nbsp| :placeholder:`B` |nbsp| |+----------------+|+-------------+| |nbsp| :diagtext:`to alignment boundary`| -| ||:diagtext:`byte`||| || | -| |+----------------+|+-------------+| | -| ||:diagtext:`bit` |||:diagtext:`s`|| | -| |+----------------+|+-------------+| | -+--------------------------------------------------------------------------------------------------------------------------------------+------------------+---------------+-----------------------------------------+ - - --Wparentheses -------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wbitwise-conditional-parentheses`_, `-Wbitwise-op-parentheses`_, `-Wdangling-else`_, `-Wlogical-not-parentheses`_, `-Wlogical-op-parentheses`_, `-Woverloaded-shift-op-parentheses`_, `-Wparentheses-equality`_, `-Wshift-op-parentheses`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using the result of an assignment as a condition without parentheses`| -+-----------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has lower precedence than` |nbsp| :placeholder:`B`:diagtext:`;` |nbsp| :placeholder:`B` |nbsp| :diagtext:`will be evaluated first`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`operator '?:' has lower precedence than '`:placeholder:`A`:diagtext:`'; '`:placeholder:`A`:diagtext:`' will be evaluated first`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wparentheses-equality ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`equality comparison with extraneous parentheses`| -+--------------------------------------------------------------------------------------+ - - --Wpartial-availability ----------------------- -Synonym for `-Wunguarded-availability`_. - - --Rpass ------- -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --Rpass-analysis ---------------- -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:remark:`remark:` |nbsp| :placeholder:`A`:diagtext:`; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume\_safety)' before the loop or provide the '\_\_restrict\_\_' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied!`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:remark:`remark:` |nbsp| :placeholder:`A`:diagtext:`; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop or by providing the compiler option '-ffast-math'.`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpass-failed -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --Rpass-missed -------------- -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --Wpch-date-time ---------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+--------------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------+| |nbsp| :diagtext:`uses \_\_DATE\_\_ or \_\_TIME\_\_`| -| ||:diagtext:`precompiled header`|| | -| |+------------------------------+| | -| ||:diagtext:`module` || | -| |+------------------------------+| | -+---------------------------+--------------------------------+-----------------------------------------------------+ - - --Wpedantic ----------- -Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-literal`_, `-Wc++20-designator`_, `-Wc11-extensions`_, `-Wcomplex-component-init`_, `-Wdeclaration-after-statement`_, `-Wdollar-in-identifier-extension`_, `-Wembedded-directive`_, `-Wempty-translation-unit`_, `-Wfixed-enum-extension`_, `-Wflexible-array-extensions`_, `-Wfour-char-constants`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-union-cast`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wimport-preprocessor-directive-pedantic`_, `-Wkeyword-macro`_, `-Wlanguage-extension-token`_, `-Wlong-long`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-value`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-redeclare-static`_, `-Wnested-anon-types`_, `-Wnullability-extension`_, `-Woverlength-strings`_, `-Wretained-language-linkage`_, `-Wundefined-internal-type`_, `-Wvla-extension`_, `-Wzero-length-array`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate '`:placeholder:`A`:diagtext:`' declaration specifier`| -+-----------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'enable\_if' is a clang extension`| -+------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'diagnose\_if' is a clang extension`| -+--------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`designated initializers are a C99 feature`| -+--------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ does not allow 'main' to be used by a program`| -+--------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C++98 requires an accessible copy constructor for class` |nbsp| :placeholder:`C` |nbsp| :diagtext:`when binding a reference to a temporary; was` |nbsp| |+---------------------+| -| ||:diagtext:`private` || -| |+---------------------+| -| ||:diagtext:`protected`|| -| |+---------------------+| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ - -+--------------------------------------------------------+--------------------+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`anonymous` |nbsp| |+------------------+| |nbsp| :diagtext:`cannot be '`:placeholder:`B`:diagtext:`'`| -| ||:diagtext:`struct`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -+--------------------------------------------------------+--------------------+------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ considers this destructor name lookup to be ambiguous`| -+----------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no viable constructor` |nbsp| |+----------------------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B`:diagtext:`; C++98 requires a copy constructor when binding a reference to a temporary`| -| ||:diagtext:`copying variable` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying parameter` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`returning object` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`initializing statement expression result`|| | -| |+----------------------------------------------------+| | -| ||:diagtext:`throwing object` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying member subobject` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying array element` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`allocating object` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`copying temporary` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`initializing base subobject` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`initializing vector element` || | -| |+----------------------------------------------------+| | -| ||:diagtext:`capturing value` || | -| |+----------------------------------------------------+| | -+--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ standards before C++17 do not allow new expression for type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to use list-initialization`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parameter` |nbsp| :placeholder:`A` |nbsp| :diagtext:`was not declared, defaulting to type 'int'`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invoking a pointer to a 'const &' member function on an rvalue is a C++20 extension`| -+--------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`qualifier in explicit instantiation of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires a template-id (a typedef is not permitted)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------+----------------------+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`is used in an inline function with external linkage`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+-----------------------------------------------------+----------------------+-----------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C forbids forward references to 'enum' types`| -+---------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------+-------------------+-------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C restricts enumerator values to range of 'int' (`:placeholder:`A` |nbsp| :diagtext:`is too` |nbsp| |+-----------------+|:diagtext:`)`| -| ||:diagtext:`small`|| | -| |+-----------------+| | -| ||:diagtext:`large`|| | -| |+-----------------+| | -+----------------------------------------------------------------------------------------------------------------------------------------------+-------------------+-------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`size of static array must be an integer constant expression`| -+--------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializer for aggregate is not a compile-time constant`| -+-----------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`flexible array members are a C99 feature`| -+-------------------------------------------------------------------------------+ - -+---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a function type`| -| ||:diagtext:`sizeof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`vec\_step` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_alignof` || | -| |+---------------------------------------------------+| | -+---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ - -+---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a void type`| -| ||:diagtext:`sizeof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`vec\_step` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_alignof` || | -| |+---------------------------------------------------+| | -+---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C90 does not allow subscripting non-lvalue array`| -+-------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`subscript of a pointer to void is a GNU extension`| -+----------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C forbids taking the address of an expression of type 'void'`| -+-------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ordered comparison between pointer and zero (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is an extension`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`equality comparison between function pointer and void pointer (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`arithmetic on`|+---------------------+| |nbsp| :diagtext:`pointer`|+-------------+| |nbsp| :diagtext:`to void is a GNU extension`| -| || |nbsp| :diagtext:`a`|| || || | -| |+---------------------+| |+-------------+| | -| || || ||:diagtext:`s`|| | -| |+---------------------+| |+-------------+| | -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------------------------------+ - -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------+-------------------------+---------------------------------+---------------+------------------------+---------------------------------------------------+--------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`arithmetic on`|+---------------------+| |nbsp| :diagtext:`pointer`|+-------------+| |nbsp| :diagtext:`to`|+-----------------------+| |nbsp| :diagtext:`function type`|+-------------+| |nbsp| :placeholder:`B`|+-------------------------------------------------+| |nbsp| :diagtext:`is a GNU extension`| -| || |nbsp| :diagtext:`a`|| || || || |nbsp| :diagtext:`the`|| || || || || | -| |+---------------------+| |+-------------+| |+-----------------------+| |+-------------+| |+-------------------------------------------------+| | -| || || ||:diagtext:`s`|| || || ||:diagtext:`s`|| ||+-----------------------------------------------+|| | -| |+---------------------+| |+-------------+| |+-----------------------+| |+-------------+| ||| |nbsp| :diagtext:`and` |nbsp| :placeholder:`D`||| | -| | | | | | | | | ||+-----------------------------------------------+|| | -| | | | | | | | | |+-------------------------------------------------+| | -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------+-------------------------+---------------------------------+---------------+------------------------+---------------------------------------------------+--------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C does not support '++'/'--' on complex integer type` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C does not support '~' for complex conjugation of` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`complex numbers are an extension in a freestanding C99 implementation`| -+------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast between pointer-to-function and pointer-to-object is an extension`| -+-------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from array size expression of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| |+-----------------------+| |nbsp| :diagtext:`type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`is a C++11 extension`| -| ||:diagtext:`integral` || | -| |+-----------------------+| | -| ||:diagtext:`enumeration`|| | -| |+-----------------------+| | -+---------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------------------------+ - -+---------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`converts between void pointer and function pointer`| -| ||:diagtext:`assigning to different types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`passing to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`returning from function with different return type`|| | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`converting between types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`initializing with expression of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+---------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`kernel function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a member function; this may not be accepted by nvcc`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C99 forbids conditional expressions with only one void side`| -+--------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C99 forbids casting nonscalar type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to the same type`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++14 extension`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++17 extension`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++20 extension`| -+---------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------+--------------------+---------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`types declared in an anonymous` |nbsp| |+------------------+| |nbsp| :diagtext:`are a Microsoft extension`| -| ||:diagtext:`struct`|| | -| |+------------------+| | -| ||:diagtext:`union` || | -| |+------------------+| | -+-----------------------------------------------------------------------------+--------------------+---------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`format specifies type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`but the argument has` |nbsp| |+---------------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`type` || | -| |+---------------------------+| | -| ||:diagtext:`underlying type`|| | -| |+---------------------------+| | -+------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ - -+---------------------------------------------------+----------------------+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`void` |nbsp| |+--------------------+| |nbsp| :placeholder:`A` |nbsp| :diagtext:`should not return void expression`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`method` || | -| |+--------------------+| | -| ||:diagtext:`block` || | -| |+--------------------+| | -+---------------------------------------------------+----------------------+-----------------------------------------------------------------------------+ - -+---------------------------+----------------------------------+------------------------------+-----------------------+----------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------+|:diagtext:`array size` |nbsp| |+---------------------+|:diagtext:`is a C99 feature`| -| ||:diagtext:`qualifier in` |nbsp| || || || | -| |+--------------------------------+| |+---------------------+| | -| ||:diagtext:`static` |nbsp| || || || | -| |+--------------------------------+| |+---------------------+| | -| || || ||:diagtext:`'\[\*\] '`|| | -| |+--------------------------------+| |+---------------------+| | -+---------------------------+----------------------------------+------------------------------+-----------------------+----------------------------+ - -+--------------------------------------------------------+------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra ';'` |nbsp| |+----------------------------------------------+| -| ||:diagtext:`outside of a function` || -| |+----------------------------------------------+| -| ||+--------------------------------------------+|| -| |||:diagtext:`inside a` |nbsp| :placeholder:`B`||| -| ||+--------------------------------------------+|| -| |+----------------------------------------------+| -| ||:diagtext:`inside instance variable list` || -| |+----------------------------------------------+| -| ||:diagtext:`after member function definition` || -| |+----------------------------------------------+| -+--------------------------------------------------------+------------------------------------------------+ - -+-----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'\_\_thread' before '`:placeholder:`A`:diagtext:`'`| -+-----------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`type-less parameter names in function declaration`| -+----------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable declaration in for loop is a C99-specific feature`| -+-------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`compound literals are a C99-specific feature`| -+-----------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`commas at the end of enumerator lists are a C99-specific feature`| -+-------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`commas at the end of enumerator lists are a C++11 extension`| -+--------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are a C++11 extension`| -+-----------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a C99 extension`| -+----------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of GNU array range extension`| -+-----------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`exception specification of '...' is a Microsoft extension`| -+------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------+---------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attributes on` |nbsp| |+-------------------------+| |nbsp| :diagtext:`declaration are a C++17 extension`| -| ||:diagtext:`a namespace` || | -| |+-------------------------+| | -| ||:diagtext:`an enumerator`|| | -| |+-------------------------+| | -+------------------------------------------------------------+---------------------------+-----------------------------------------------------+ - -+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extern templates are a C++11 extension`| -+-----------------------------------------------------------------------------+ - -+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multi-line // comment`| -+------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`// comments are not allowed in this language`| -+-----------------------------------------------------------------------------------+ - -+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no newline at end of file`| -+----------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of non-standard escape character '\\`:placeholder:`A`:diagtext:`'`| -+------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating constants are a C99 feature`| -+---------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are a C++17 feature`| -+----------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#ident is a language extension`| -+---------------------------------------------------------------------+ - -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#warning is a language extension`| -+-----------------------------------------------------------------------+ - -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comma operator in operand of #if`| -+-----------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\_\_VA\_ARGS\_\_ can only appear in the expansion of a C99 variadic macro`| -+----------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variadic macros are a C99 feature`| -+------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`named variadic macros are a GNU extension`| -+--------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty macro arguments are a C99 feature`| -+------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variadic macros are a Clang extension in OpenCL`| -+--------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`C requires #line number to be less than` |nbsp| :placeholder:`A`:diagtext:`, allowed as extension`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`macro expansion producing 'defined' has undefined behavior`| -+-------------------------------------------------------------------------------------------------+ - - --Wpedantic-core-features ------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`OpenCL extension` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is core feature or supported optional core feature - ignoring`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpessimizing-move ------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`moving a temporary object prevents copy elision`| -+--------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`moving a local object in a return statement prevents copy elision`| -+--------------------------------------------------------------------------------------------------------+ - - --Wpointer-arith ---------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------+-------------------------+---------------------------------+---------------+------------------------+---------------------------------------------------+--------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`arithmetic on`|+---------------------+| |nbsp| :diagtext:`pointer`|+-------------+| |nbsp| :diagtext:`to`|+-----------------------+| |nbsp| :diagtext:`function type`|+-------------+| |nbsp| :placeholder:`B`|+-------------------------------------------------+| |nbsp| :diagtext:`is a GNU extension`| -| || |nbsp| :diagtext:`a`|| || || || |nbsp| :diagtext:`the`|| || || || || | -| |+---------------------+| |+-------------+| |+-----------------------+| |+-------------+| |+-------------------------------------------------+| | -| || || ||:diagtext:`s`|| || || ||:diagtext:`s`|| ||+-----------------------------------------------+|| | -| |+---------------------+| |+-------------+| |+-----------------------+| |+-------------+| ||| |nbsp| :diagtext:`and` |nbsp| :placeholder:`D`||| | -| | | | | | | | | ||+-----------------------------------------------+|| | -| | | | | | | | | |+-------------------------------------------------+| | -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------+-------------------------+---------------------------------+---------------+------------------------+---------------------------------------------------+--------------------------------------+ - -+----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`subscript of a pointer to void is a GNU extension`| -+----------------------------------------------------------------------------------------+ - -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`arithmetic on`|+---------------------+| |nbsp| :diagtext:`pointer`|+-------------+| |nbsp| :diagtext:`to void is a GNU extension`| -| || |nbsp| :diagtext:`a`|| || || | -| |+---------------------+| |+-------------+| | -| || || ||:diagtext:`s`|| | -| |+---------------------+| |+-------------+| | -+----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------------------------------+ - -+---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a function type`| -| ||:diagtext:`sizeof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`vec\_step` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_alignof` || | -| |+---------------------------------------------------+| | -+---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ - -+---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a void type`| -| ||:diagtext:`sizeof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`vec\_step` || | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | -| |+---------------------------------------------------+| | -| ||:diagtext:`\_\_alignof` || | -| |+---------------------------------------------------+| | -+---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`subtraction of pointers to type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of zero size has undefined behavior`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpointer-bool-conversion -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------+---------------------------+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nonnull` |nbsp| |+-------------------------+| |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' will evaluate to 'true' on first encounter`| -| ||:diagtext:`function call`|| | -| |+-------------------------+| | -| ||:diagtext:`parameter` || | -| |+-------------------------+| | -+------------------------------------------------------+---------------------------+---------------------------------------------------------------------------------------------+ - -+-------------------------------------------------+------------------------------+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`address of`|+----------------------------+| |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' will always evaluate to 'true'`| -| || || | -| |+----------------------------+| | -| || |nbsp| :diagtext:`function`|| | -| |+----------------------------+| | -| || |nbsp| :diagtext:`array` || | -| |+----------------------------+| | -+-------------------------------------------------+------------------------------+---------------------------------------------------------------------------------+ - - --Wpointer-compare ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------+------------------------+-------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparing a pointer to a null character constant; did you mean to compare to` |nbsp| |+----------------------+|:diagtext:`?`| -| ||:diagtext:`NULL` || | -| |+----------------------+| | -| ||:diagtext:`(void \*)0`|| | -| |+----------------------+| | -+---------------------------------------------------------------------------------------------------------------------------+------------------------+-------------+ - - --Wpointer-integer-compare -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison between pointer and integer (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`)`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpointer-sign --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+----------------------------------------------------------------+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`converts between pointers to integer types with different sign`| -| ||:diagtext:`assigning to different types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`passing to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`returning from function with different return type`|| | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`converting between types` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`initializing with expression of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`sending to parameter of different type` || | -| |+--------------------------------------------------------------+| | -| ||:diagtext:`casting between types` || | -| |+--------------------------------------------------------------+| | -+---------------------------+----------------------------------------------------------------+----------------------------------------------------------------------------------+ - - --Wpointer-to-enum-cast ----------------------- -This diagnostic is enabled by default. - -Also controls `-Wvoid-pointer-to-enum-cast`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpointer-to-int-cast ---------------------- -This diagnostic is enabled by default. - -Also controls `-Wpointer-to-enum-cast`_, `-Wvoid-pointer-to-int-cast`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpointer-to-int-cast ---------------------- -This diagnostic is enabled by default. - -Also controls `-Wpointer-to-enum-cast`_, `-Wvoid-pointer-to-int-cast`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpointer-type-mismatch ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pointer type mismatch`| -+------------------------------------------------------------+ - - --Wpoison-system-directories ---------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`include location '`:placeholder:`A`:diagtext:`' is unsafe for cross-compilation`| -+----------------------------------------------------------------------------------------------------------------------+ - - --Wpotentially-evaluated-expression ----------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression with side effects will be evaluated despite being used as an operand to 'typeid'`| -+----------------------------------------------------------------------------------------------------------------------------------+ - - --Wpragma-clang-attribute ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in '#pragma clang attribute push' region`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpragma-once-outside-header ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma once in main file`| -+----------------------------------------------------------------+ - - --Wpragma-pack -------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wpragma-pack-suspicious-include`_. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the current #pragma pack alignment value is modified in the included file`| -+----------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unterminated '#pragma pack (push, ...)' at end of file`| -+---------------------------------------------------------------------------------------------+ - - --Wpragma-pack-suspicious-include --------------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-default #pragma pack value changes the alignment of struct or union members in the included file`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wpragma-system-header-outside-header -------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma system\_header ignored in main file`| -+----------------------------------------------------------------------------------+ - - --Wpragmas ---------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wignored-pragmas`_, `-Wpragma-clang-attribute`_, `-Wpragma-pack`_, `-Wunknown-pragmas`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------+----------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma redefine\_extname is applicable to external C declarations only; not applied to` |nbsp| |+--------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+--------------------------------------------------------------------------------------------------------------------------------------+----------------------+------------------------+ - - --Wpredefined-identifier-outside-function ----------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`predefined identifier is only valid inside function`| -+------------------------------------------------------------------------------------------+ - - --Wprivate-extern ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of \_\_private\_extern\_\_ on a declaration may not produce external symbol private to the linkage unit and is deprecated`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wprivate-header ----------------- -This diagnostic is an error by default, but the flag ``-Wno-private-header`` can be used to disable the error. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`use of private header from outside its module: '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------------------+ - - --Wprivate-module ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected canonical name for private module '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`private submodule '`:placeholder:`A`:diagtext:`' in private module map, expected top-level module`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`module '`:placeholder:`A`:diagtext:`' already re-exported as '`:placeholder:`B`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no submodule named` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in module '`:placeholder:`B`:diagtext:`'; using top level '`:placeholder:`C`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wprofile-instr-missing ------------------------ -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`profile data may be incomplete: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+----------------+| |nbsp| :diagtext:`no data`| -| || || ||:diagtext:`has` || | -| |+-------------+| |+----------------+| | -| ||:diagtext:`s`|| ||:diagtext:`have`|| | -| |+-------------+| |+----------------+| | -+-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+---------------------------+ - - --Wprofile-instr-out-of-date ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+--------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`profile data may be out of date: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+----------------+| |nbsp| :diagtext:`mismatched data that will be ignored`| -| || || ||:diagtext:`has` || | -| |+-------------+| |+----------------+| | -| ||:diagtext:`s`|| ||:diagtext:`have`|| | -| |+-------------+| |+----------------+| | -+------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+--------------------------------------------------------+ - - --Wprofile-instr-unprofiled --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no profile data available for file "`:placeholder:`A`:diagtext:`"`| -+--------------------------------------------------------------------------------------------------------+ - - --Wproperty-access-dot-syntax ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`not found on object of type` |nbsp| :placeholder:`B`:diagtext:`; did you mean to access property` |nbsp| :placeholder:`C`:diagtext:`?`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wproperty-attribute-mismatch ------------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property attribute in class extension does not match the primary class`| -+-------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' attribute on property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`does not match the property inherited from` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`getter name mismatch between property redeclaration (`:placeholder:`B`:diagtext:`) and its original declaration (`:placeholder:`A`:diagtext:`)`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attribute 'readonly' of property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`restricts attribute 'readwrite' of property inherited from` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wprotocol ----------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`method` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in protocol` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not implemented`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wprotocol-property-synthesis-ambiguity ---------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------+----------------------------------------------------------------+----------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`was selected for synthesis`| -| ||+-------------------------------------------+ || | -| |||:diagtext:`of type` |nbsp| :placeholder:`B`| || | -| ||+-------------------------------------------+ || | -| |+--------------------------------------------------------------+| | -| ||+---------------------------------------------------------+ || | -| |||:diagtext:`with attribute '`:placeholder:`B`:diagtext:`'`| || | -| ||+---------------------------------------------------------+ || | -| |+--------------------------------------------------------------+| | -| ||+------------------------------------------------------------+|| | -| |||:diagtext:`without attribute '`:placeholder:`B`:diagtext:`'`||| | -| ||+------------------------------------------------------------+|| | -| |+--------------------------------------------------------------+| | -| ||+-----------------------------------------------+ || | -| |||:diagtext:`with getter` |nbsp| :placeholder:`B`| || | -| ||+-----------------------------------------------+ || | -| |+--------------------------------------------------------------+| | -| ||+-----------------------------------------------+ || | -| |||:diagtext:`with setter` |nbsp| :placeholder:`B`| || | -| ||+-----------------------------------------------+ || | -| |+--------------------------------------------------------------+| | -+-------------------------------------------------------+----------------------------------------------------------------+----------------------------------------------+ - - --Wqualified-void-return-type ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`function cannot return qualified void type` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------+ - - --Wquoted-include-in-framework-header ------------------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`double-quoted include "`:placeholder:`A`:diagtext:`" in framework header, expected angle-bracketed instead`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wrange-loop-analysis ---------------------- -Controls `-Wrange-loop-bind-reference`_, `-Wrange-loop-construct`_. - - --Wrange-loop-bind-reference ---------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`binds to a temporary value produced by a range of type` |nbsp| :placeholder:`B`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wrange-loop-construct ----------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`binds to a temporary constructed from a different type`| -+------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`creates a copy from type` |nbsp| :placeholder:`B`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wreadonly-iboutlet-property ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`readonly IBOutlet property` |nbsp| :placeholder:`A` |nbsp| :diagtext:`when auto-synthesized may not work correctly with 'nib' loader`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wreceiver-expr ---------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`receiver type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not 'id' or interface pointer, consider casting it to 'id'`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wreceiver-forward-class ------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`receiver` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a forward class and corresponding @interface may not exist`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`receiver type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`for instance message is a forward declaration`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wredeclared-class-member -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`class member cannot be redeclared`| -+------------------------------------------------------------------------+ - - --Wredundant-decls ------------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wredundant-move ----------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redundant move in return statement`| -+-------------------------------------------------------------------------+ - - --Wredundant-parens ------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redundant parentheses surrounding declarator`| -+-----------------------------------------------------------------------------------+ - - --Wregister ----------- -This diagnostic is enabled by default. - -Also controls `-Wdeprecated-register`_. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ISO C++17 does not allow 'register' storage class specifier`| -+----------------------------------------------------------------------------------------------+ - - --Wreinterpret-base-class ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------+------------------+---------------------------------------------------------+------------------+-------------------------------+-------------------------------------+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'reinterpret\_cast'` |nbsp| |+----------------+| |nbsp| :diagtext:`class` |nbsp| :placeholder:`A` |nbsp| |+----------------+| |nbsp| :diagtext:`its` |nbsp| |+-----------------------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`behaves differently from 'static\_cast'`| -| ||:diagtext:`from`|| ||:diagtext:`to` || ||:diagtext:`virtual base` || | -| |+----------------+| |+----------------+| |+-----------------------------------+| | -| ||:diagtext:`to` || ||:diagtext:`from`|| ||:diagtext:`base at non-zero offset`|| | -| |+----------------+| |+----------------+| |+-----------------------------------+| | -+------------------------------------------------------------------+------------------+---------------------------------------------------------+------------------+-------------------------------+-------------------------------------+-----------------------------------------------------------------------------------+ - - --Rremark-backend-plugin ------------------------ -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --Wreorder ---------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wreorder-ctor`_, `-Wreorder-init-list`_. - - --Wreorder-ctor --------------- -**Diagnostic text:** - -+---------------------------+------------------------+-----------------------------------------------------------------------------+-------------------+------------------------+ -|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`will be initialized after` |nbsp| |+-----------------+| |nbsp| :placeholder:`D`| -| ||:diagtext:`field` || ||:diagtext:`field`|| | -| |+----------------------+| |+-----------------+| | -| ||:diagtext:`base class`|| ||:diagtext:`base` || | -| |+----------------------+| |+-----------------+| | -+---------------------------+------------------------+-----------------------------------------------------------------------------+-------------------+------------------------+ - - --Wreorder-init-list -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ requires field designators to be specified in declaration order; field` |nbsp| :placeholder:`B` |nbsp| :diagtext:`will be initialized after field` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wrequires-expression ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`this requires expression will only be checked for syntactic validity; did you intend to place it in a nested requirement? (add another 'requires' before the expression)`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wrequires-super-attribute --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+----------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute cannot be applied to` |nbsp| |+--------------------------------+| -| ||:diagtext:`methods in protocols`|| -| |+--------------------------------+| -| ||:diagtext:`dealloc` || -| |+--------------------------------+| -+-----------------------------------------------------------------------------------------------------+----------------------------------+ - - --Wreserved-id-macro -------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`macro name is a reserved identifier`| -+--------------------------------------------------------------------------+ - - --Wreserved-user-defined-literal -------------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++11-compat-reserved-user-defined-literal`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid suffix on literal; C++11 requires a space between literal and identifier`| -+-----------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`invalid suffix on literal; C++11 requires a space between literal and identifier`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Wretained-language-linkage ---------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`friend function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`retaining previous language linkage is an extension`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wreturn-stack-address ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`returning address of label, which is local`| -+---------------------------------------------------------------------------------+ - -+--------------------------------------------------------+--------------------------+------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`returning` |nbsp| |+------------------------+| |nbsp| :diagtext:`local temporary object`| -| ||:diagtext:`address of` || | -| |+------------------------+| | -| ||:diagtext:`reference to`|| | -| |+------------------------+| | -+--------------------------------------------------------+--------------------------+------------------------------------------+ - -+---------------------------+--------------------------+--------------------------------------------------------+----------------------------+----------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------+| |nbsp| :diagtext:`stack memory associated with` |nbsp| |+--------------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`returned`| -| ||:diagtext:`address of` || ||:diagtext:`local variable`|| | -| |+------------------------+| |+--------------------------+| | -| ||:diagtext:`reference to`|| ||:diagtext:`parameter` || | -| |+------------------------+| |+--------------------------+| | -+---------------------------+--------------------------+--------------------------------------------------------+----------------------------+----------------------------------------------------+ - - --Wreturn-std-move ------------------ -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`local variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will be copied despite being` |nbsp| |+--------------------+| |nbsp| :diagtext:`by name`| -| ||:diagtext:`returned`|| | -| |+--------------------+| | -| ||:diagtext:`thrown` || | -| |+--------------------+| | -+-------------------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ - - --Wreturn-std-move-in-c++11 --------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`prior to the resolution of a defect report against ISO C++11, local variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`would have been copied despite being returned by name, due to its not matching the function return type`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wreturn-type -------------- -This diagnostic is enabled by default. - -Also controls `-Wreturn-type-c-linkage`_. - -**Diagnostic text:** - -+-----------------------+---------------------------+---------------------------------------------------------------------+ -|:error:`error:` |nbsp| |+-------------------------+| |nbsp| :placeholder:`A` |nbsp| :diagtext:`should not return a value`| -| ||:diagtext:`void function`|| | -| |+-------------------------+| | -| ||:diagtext:`void method` || | -| |+-------------------------+| | -| ||:diagtext:`constructor` || | -| |+-------------------------+| | -| ||:diagtext:`destructor` || | -| |+-------------------------+| | -+-----------------------+---------------------------+---------------------------------------------------------------------+ - -+---------------------------------------------------+----------------------+-----------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`non-void` |nbsp| |+--------------------+| |nbsp| :placeholder:`A` |nbsp| :diagtext:`should return a value`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`method` || | -| |+--------------------+| | -+---------------------------------------------------+----------------------+-----------------------------------------------------------------+ - -+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-void coroutine does not return a value`| -+---------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-void function does not return a value`| -+--------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-void lambda does not return a value`| -+------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-void coroutine does not return a value in all control paths`| -+------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-void function does not return a value in all control paths`| -+-----------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-void lambda does not return a value in all control paths`| -+---------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------+----------------------+-----------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`non-void` |nbsp| |+--------------------+| |nbsp| :placeholder:`A` |nbsp| :diagtext:`should return a value`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`method` || | -| |+--------------------+| | -+---------------------------------------------------+----------------------+-----------------------------------------------------------------+ - - --Wreturn-type-c-linkage ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has C-linkage specified, but returns user-defined type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`which is incompatible with C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has C-linkage specified, but returns incomplete type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`which could be incompatible with C`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wrewrite-not-bool ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 requires return type of selected 'operator==' function for rewritten '`:placeholder:`B`:diagtext:`' comparison to be 'bool', not` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Rsanitize-address ------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------+ -|:remark:`remark:` |nbsp| :diagtext:`-fsanitize-address-field-padding applied to` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+ -|:remark:`remark:` |nbsp| :diagtext:`-fsanitize-address-field-padding ignored for` |nbsp| :placeholder:`A` |nbsp| :diagtext:`because it` |nbsp| |+------------------------------------+| -| ||:diagtext:`is not C++` || -| |+------------------------------------+| -| ||:diagtext:`is packed` || -| |+------------------------------------+| -| ||:diagtext:`is a union` || -| |+------------------------------------+| -| ||:diagtext:`is trivially copyable` || -| |+------------------------------------+| -| ||:diagtext:`has trivial destructor` || -| |+------------------------------------+| -| ||:diagtext:`is standard layout` || -| |+------------------------------------+| -| ||:diagtext:`is in a blacklisted file`|| -| |+------------------------------------+| -| ||:diagtext:`is blacklisted` || -| |+------------------------------------+| -+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+ - - --Wsection ---------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`section attribute is specified on redeclared variable`| -+--------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`duplicate code segment specifiers`| -+------------------------------------------------------------------------+ - -+---------------------------+---------------------+-------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`does not match previous declaration`| -| ||:diagtext:`codeseg`|| | -| |+-------------------+| | -| ||:diagtext:`section`|| | -| |+-------------------+| | -+---------------------------+---------------------+-------------------------------------------------------+ - - --Wselector ----------- -Also controls `-Wselector-type-mismatch`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no method with selector` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is implemented in this translation unit`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wselector-type-mismatch ------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`several methods with selector` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of mismatched types are found for the @selector expression`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wself-assign -------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wself-assign-field`_, `-Wself-assign-overloaded`_. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicitly assigning value of variable of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to itself`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wself-assign-field -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------+-------------------------------+-----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`assigning` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`to itself`| -| ||:diagtext:`field` || | -| |+-----------------------------+| | -| ||:diagtext:`instance variable`|| | -| |+-----------------------------+| | -+--------------------------------------------------------+-------------------------------+-----------------------------+ - - --Wself-assign-overloaded ------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicitly assigning value of variable of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to itself`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wself-move ------------ -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicitly moving variable of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to itself`| -+------------------------------------------------------------------------------------------------------------------------------+ - - --Wsemicolon-before-method-body ------------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`semicolon before method body is ignored`| -+------------------------------------------------------------------------------+ - - --Wsentinel ----------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------+-----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing sentinel in` |nbsp| |+---------------------------+| -| ||:diagtext:`function call` || -| |+---------------------------+| -| ||:diagtext:`method dispatch`|| -| |+---------------------------+| -| ||:diagtext:`block call` || -| |+---------------------------+| -+------------------------------------------------------------------+-----------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`not enough variable arguments in` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declaration to fit a sentinel`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsequence-point ----------------- -Synonym for `-Wunsequenced`_. - - --Wserialized-diagnostics ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unable to open file` |nbsp| :placeholder:`A` |nbsp| :diagtext:`for serializing diagnostics (`:placeholder:`B`:diagtext:`)`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unable to merge a subprocess's serialized diagnostics`| -+--------------------------------------------------------------------------------------------+ - - --Wshadow --------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wshadow-field-in-constructor-modified`_, `-Wshadow-ivar`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------+-------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration shadows a` |nbsp| |+-----------------------------------------------------------+| -| ||:diagtext:`local variable` || -| |+-----------------------------------------------------------+| -| ||+-----------------------------------------------+ || -| |||:diagtext:`variable in` |nbsp| :placeholder:`C`| || -| ||+-----------------------------------------------+ || -| |+-----------------------------------------------------------+| -| ||+---------------------------------------------------------+|| -| |||:diagtext:`static data member of` |nbsp| :placeholder:`C`||| -| ||+---------------------------------------------------------+|| -| |+-----------------------------------------------------------+| -| ||+--------------------------------------------+ || -| |||:diagtext:`field of` |nbsp| :placeholder:`C`| || -| ||+--------------------------------------------+ || -| |+-----------------------------------------------------------+| -| ||+----------------------------------------------+ || -| |||:diagtext:`typedef in` |nbsp| :placeholder:`C`| || -| ||+----------------------------------------------+ || -| |+-----------------------------------------------------------+| -| ||+-------------------------------------------------+ || -| |||:diagtext:`type alias in` |nbsp| :placeholder:`C`| || -| ||+-------------------------------------------------+ || -| |+-----------------------------------------------------------+| -+--------------------------------------------------------------------+-------------------------------------------------------------+ - - --Wshadow-all ------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wshadow`_, `-Wshadow-field`_, `-Wshadow-field-in-constructor`_, `-Wshadow-uncaptured-local`_. - - --Wshadow-field --------------- -**Diagnostic text:** - -+---------------------------+------------------------------------+--------------------------------+--------------------------------------------------+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------------------+| |nbsp| :placeholder:`A` |nbsp| |+------------------------------------------------+|:diagtext:`shadows member inherited from type` |nbsp| :placeholder:`C`| -| ||:diagtext:`parameter` || || || | -| |+----------------------------------+| |+------------------------------------------------+| | -| ||:diagtext:`non-static data member`|| ||+----------------------------------------------+|| | -| |+----------------------------------+| |||:diagtext:`of` |nbsp| :placeholder:`B` |nbsp| ||| | -| | | ||+----------------------------------------------+|| | -| | | |+------------------------------------------------+| | -+---------------------------+------------------------------------+--------------------------------+--------------------------------------------------+----------------------------------------------------------------------+ - - --Wshadow-field-in-constructor ------------------------------ -Also controls `-Wshadow-field-in-constructor-modified`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constructor parameter` |nbsp| :placeholder:`A` |nbsp| :diagtext:`shadows the field` |nbsp| :placeholder:`B` |nbsp| :diagtext:`of` |nbsp| :placeholder:`C`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wshadow-field-in-constructor-modified --------------------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`modifying constructor parameter` |nbsp| :placeholder:`A` |nbsp| :diagtext:`that shadows a field of` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wshadow-ivar -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`local declaration of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`hides instance variable`| -+------------------------------------------------------------------------------------------------------------------------------+ - - --Wshadow-uncaptured-local -------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------+-------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration shadows a` |nbsp| |+-----------------------------------------------------------+| -| ||:diagtext:`local variable` || -| |+-----------------------------------------------------------+| -| ||+-----------------------------------------------+ || -| |||:diagtext:`variable in` |nbsp| :placeholder:`C`| || -| ||+-----------------------------------------------+ || -| |+-----------------------------------------------------------+| -| ||+---------------------------------------------------------+|| -| |||:diagtext:`static data member of` |nbsp| :placeholder:`C`||| -| ||+---------------------------------------------------------+|| -| |+-----------------------------------------------------------+| -| ||+--------------------------------------------+ || -| |||:diagtext:`field of` |nbsp| :placeholder:`C`| || -| ||+--------------------------------------------+ || -| |+-----------------------------------------------------------+| -| ||+----------------------------------------------+ || -| |||:diagtext:`typedef in` |nbsp| :placeholder:`C`| || -| ||+----------------------------------------------+ || -| |+-----------------------------------------------------------+| -| ||+-------------------------------------------------+ || -| |||:diagtext:`type alias in` |nbsp| :placeholder:`C`| || -| ||+-------------------------------------------------+ || -| |+-----------------------------------------------------------+| -+--------------------------------------------------------------------+-------------------------------------------------------------+ - - --Wshift-count-negative ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`shift count is negative`| -+--------------------------------------------------------------+ - - --Wshift-count-overflow ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`shift count >= width of type`| -+-------------------------------------------------------------------+ - - --Wshift-negative-value ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`shifting a negative signed value is undefined`| -+------------------------------------------------------------------------------------+ - - --Wshift-op-parentheses ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`operator '`:placeholder:`A`:diagtext:`' has lower precedence than '`:placeholder:`B`:diagtext:`'; '`:placeholder:`B`:diagtext:`' will be evaluated first`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wshift-overflow ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`signed shift result (`:placeholder:`A`:diagtext:`) requires` |nbsp| :placeholder:`B` |nbsp| :diagtext:`bits to represent, but` |nbsp| :placeholder:`C` |nbsp| :diagtext:`only has` |nbsp| :placeholder:`D` |nbsp| :diagtext:`bits`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wshift-sign-overflow ---------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`signed shift result (`:placeholder:`A`:diagtext:`) sets the sign bit of the shift expression's type (`:placeholder:`B`:diagtext:`) and becomes negative`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wshorten-64-to-32 ------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion loses integer precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsign-compare --------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of integers of different signs:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsign-conversion ------------------ -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion changes signedness:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`operand of ? changes signedness:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the resulting value is always non-negative after implicit conversion`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wsign-promo ------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wsigned-enum-bitfield ----------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`enums in the Microsoft ABI are signed integers by default; consider giving the enum` |nbsp| :placeholder:`A` |nbsp| :diagtext:`an unsigned underlying type to make this code portable`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsigned-unsigned-wchar ------------------------ -This diagnostic is an error by default, but the flag ``-Wno-signed-unsigned-wchar`` can be used to disable the error. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' cannot be signed or unsigned`| -+----------------------------------------------------------------------------------------------+ - - --Wsizeof-array-argument ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`sizeof on array function parameter will return size of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`instead of` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsizeof-array-decay --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`sizeof on pointer operation will return size of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`instead of` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsizeof-array-div ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression does not compute the number of elements in this array; element type is` |nbsp| :placeholder:`A`:diagtext:`, not` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsizeof-pointer-div --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will return the size of the pointer, not the array itself`| -+-------------------------------------------------------------------------------------------------------------------------------+ - - --Wsizeof-pointer-memaccess --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' call operates on objects of type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`while the size is based on a different type` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument to 'sizeof' in` |nbsp| :placeholder:`A` |nbsp| :diagtext:`call is the same pointer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`as the` |nbsp| |+-----------------------+|:diagtext:`; expected` |nbsp| :placeholder:`D` |nbsp| :diagtext:`or an explicit length`| -| ||:diagtext:`destination`|| | -| |+-----------------------+| | -| ||:diagtext:`source` || | -| |+-----------------------+| | -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+---------------------------------------------------------------------------------------+ - - --Wslash-u-filename ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'/U`:placeholder:`A`:diagtext:`' treated as the '/U' option`| -+--------------------------------------------------------------------------------------------------+ - - --Wsometimes-uninitialized -------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+----------------------+--------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is` |nbsp| |+--------------------+| |nbsp| :diagtext:`uninitialized whenever` |nbsp| |+------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`used` || ||+---------------------------------------------------------------+-------------------+ || -| |+--------------------+| |||:diagtext:`'`:placeholder:`D`:diagtext:`' condition is` |nbsp| |+-----------------+| || -| ||:diagtext:`captured`|| ||| ||:diagtext:`true` || || -| |+--------------------+| ||| |+-----------------+| || -| | | ||| ||:diagtext:`false`|| || -| | | ||| |+-----------------+| || -| | | ||+---------------------------------------------------------------+-------------------+ || -| | | |+------------------------------------------------------------------------------------------------------------+| -| | | ||+-------------------------------------------------------+--------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`D`:diagtext:`' loop` |nbsp| |+------------------------------------------------+||| -| | | ||| ||:diagtext:`is entered` |||| -| | | ||| |+------------------------------------------------+||| -| | | ||| ||:diagtext:`exits because its condition is false`|||| -| | | ||| |+------------------------------------------------+||| -| | | ||+-------------------------------------------------------+--------------------------------------------------+|| -| | | |+------------------------------------------------------------------------------------------------------------+| -| | | ||+-------------------------------------------------------+--------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`D`:diagtext:`' loop` |nbsp| |+------------------------------------------------+||| -| | | ||| ||:diagtext:`condition is true` |||| -| | | ||| |+------------------------------------------------+||| -| | | ||| ||:diagtext:`exits because its condition is false`|||| -| | | ||| |+------------------------------------------------+||| -| | | ||+-------------------------------------------------------+--------------------------------------------------+|| -| | | |+------------------------------------------------------------------------------------------------------------+| -| | | ||+----------------------------------------------------------------------+ || -| | | |||:diagtext:`switch` |nbsp| :placeholder:`D` |nbsp| :diagtext:`is taken`| || -| | | ||+----------------------------------------------------------------------+ || -| | | |+------------------------------------------------------------------------------------------------------------+| -| | | ||:diagtext:`its declaration is reached` || -| | | |+------------------------------------------------------------------------------------------------------------+| -| | | ||+---------------------------------------------+ || -| | | |||:placeholder:`D` |nbsp| :diagtext:`is called`| || -| | | ||+---------------------------------------------+ || -| | | |+------------------------------------------------------------------------------------------------------------+| -+-----------------------------------------------------------------------------------------------------+----------------------+--------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ - - --Wsource-uses-openmp --------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nesting \`omp begin/end declare variant\` is not supported yet; nested context ignored`| -+-----------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'#pragma omp declare variant' cannot be applied to the function that was defined already; the original function might be used`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'#pragma omp declare variant' cannot be applied for function after first usage; the original function might be used`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`score expressions in the OpenMP context selector need to be constant;` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not and will be ignored`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`OpenMP only allows an ordered construct with the simd clause nested in a simd construct`| -+------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unexpected '#pragma omp ...' in program`| -+------------------------------------------------------------------------------+ - - --Wspir-compat -------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`sampler initializer has invalid` |nbsp| :placeholder:`A` |nbsp| :diagtext:`bits`| -+----------------------------------------------------------------------------------------------------------------------+ - - --Wstack-exhausted ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`stack nearly exhausted; compilation time may suffer, and crashes due to stack overflow are likely`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - - --Wstack-protector ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Unable to protect inline asm that clobbers stack pointer against stack clash`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Wstack-protector ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Unable to protect inline asm that clobbers stack pointer against stack clash`| -+-------------------------------------------------------------------------------------------------------------------+ - - --Wstatic-float-init -------------------- -This diagnostic is enabled by default. - -Also controls `-Wgnu-static-float-init`_. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`in-class initializer for static data member of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires 'constexpr' specifier`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wstatic-in-inline ------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------+----------------------+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`is used in an inline function with external linkage`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+-----------------------------------------------------+----------------------+-----------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------+----------------------+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`is used in an inline function with external linkage`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+-----------------------------------------------------+----------------------+-----------------------------------------------------------------------------------------------+ - - --Wstatic-inline-explicit-instantiation --------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------+--------------------+--------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '`|+------------------+|:diagtext:`' keyword on explicit template instantiation`| -| ||:diagtext:`static`|| | -| |+------------------+| | -| ||:diagtext:`inline`|| | -| |+------------------+| | -+-------------------------------------------------+--------------------+--------------------------------------------------------+ - - --Wstatic-local-in-inline ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-constant static local variable in inline function may be different in different files`| -+--------------------------------------------------------------------------------------------------------------------------------+ - - --Wstatic-self-init ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is suspiciously used within its own initialization`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wstdlibcxx-not-found ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`include path for libstdc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wstrict-aliasing ------------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-aliasing=0 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-aliasing=1 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-aliasing=2 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-overflow ------------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-overflow=0 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-overflow=1 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-overflow=2 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-overflow=3 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-overflow=4 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-overflow=5 -------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wstrict-prototypes -------------------- -**Diagnostic text:** - -+---------------------------------------------------+--------------------------------------------------------------+-------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`this` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`a prototype`| -| ||:diagtext:`function declaration is not` || | -| |+------------------------------------------------------------+| | -| ||:diagtext:`block declaration is not` || | -| |+------------------------------------------------------------+| | -| ||:diagtext:`old-style function definition is not preceded by`|| | -| |+------------------------------------------------------------+| | -+---------------------------------------------------+--------------------------------------------------------------+-------------------------------+ - - --Wstrict-prototypes -------------------- -**Diagnostic text:** - -+---------------------------------------------------+--------------------------------------------------------------+-------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`this` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`a prototype`| -| ||:diagtext:`function declaration is not` || | -| |+------------------------------------------------------------+| | -| ||:diagtext:`block declaration is not` || | -| |+------------------------------------------------------------+| | -| ||:diagtext:`old-style function definition is not preceded by`|| | -| |+------------------------------------------------------------+| | -+---------------------------------------------------+--------------------------------------------------------------+-------------------------------+ - - --Wstrict-selector-match ------------------------ -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple methods named` |nbsp| :placeholder:`A` |nbsp| :diagtext:`found`| -+--------------------------------------------------------------------------------------------------------------+ - - --Wstring-compare ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------+------------------------------+---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of comparison against` |nbsp| |+----------------------------+| |nbsp| :diagtext:`is unspecified (use an explicit string comparison function instead)`| -| ||:diagtext:`a string literal`|| | -| |+----------------------------+| | -| ||:diagtext:`@encode` || | -| |+----------------------------+| | -+---------------------------------------------------------------------------+------------------------------+---------------------------------------------------------------------------------------+ - - --Wstring-conversion -------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion turns string literal into bool:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wstring-plus-char ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`adding` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to a string pointer does not append to the string`| -+------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wstring-plus-int ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`adding` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to a string does not append to the string`| -+----------------------------------------------------------------------------------------------------------------------------------+ - - --Wstrlcpy-strlcat-size ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`size argument in` |nbsp| :placeholder:`A` |nbsp| :diagtext:`call appears to be size of the source; expected the size of the destination`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wstrncat-size --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the value of the size argument in 'strncat' is too large, might lead to a buffer overflow`| -+--------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`size argument in 'strncat' call appears to be size of the source`| -+-------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the value of the size argument to 'strncat' is wrong`| -+-------------------------------------------------------------------------------------------+ - - --Wsuper-class-method-mismatch ------------------------------ -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`method parameter type` |nbsp| :diagtext:`does not match super class method parameter type`| -+--------------------------------------------------------------------------------------------------------------------------------+ - - --Wsuspicious-bzero ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'size' argument to bzero is '0'`| -+----------------------------------------------------------------------+ - - --Wsuspicious-memaccess ----------------------- -This diagnostic is enabled by default. - -Controls `-Wdynamic-class-memaccess`_, `-Wmemset-transposed-args`_, `-Wnontrivial-memaccess`_, `-Wsizeof-pointer-memaccess`_, `-Wsuspicious-bzero`_. - - --Wswitch --------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overflow converting case value to switch condition type (`:placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`:diagtext:`)`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+----------------------------------------------------------------------------------------------+ || -| |||:diagtext:`enumeration value` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not handled in switch`| || -| ||+----------------------------------------------------------------------------------------------+ || -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+----------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C` |nbsp| :diagtext:`not handled in switch`| || -| ||+----------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`, and` |nbsp| :placeholder:`D` |nbsp| :diagtext:`not handled in switch`| || -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |||:placeholder:`A` |nbsp| :diagtext:`enumeration values not handled in switch:` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`,` |nbsp| :placeholder:`D`:diagtext:`...`||| -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -+---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`case value not in enumerated type` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------------------------+ - - --Wswitch-bool -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`switch condition has boolean value`| -+-------------------------------------------------------------------------+ - - --Wswitch-default ----------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wswitch-enum -------------- -**Diagnostic text:** - -+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+---------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`enumeration value` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not explicitly handled in switch`| || -| ||+---------------------------------------------------------------------------------------------------------+ || -| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C` |nbsp| :diagtext:`not explicitly handled in switch`| || -| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`, and` |nbsp| :placeholder:`D` |nbsp| :diagtext:`not explicitly handled in switch`| || -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |||:placeholder:`A` |nbsp| :diagtext:`enumeration values not explicitly handled in switch:` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`,` |nbsp| :placeholder:`D`:diagtext:`...`||| -| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsync-fetch-and-nand-semantics-changed ---------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the semantics of this intrinsic changed with GCC version 4.4 - the newer semantics are provided here`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wsynth -------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wtautological-bitwise-compare ------------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`bitwise comparison always evaluates to` |nbsp| |+-----------------+| -| ||:diagtext:`false`|| -| |+-----------------+| -| ||:diagtext:`true` || -| |+-----------------+| -+-------------------------------------------------------------------------------------+-------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`bitwise or with non-zero value always evaluates to true`| -+----------------------------------------------------------------------------------------------+ - - --Wtautological-compare ----------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wtautological-bitwise-compare`_, `-Wtautological-constant-compare`_, `-Wtautological-objc-bool-compare`_, `-Wtautological-overlap-compare`_, `-Wtautological-pointer-compare`_, `-Wtautological-undefined-compare`_. - -**Diagnostic text:** - -+---------------------------+---------------------------------------------------------------+----------------------------------------+-------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------------------------------------------+| |nbsp| :diagtext:`to 1 byte is` |nbsp| |+-----------------------+| -| ||:diagtext:`aligning a value` || ||:diagtext:`a no-op` || -| |+-------------------------------------------------------------+| |+-----------------------+| -| ||:diagtext:`the result of checking whether a value is aligned`|| ||:diagtext:`always true`|| -| |+-------------------------------------------------------------+| |+-----------------------+| -+---------------------------+---------------------------------------------------------------+----------------------------------------+-------------------------+ - -+---------------------------+---------------------------+--------------------------------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------+|:diagtext:`comparison always evaluates to` |nbsp| |+------------------------------------------+| -| ||:diagtext:`self-` || ||:diagtext:`a constant` || -| |+-------------------------+| |+------------------------------------------+| -| ||:diagtext:`array` |nbsp| || ||:diagtext:`true` || -| |+-------------------------+| |+------------------------------------------+| -| | | ||:diagtext:`false` || -| | | |+------------------------------------------+| -| | | ||:diagtext:`'std::strong\_ordering::equal'`|| -| | | |+------------------------------------------+| -+---------------------------+---------------------------+--------------------------------------------------+--------------------------------------------+ - - --Wtautological-constant-compare -------------------------------- -This diagnostic is enabled by default. - -Also controls `-Wtautological-constant-out-of-range-compare`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`converting the result of '?:' with integer constants to a boolean always evaluates to 'true'`| -+-----------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`converting the result of '<<' to a boolean always evaluates to` |nbsp| |+-----------------+| -| ||:diagtext:`false`|| -| |+-----------------+| -| ||:diagtext:`true` || -| |+-----------------+| -+-------------------------------------------------------------------------------------------------------------+-------------------+ - -+----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | -| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| | -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | -| |+----------------------------------------------+| |+--------------------------------------------------------+| | -| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | -| |+----------------------------------------------+| |+--------------------------------------------------------+| | -| ||:diagtext:`false` || | | | -| |+----------------------------------------------+| | | | -+----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ - - --Wtautological-constant-in-range-compare ----------------------------------------- -Controls `-Wtautological-type-limit-compare`_, `-Wtautological-unsigned-enum-zero-compare`_, `-Wtautological-unsigned-zero-compare`_. - - --Wtautological-constant-out-of-range-compare --------------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | -| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| | -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | -| |+----------------------------------------------+| |+--------------------------------------------------------+| | -| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | -| |+----------------------------------------------+| |+--------------------------------------------------------+| | -| ||:diagtext:`false` || | | | -| |+----------------------------------------------+| | | | -+----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ - - --Wtautological-objc-bool-compare --------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of comparison of constant` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with expression of type 'BOOL' is always` |nbsp| :placeholder:`B`:diagtext:`, as the only well defined values for 'BOOL' are YES and NO`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wtautological-overlap-compare ------------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`overlapping comparisons always evaluate to` |nbsp| |+-----------------+| -| ||:diagtext:`false`|| -| |+-----------------+| -| ||:diagtext:`true` || -| |+-----------------+| -+-----------------------------------------------------------------------------------------+-------------------+ - - --Wtautological-pointer-compare ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------+---------------------------+----------------------------------------------------------+-------------------------+----------------------------------------+-------------------+--------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of nonnull` |nbsp| |+-------------------------+| |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`'` |nbsp| |+-----------------------+|:diagtext:`equal to a null pointer is '`|+-----------------+|:diagtext:`' on first encounter`| -| ||:diagtext:`function call`|| ||:diagtext:`not` |nbsp| || ||:diagtext:`true` || | -| |+-------------------------+| |+-----------------------+| |+-----------------+| | -| ||:diagtext:`parameter` || || || ||:diagtext:`false`|| | -| |+-------------------------+| |+-----------------------+| |+-----------------+| | -+--------------------------------------------------------------------+---------------------------+----------------------------------------------------------+-------------------------+----------------------------------------+-------------------+--------------------------------+ - -+------------------------------------------------------------+------------------------+----------------------------------------------------------+-------------------------+-----------------------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+----------------------+| |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`'` |nbsp| |+-----------------------+|:diagtext:`equal to a null pointer is always` |nbsp| |+-----------------+| -| ||:diagtext:`address of`|| ||:diagtext:`not` |nbsp| || ||:diagtext:`true` || -| |+----------------------+| |+-----------------------+| |+-----------------+| -| ||:diagtext:`function` || || || ||:diagtext:`false`|| -| |+----------------------+| |+-----------------------+| |+-----------------+| -| ||:diagtext:`array` || | | | | -| |+----------------------+| | | | | -+------------------------------------------------------------+------------------------+----------------------------------------------------------+-------------------------+-----------------------------------------------------+-------------------+ - - --Wtautological-type-limit-compare ---------------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------+------------------+--------------------------------+------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of comparison` |nbsp| |+----------------+| |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| -| ||:placeholder:`D`|| ||:placeholder:`B`|| | -| |+----------------+| |+----------------+| | -| ||:placeholder:`B`|| ||:placeholder:`D`|| | -| |+----------------+| |+----------------+| | -+-------------------------------------------------------------------+------------------+--------------------------------+------------------+-----------------------------------------------------+ - - --Wtautological-undefined-compare --------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to` |nbsp| |+-----------------+| -| ||:diagtext:`true` || -| |+-----------------+| -| ||:diagtext:`false`|| -| |+-----------------+| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to` |nbsp| |+-----------------+| -| ||:diagtext:`true` || -| |+-----------------+| -| ||:diagtext:`false`|| -| |+-----------------+| -+------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+ - - --Wtautological-unsigned-enum-zero-compare ------------------------------------------ -**Diagnostic text:** - -+----------------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+------------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| -| ||:placeholder:`D` || ||:diagtext:`unsigned enum expression`|| | -| |+------------------------------------+| |+------------------------------------+| | -| ||:diagtext:`unsigned enum expression`|| ||:placeholder:`D` || | -| |+------------------------------------+| |+------------------------------------+| | -+----------------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-----------------------------------------------------+ - - --Wtautological-unsigned-zero-compare ------------------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+-------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| -| ||:placeholder:`D` || ||:diagtext:`unsigned expression`|| | -| |+-------------------------------+| |+-------------------------------+| | -| ||:diagtext:`unsigned expression`|| ||:placeholder:`D` || | -| |+-------------------------------+| |+-------------------------------+| | -+----------------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-----------------------------------------------------+ - - --Wtentative-definition-incomplete-type --------------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`tentative definition of variable with internal linkage has incomplete non-array type` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wthread-safety ---------------- -Controls `-Wthread-safety-analysis`_, `-Wthread-safety-attributes`_, `-Wthread-safety-precise`_, `-Wthread-safety-reference`_. - - --Wthread-safety-analysis ------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' must be acquired before '`:placeholder:`C`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Cycle in acquired\_before/after dependencies, starting with '`:placeholder:`A`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cannot resolve lock expression`| -+---------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`acquiring` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' that is already held`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expecting` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' to be held at start of each loop`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expecting` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' to be held at the end of function`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cannot call function '`:placeholder:`B`:diagtext:`' while` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`C`:diagtext:`' is held`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`calling function` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' is acquired exclusively and shared in the same scope`| -+--------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' is not held on every path through here`| -+------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' is still held at the end of function`| -+----------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`releasing` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' that was not held`| -+--------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+--------------------------------------------+-----------------------+--------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`releasing` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' using` |nbsp| |+---------------------+| |nbsp| :diagtext:`access, expected` |nbsp| |+---------------------+| |nbsp| :diagtext:`access`| -| ||:diagtext:`shared` || ||:diagtext:`shared` || | -| |+---------------------+| |+---------------------+| | -| ||:diagtext:`exclusive`|| ||:diagtext:`exclusive`|| | -| |+---------------------+| |+---------------------+| | -+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+--------------------------------------------+-----------------------+--------------------------+ - -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------+-----------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires holding` |nbsp| |+---------------------------------+| -| ||:diagtext:`reading`|| ||:diagtext:`any mutex` || -| |+-------------------+| |+---------------------------------+| -| ||:diagtext:`writing`|| ||:diagtext:`any mutex exclusively`|| -| |+-------------------+| |+---------------------------------+| -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------+-----------------------------------+ - -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+---------------------------+---------------------+------------------------------------------------------------------------------------------------+-----------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires holding` |nbsp| |+---------------------------------+| -| ||:diagtext:`reading`|| ||:diagtext:`any mutex` || -| |+-------------------+| |+---------------------------------+| -| ||:diagtext:`writing`|| ||:diagtext:`any mutex exclusively`|| -| |+-------------------+| |+---------------------------------+| -+---------------------------+---------------------+------------------------------------------------------------------------------------------------+-----------------------------------+ - -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - - --Wthread-safety-attributes --------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute requires arguments whose type is annotated with 'capability' attribute; type here is` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute can only be applied in a context annotated with 'capability' attribute`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`only applies to pointer types; type here is` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute because its argument is invalid`| -+------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute without capability arguments refers to 'this', but` |nbsp| :placeholder:`B` |nbsp| :diagtext:`isn't annotated with 'capability' or 'scoped\_lockable' attribute`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute without capability arguments can only be applied to non-static methods of a class`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wthread-safety-beta --------------------- -**Diagnostic text:** - -+------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Thread safety beta warning.`| -+------------------------------------------------------------------+ - - --Wthread-safety-negative ------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`acquiring` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' requires negative capability '`:placeholder:`C`:diagtext:`'`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wthread-safety-precise ------------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`calling function` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - - --Wthread-safety-reference -------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`by reference requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing the value that` |nbsp| :placeholder:`B` |nbsp| :diagtext:`points to by reference requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - - --Wthread-safety-verbose ------------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Thread safety verbose warning.`| -+---------------------------------------------------------------------+ - - --Wtrigraphs ------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`trigraph converted to '`:placeholder:`A`:diagtext:`' character`| -+-----------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`trigraph ends block comment`| -+------------------------------------------------------------------+ - -+-------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`trigraph ignored`| -+-------------------------------------------------------+ - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignored trigraph would end block comment`| -+-------------------------------------------------------------------------------+ - - --Wtype-limits -------------- -Synonym for `-Wtautological-constant-in-range-compare`_. - - --Wtype-limits -------------- -Synonym for `-Wtautological-constant-in-range-compare`_. - - --Wtype-safety -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`specified` |nbsp| :placeholder:`A` |nbsp| :diagtext:`type tag requires a null pointer`| -+----------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`doesn't match specified` |nbsp| :placeholder:`B` |nbsp| :diagtext:`type tag` |nbsp| |+---------------------------------------------------+| -| ||+-------------------------------------------------+|| -| |||:diagtext:`that requires` |nbsp| :placeholder:`D`||| -| ||+-------------------------------------------------+|| -| |+---------------------------------------------------+| -| || || -| |+---------------------------------------------------+| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`this type tag was not designed to be used with this function`| -+---------------------------------------------------------------------------------------------------+ - - --Wtypedef-redefinition ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redefinition of typedef` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a C11 feature`| -+--------------------------------------------------------------------------------------------------------------------------+ - - --Wtypename-missing ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`missing 'typename' prior to dependent type name '`:placeholder:`A`:placeholder:`B`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunable-to-open-stats-file ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unable to open statistics output file '`:placeholder:`A`:diagtext:`': '`:placeholder:`B`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunavailable-declarations --------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may be unavailable because the receiver type is unknown`| -+----------------------------------------------------------------------------------------------------------------------+ - - --Wundeclared-selector ---------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`undeclared selector` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`undeclared selector` |nbsp| :placeholder:`A`:diagtext:`; did you mean` |nbsp| :placeholder:`B`:diagtext:`?`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wundef -------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not defined, evaluates to 0`| -+---------------------------------------------------------------------------------------------+ - - --Wundefined-bool-conversion ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wundefined-func-template -------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instantiation of function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`required here, but no definition is available`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wundefined-inline ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not defined`| -+----------------------------------------------------------------------------------------------------------------+ - - --Wundefined-internal --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+----------------------+-----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`has internal linkage but is not defined`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+---------------------------+----------------------+-----------------------------------------------------------------------------------+ - - --Wundefined-internal-type -------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------+----------------------+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ requires a definition in this translation unit for` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`because its type does not have linkage`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+---------------------------------------------------------------------------------------------------------+----------------------+----------------------------------------------------------------------------------+ - - --Wundefined-reinterpret-cast ----------------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dereference of type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`that was reinterpret\_cast from type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has undefined behavior`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reinterpret\_cast from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has undefined behavior`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wundefined-var-template ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`instantiation of variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`required here, but no definition is available`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunderaligned-exception-object -------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`underaligned exception object thrown`| -+---------------------------------------------------------------------------+ - - --Wunevaluated-expression ------------------------- -This diagnostic is enabled by default. - -Also controls `-Wpotentially-evaluated-expression`_. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression with side effects has no effect in an unevaluated context`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wunguarded-availability ------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wunguarded-availability-new`_. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is only available on` |nbsp| :placeholder:`B` |nbsp| :placeholder:`C` |nbsp| :diagtext:`or newer`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunguarded-availability-new ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is only available on` |nbsp| :placeholder:`B` |nbsp| :placeholder:`C` |nbsp| :diagtext:`or newer`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunicode ---------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incomplete universal character name; treating as '\\' followed by identifier`| -+-------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\\`:placeholder:`A` |nbsp| :diagtext:`used with no following hex digits; treating as '\\' followed by identifier`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`universal character name refers to a surrogate character`| -+-----------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`universal character names are only valid in C99 or C++; treating as '\\' followed by identifier`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`universal character names are only valid in C99 or C++`| -+---------------------------------------------------------------------------------------------+ - - --Wunicode-homoglyph -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`treating Unicode character as identifier character rather than as '`:placeholder:`B`:diagtext:`' symbol`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunicode-whitespace --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`treating Unicode character as whitespace`| -+-------------------------------------------------------------------------------+ - - --Wunicode-zero-width --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`identifier contains Unicode character that is invisible in some environments`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wuninitialized ---------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wsometimes-uninitialized`_, `-Wstatic-self-init`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`base class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is uninitialized when used here to access` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is uninitialized when used here`| -+-----------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reference` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not yet bound to a value when used here`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------+---------------------------+------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`block pointer variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is` |nbsp| |+-------------------------+| |nbsp| :diagtext:`when captured by block`| -| ||:diagtext:`uninitialized`|| | -| |+-------------------------+| | -| ||:diagtext:`null` || | -| |+-------------------------+| | -+-------------------------------------------------------------------------------------------------------------------+---------------------------+------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is uninitialized when used within its own initialization`| -+---------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`reference` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not yet bound to a value when used within its own initialization`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------+-------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is uninitialized when` |nbsp| |+-----------------------------+| -| ||:diagtext:`used here` || -| |+-----------------------------+| -| ||:diagtext:`captured by block`|| -| |+-----------------------------+| -+------------------------------------------------------------------------------------------------------------------------+-------------------------------+ - - --Wunknown-argument ------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown argument ignored in clang-cl: '`:placeholder:`A`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown argument ignored in clang-cl '`:placeholder:`A`:diagtext:`'; did you mean '`:placeholder:`B`:diagtext:`'?`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunknown-attributes --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wunknown-cuda-version ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Unknown CUDA version` |nbsp| :placeholder:`A`:diagtext:`. Assuming the latest supported version` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunknown-escape-sequence -------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown escape sequence '\\`:placeholder:`A`:diagtext:`'`| -+-----------------------------------------------------------------------------------------------+ - - --Wunknown-pragmas ------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected 'ON' or 'OFF' or 'DEFAULT' in pragma`| -+------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expected end of directive in pragma`| -+--------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown pragma in STDC namespace`| -+-----------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pragma diagnostic pop could not pop, no matching push`| -+--------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'`| -+--------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pragma diagnostic expected option name (e.g. "-Wundef")`| -+----------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unexpected token in pragma diagnostic`| -+----------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma execution\_character\_set expected '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma execution\_character\_set invalid value '`:placeholder:`A`:diagtext:`', only 'UTF-8' is supported`| -+------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma execution\_character\_set expected 'push' or 'pop'`| -+-------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown pragma ignored`| -+-------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pragma include\_alias expected '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pragma include\_alias expected include filename`| -+--------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`angle-bracketed include <`:placeholder:`A`:diagtext:`> cannot be aliased to double-quoted include "`:placeholder:`B`:diagtext:`"`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`double-quoted include "`:placeholder:`A`:diagtext:`" cannot be aliased to angle-bracketed include <`:placeholder:`B`:diagtext:`>`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma warning expected '`:placeholder:`A`:diagtext:`'`| -+----------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma warning expected a warning number`| -+--------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma warning(push, level) requires a level between 0 and 4`| -+----------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`#pragma warning expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pragma STDC FENV\_ACCESS ON is not supported, ignoring pragma`| -+----------------------------------------------------------------------------------------------------+ - - --Wunknown-sanitizers --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown sanitizer '`:placeholder:`A`:diagtext:`' ignored`| -+-----------------------------------------------------------------------------------------------+ - - --Wunknown-warning-option ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown warning group '`:placeholder:`A`:diagtext:`', ignored`| -+----------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------+---------------------+---------------------------------------------------------+--------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown` |nbsp| |+-------------------+| |nbsp| :diagtext:`option '`:placeholder:`B`:diagtext:`'`|+------------------------------------------------------------+| -| ||:diagtext:`warning`|| || || -| |+-------------------+| |+------------------------------------------------------------+| -| ||:diagtext:`remark` || ||+----------------------------------------------------------+|| -| |+-------------------+| |||:diagtext:`; did you mean '`:placeholder:`D`:diagtext:`'?`||| -| | | ||+----------------------------------------------------------+|| -| | | |+------------------------------------------------------------+| -+------------------------------------------------------+---------------------+---------------------------------------------------------+--------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown` |nbsp| :placeholder:`A` |nbsp| :diagtext:`warning specifier: '`:placeholder:`B`:diagtext:`'`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunnamed-type-template-args ----------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - -Also controls `-Wc++98-compat-unnamed-type-template-args`_. - -**Diagnostic text:** - -+--------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template argument uses unnamed type`| -+--------------------------------------------------------------------------+ - - --Wunneeded-internal-declaration -------------------------------- -**Diagnostic text:** - -+---------------------------+----------------------+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`is not needed and will not be emitted`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+---------------------------+----------------------+---------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'static' function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`declared in header file should be declared 'static inline'`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunneeded-member-function --------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`member function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not needed and will not be emitted`| -+---------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunreachable-code ------------------- -Also controls `-Wunreachable-code-loop-increment`_. - -**Diagnostic text:** - -+------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`code will never be executed`| -+------------------------------------------------------------------+ - - --Wunreachable-code-aggressive ------------------------------ -Controls `-Wunreachable-code`_, `-Wunreachable-code-break`_, `-Wunreachable-code-return`_. - - --Wunreachable-code-break ------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'break' will never be executed`| -+---------------------------------------------------------------------+ - - --Wunreachable-code-loop-increment ---------------------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`loop will run at most once (loop increment never executed)`| -+-------------------------------------------------------------------------------------------------+ - - --Wunreachable-code-return -------------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'return' will never be executed`| -+----------------------------------------------------------------------+ - - --Wunsequenced -------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`multiple unsequenced modifications to` |nbsp| :placeholder:`A`| -+----------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unsequenced modification and access to` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------------------+ - - --Wunsupported-abs ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mabs=2008' option because the '`:placeholder:`A`:diagtext:`' architecture does not support it`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mabs=legacy' option because the '`:placeholder:`A`:diagtext:`' architecture does not support it`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunsupported-availability-guard --------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+------------------------------------+--------------------------------------------------------------+------------------------------------+---------------------+ -|:warning:`warning:` |nbsp| |+----------------------------------+| |nbsp| :diagtext:`does not guard availability here; use if (`|+----------------------------------+|:diagtext:`) instead`| -| ||:diagtext:`@available` || ||:diagtext:`@available` || | -| |+----------------------------------+| |+----------------------------------+| | -| ||:diagtext:`\_\_builtin\_available`|| ||:diagtext:`\_\_builtin\_available`|| | -| |+----------------------------------+| |+----------------------------------+| | -+---------------------------+------------------------------------+--------------------------------------------------------------+------------------------------------+---------------------+ - - --Wunsupported-cb ----------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mcompact-branches=' option because the '`:placeholder:`A`:diagtext:`' architecture does not support it`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunsupported-dll-base-class-template -------------------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`propagating dll attribute to` |nbsp| |+----------------------------------+| |nbsp| :diagtext:`base class template without dll attribute is not supported`| -| ||:diagtext:`already instantiated` || | -| |+----------------------------------+| | -| ||:diagtext:`explicitly specialized`|| | -| |+----------------------------------+| | -+---------------------------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------+ - - --Wunsupported-friend --------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dependent nested name specifier '`:placeholder:`A`:diagtext:`' for friend template declaration is not supported; ignoring this friend declaration`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dependent nested name specifier '`:placeholder:`A`:diagtext:`' for friend class declaration is not supported; turning off access control for` |nbsp| :placeholder:`B`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunsupported-gpopt -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mgpopt' option as it cannot be used with` |nbsp| |+-----------------------------------------+|:diagtext:`-mabicalls`| -| || || | -| |+-----------------------------------------+| | -| ||:diagtext:`the implicit usage of` |nbsp| || | -| |+-----------------------------------------+| | -+--------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ - - --Wunsupported-nan ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mnan=2008' option because the '`:placeholder:`A`:diagtext:`' architecture does not support it`| -+-----------------------------------------------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mnan=legacy' option because the '`:placeholder:`A`:diagtext:`' architecture does not support it`| -+-------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunsupported-target-opt ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`debug information option '`:placeholder:`A`:diagtext:`' is not supported for target '`:placeholder:`B`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunsupported-visibility ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`target does not support 'protected' visibility; using 'default'`| -+------------------------------------------------------------------------------------------------------+ - - --Wunusable-partial-specialization ---------------------------------- -This diagnostic is an error by default, but the flag ``-Wno-unusable-partial-specialization`` can be used to disable the error. - -**Diagnostic text:** - -+-----------------------+----------------------+--------------------------------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| |+--------------------+| |nbsp| :diagtext:`template partial specialization contains` |nbsp| |+--------------------------------+| |nbsp| :diagtext:`that cannot be deduced; this partial specialization will never be used`| -| ||:diagtext:`class` || ||:diagtext:`a template parameter`|| | -| |+--------------------+| |+--------------------------------+| | -| ||:diagtext:`variable`|| ||:diagtext:`template parameters` || | -| |+--------------------+| |+--------------------------------+| | -+-----------------------+----------------------+--------------------------------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------+ - - --Wunused --------- -Some of the diagnostics controlled by this flag are enabled by default. - -Controls `-Wunused-argument`_, `-Wunused-function`_, `-Wunused-label`_, `-Wunused-lambda-capture`_, `-Wunused-local-typedef`_, `-Wunused-private-field`_, `-Wunused-property-ivar`_, `-Wunused-value`_, `-Wunused-variable`_. - - --Wunused-argument ------------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wunused-command-line-argument ------------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument '`:placeholder:`A`:diagtext:`' requires profile-guided optimization information`| -+-------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`joined argument expects additional value: '`:placeholder:`A`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------+----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A`:diagtext:`: '`:placeholder:`B`:diagtext:`' input unused`|+--------------------------------------------------------------------+| -| ||+------------------------------------------------------------------+|| -| ||| |nbsp| :diagtext:`when '`:placeholder:`D`:diagtext:`' is present`||| -| ||+------------------------------------------------------------------+|| -| |+--------------------------------------------------------------------+| -| || || -| |+--------------------------------------------------------------------+| -+----------------------------------------------------------------------------------------------------+----------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A`:diagtext:`: '`:placeholder:`B`:diagtext:`' input unused in cpp mode`| -+----------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A`:diagtext:`: previously preprocessed input`|+---------------------------------------------------------------------------+| -| ||+-------------------------------------------------------------------------+|| -| ||| |nbsp| :diagtext:`unused when '`:placeholder:`C`:diagtext:`' is present`||| -| ||+-------------------------------------------------------------------------+|| -| |+---------------------------------------------------------------------------+| -| || || -| |+---------------------------------------------------------------------------+| -+--------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument unused during compilation: '`:placeholder:`A`:diagtext:`'`| -+---------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`the flag '`:placeholder:`A`:diagtext:`' has been deprecated and will be ignored`| -+----------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring -fdiscard-value-names for LLVM Bitcode`| -+--------------------------------------------------------------------------------------+ - - --Wunused-comparison -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------+------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`comparison result unused`| -| ||:diagtext:`equality` || | -| |+----------------------+| | -| ||:diagtext:`inequality`|| | -| |+----------------------+| | -| ||:diagtext:`relational`|| | -| |+----------------------+| | -| ||:diagtext:`three-way` || | -| |+----------------------+| | -+---------------------------+------------------------+--------------------------------------------+ - - --Wunused-const-variable ------------------------ -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused variable` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------+ - - --Wunused-exception-parameter ----------------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused exception parameter` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------+ - - --Wunused-function ------------------ -Also controls `-Wunneeded-internal-declaration`_. - -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused function` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------+ - - --Wunused-getter-return-value ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property access result unused - getters should not be used for side effects`| -+------------------------------------------------------------------------------------------------------------------+ - - --Wunused-label --------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused label` |nbsp| :placeholder:`A`| -+---------------------------------------------------------------------------+ - - --Wunused-lambda-capture ------------------------ -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------+--------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`lambda capture` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not` |nbsp| |+------------------------------------------------+| -| ||:diagtext:`used` || -| |+------------------------------------------------+| -| ||:diagtext:`required to be captured for this use`|| -| |+------------------------------------------------+| -+---------------------------------------------------------------------------------------------------------------+--------------------------------------------------+ - - --Wunused-local-typedef ----------------------- -**Diagnostic text:** - -+-----------------------------------------------------+------------------------+------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused` |nbsp| |+----------------------+| |nbsp| :placeholder:`B`| -| ||:diagtext:`typedef` || | -| |+----------------------+| | -| ||:diagtext:`type alias`|| | -| |+----------------------+| | -+-----------------------------------------------------+------------------------+------------------------+ - - --Wunused-local-typedefs ------------------------ -Synonym for `-Wunused-local-typedef`_. - - --Wunused-macros ---------------- -**Diagnostic text:** - -+--------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`macro is not used`| -+--------------------------------------------------------+ - - --Wunused-member-function ------------------------- -Also controls `-Wunneeded-member-function`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused member function` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------+ - - --Wunused-parameter ------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused parameter` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------+ - - --Wunused-private-field ----------------------- -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`private field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not used`| -+-----------------------------------------------------------------------------------------------------------+ - - --Wunused-property-ivar ----------------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ivar` |nbsp| :placeholder:`A` |nbsp| :diagtext:`which backs the property is not referenced in this property's accessor`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunused-result ---------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring return value of function declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring return value of function declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute:` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wunused-template ------------------ -Also controls `-Wunneeded-internal-declaration`_. - -**Diagnostic text:** - -+-----------------------------------------------------+----------------------+----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused` |nbsp| |+--------------------+| |nbsp| :diagtext:`template` |nbsp| :placeholder:`B`| -| ||:diagtext:`function`|| | -| |+--------------------+| | -| ||:diagtext:`variable`|| | -| |+--------------------+| | -+-----------------------------------------------------+----------------------+----------------------------------------------------+ - - --Wunused-value --------------- -This diagnostic is enabled by default. - -Also controls `-Wunevaluated-expression`_, `-Wunused-comparison`_, `-Wunused-result`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring return value of function declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring temporary created by a constructor declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring temporary created by a constructor declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute:` |nbsp| :placeholder:`B`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`container access result unused - container access should not be used for side effects`| -+----------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression result unused`| -+---------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression result unused; should this cast be to 'void'?`| -+-----------------------------------------------------------------------------------------------+ - - --Wunused-variable ------------------ -Also controls `-Wunused-const-variable`_. - -**Diagnostic text:** - -+------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unused variable` |nbsp| :placeholder:`A`| -+------------------------------------------------------------------------------+ - - --Wunused-volatile-lvalue ------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`expression result unused; assign into a variable to force a volatile load`| -+----------------------------------------------------------------------------------------------------------------+ - - --Wused-but-marked-unused ------------------------- -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`was marked unused but was used`| -+---------------------------------------------------------------------------------------------+ - - --Wuser-defined-literals ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------+----------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`user-defined literal suffixes not starting with '\_' are reserved`|+--------------------------------------------------+| -| ||:diagtext:`; no literal will invoke this operator`|| -| |+--------------------------------------------------+| -| || || -| |+--------------------------------------------------+| -+--------------------------------------------------------------------------------------------------------+----------------------------------------------------+ - - --Wuser-defined-warnings ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -The text of this diagnostic is not controlled by Clang. - - --Wvarargs ---------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`second argument to 'va\_start' is not the last named parameter`| -+-----------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`second argument to 'va\_arg' is of promotable type` |nbsp| :placeholder:`A`:diagtext:`; this va\_arg has undefined behavior because arguments will be promoted to` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing` |nbsp| |+---------------------------------------------------------------+| |nbsp| :diagtext:`to 'va\_start' has undefined behavior`| -| ||:diagtext:`an object that undergoes default argument promotion`|| | -| |+---------------------------------------------------------------+| | -| ||:diagtext:`an object of reference type` || | -| |+---------------------------------------------------------------+| | -| ||:diagtext:`a parameter declared with the 'register' keyword` || | -| |+---------------------------------------------------------------+| | -+------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------+ - - --Wvariadic-macros ------------------ -Some of the diagnostics controlled by this flag are enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`named variadic macros are a GNU extension`| -+--------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`\_\_VA\_OPT\_\_ can only appear in the expansion of a variadic macro`| -+-----------------------------------------------------------------------------------------------------------+ - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variadic macros are a C99 feature`| -+------------------------------------------------------------------------+ - - --Wvec-elem-size ---------------- -This diagnostic is an error by default, but the flag ``-Wno-vec-elem-size`` can be used to disable the error. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`vector operands do not have the same elements sizes (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`)`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wvector-conversion -------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incompatible vector types` |nbsp| |+--------------------------------------------------------------+| -| ||:diagtext:`assigning to different types` || -| |+--------------------------------------------------------------+| -| ||:diagtext:`passing to parameter of different type` || -| |+--------------------------------------------------------------+| -| ||:diagtext:`returning from function with different return type`|| -| |+--------------------------------------------------------------+| -| ||:diagtext:`converting between types` || -| |+--------------------------------------------------------------+| -| ||:diagtext:`initializing with expression of different type` || -| |+--------------------------------------------------------------+| -| ||:diagtext:`sending to parameter of different type` || -| |+--------------------------------------------------------------+| -| ||:diagtext:`casting between types` || -| |+--------------------------------------------------------------+| -+------------------------------------------------------------------------+----------------------------------------------------------------+ - - --Wvector-conversions --------------------- -Synonym for `-Wvector-conversion`_. - - --Wvexing-parse --------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`empty parentheses interpreted as a function declaration`| -+----------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parentheses were disambiguated as a function declaration`| -+-----------------------------------------------------------------------------------------------+ - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`parentheses were disambiguated as redundant parentheses around declaration of variable named` |nbsp| :placeholder:`A`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wvisibility ------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`declaration of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will not be visible outside of this function`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`redefinition of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will not be visible outside of this function`| -+----------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wvla ------ -**Diagnostic text:** - -+-----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable length array used`| -+-----------------------------------------------------------------+ - - --Wvla-extension ---------------- -**Diagnostic text:** - -+-------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`variable length arrays are a C99 feature`| -+-------------------------------------------------------------------------------+ - - --Wvoid-pointer-to-enum-cast ---------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wvoid-pointer-to-int-cast --------------------------- -This diagnostic is enabled by default. - -Also controls `-Wvoid-pointer-to-enum-cast`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wvoid-ptr-dereference ----------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++ does not allow indirection on operand of type` |nbsp| :placeholder:`A`| -+--------------------------------------------------------------------------------------------------------------------+ - - --Wvolatile-register-var ------------------------ -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. - --Wweak-template-vtables ------------------------ -**Diagnostic text:** - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit template instantiation` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will emit a vtable in every translation unit`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wweak-vtables --------------- -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wwritable-strings ------------------- -This diagnostic is enabled by default. - -Also controls `-Wdeprecated-writable-strings`_. - -**Diagnostic text:** - -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++11 does not allow conversion from string literal to` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------------+ - - --Wwrite-strings ---------------- -Synonym for `-Wwritable-strings`_. - - --Wxor-used-as-pow ------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of '`:placeholder:`A`:diagtext:`' is` |nbsp| :placeholder:`B`:diagtext:`; did you mean exponentiation?`| -+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of '`:placeholder:`A`:diagtext:`' is` |nbsp| :placeholder:`B`:diagtext:`; did you mean '`:placeholder:`C`:diagtext:`'?`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`result of '`:placeholder:`A`:diagtext:`' is` |nbsp| :placeholder:`B`:diagtext:`; did you mean '`:placeholder:`C`:diagtext:`' (`:placeholder:`D`:diagtext:`)?`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - --Wzero-as-null-pointer-constant -------------------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`zero as null pointer constant`| -+--------------------------------------------------------------------+ - - --Wzero-length-array -------------------- -**Diagnostic text:** - -+------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`zero size arrays are an extension`| -+------------------------------------------------------------------------+ - - --Wwasm-exception-spec ---------------------- -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`dynamic exception specifications with types are currently ignored in wasm`| -+----------------------------------------------------------------------------------------------------------------+ diff --git a/clang/docs/HardwareAssistedAddressSanitizerDesign.rst b/clang/docs/HardwareAssistedAddressSanitizerDesign.rst index b97fbb91a43a..f89ca117427a 100644 --- a/clang/docs/HardwareAssistedAddressSanitizerDesign.rst +++ b/clang/docs/HardwareAssistedAddressSanitizerDesign.rst @@ -19,13 +19,17 @@ The redzones, the quarantine, and, to a less extent, the shadow, are the sources of AddressSanitizer's memory overhead. See the `AddressSanitizer paper`_ for details. -AArch64 has the `Address Tagging`_ (or top-byte-ignore, TBI), a hardware feature that allows -software to use 8 most significant bits of a 64-bit pointer as +AArch64 has `Address Tagging`_ (or top-byte-ignore, TBI), a hardware feature that allows +software to use the 8 most significant bits of a 64-bit pointer as a tag. HWASAN uses `Address Tagging`_ to implement a memory safety tool, similar to :doc:`AddressSanitizer`, but with smaller memory overhead and slightly different (mostly better) accuracy guarantees. +Intel's `Linear Address Masking`_ (LAM) also provides address tagging for +x86_64, though it is not widely available in hardware yet. For x86_64, HWASAN +has a limited implementation using page aliasing instead. + Algorithm ========= * Every heap/stack/global memory object is forcibly aligned by `TG` bytes @@ -266,7 +270,15 @@ before every load and store by compiler instrumentation, but this variant will have limited deployability since not all of the code is typically instrumented. -The HWASAN's approach is not applicable to 32-bit architectures. +On x86_64, HWASAN utilizes page aliasing to place tags in userspace address +bits. Currently only heap tagging is supported. The page aliases rely on +shared memory, which will cause heap memory to be shared between processes if +the application calls ``fork()``. Therefore x86_64 is really only safe for +applications that do not fork. + +HWASAN does not currently support 32-bit architectures since they do not +support `Address Tagging`_ and the address space is too constrained to easily +implement page aliasing. Related Work @@ -284,4 +296,4 @@ Related Work .. _SPARC ADI: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html .. _AddressSanitizer paper: https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf .. _Address Tagging: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch12s05s01.html - +.. _Linear Address Masking: https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html diff --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst index 32c8f2dad5aa..a547154721e9 100644 --- a/clang/docs/InternalsManual.rst +++ b/clang/docs/InternalsManual.rst @@ -2795,12 +2795,14 @@ implementing a keyword attribute, the parsing of the keyword and creation of the ``ParsedAttr`` object must be done manually. Eventually, ``Sema::ProcessDeclAttributeList()`` is called with a ``Decl`` and -an ``ParsedAttr``, at which point the parsed attribute can be transformed +a ``ParsedAttr``, at which point the parsed attribute can be transformed into a semantic attribute. The process by which a parsed attribute is converted into a semantic attribute depends on the attribute definition and semantic requirements of the attribute. The end result, however, is that the semantic attribute object is attached to the ``Decl`` object, and can be obtained by a -call to ``Decl::getAttr()``. +call to ``Decl::getAttr()``. Similarly, for statement attributes, +``Sema::ProcessStmtAttributes()`` is called with a ``Stmt`` a list of +``ParsedAttr`` objects to be converted into a semantic attribute. The structure of the semantic attribute is also governed by the attribute definition given in Attr.td. This definition is used to automatically generate @@ -2820,12 +2822,13 @@ semantic) type, or one of its derivatives. Most attributes will derive from the later redeclarations of the ``Decl`` it is associated with. ``InheritableParamAttr`` is similar to ``InheritableAttr``, except that the attribute is written on a parameter instead of a declaration. If the attribute -is intended to apply to a type instead of a declaration, such an attribute -should derive from ``TypeAttr``, and will generally not be given an AST -representation. (Note that this document does not cover the creation of type -attributes.) An attribute that inherits from ``IgnoredAttr`` is parsed, but will -generate an ignored attribute diagnostic when used, which may be useful when an -attribute is supported by another vendor but not supported by clang. +applies to statements, it should inherit from ``StmtAttr`. If the attribute is +intended to apply to a type instead of a declaration, such an attribute should +derive from ``TypeAttr``, and will generally not be given an AST representation. +(Note that this document does not cover the creation of type attributes.) An +attribute that inherits from ``IgnoredAttr`` is parsed, but will generate an +ignored attribute diagnostic when used, which may be useful when an attribute is +supported by another vendor but not supported by clang. The definition will specify several key pieces of information, such as the semantic name of the attribute, the spellings the attribute supports, the @@ -2854,10 +2857,11 @@ are created implicitly. The following spellings are accepted: ``Declspec`` Spelled with a Microsoft-style ``__declspec(attr)`` syntax. ``Keyword`` The attribute is spelled as a keyword, and required custom parsing. - ``GCC`` Specifies two spellings: the first is a GNU-style spelling, and - the second is a C++-style spelling with the ``gnu`` namespace. - Attributes should only specify this spelling for attributes - supported by GCC. + ``GCC`` Specifies two or three spellings: the first is a GNU-style + spelling, the second is a C++-style spelling with the ``gnu`` + namespace, and the third is an optional C-style spelling with + the ``gnu`` namespace. Attributes should only specify this + spelling for attributes supported by GCC. ``Clang`` Specifies two or three spellings: the first is a GNU-style spelling, the second is a C++-style spelling with the ``clang`` namespace, and the third is an optional C-style spelling with @@ -2871,19 +2875,16 @@ are created implicitly. The following spellings are accepted: Subjects ~~~~~~~~ -Attributes appertain to one or more ``Decl`` subjects. If the attribute attempts -to attach to a subject that is not in the subject list, a diagnostic is issued +Attributes appertain to one or more subjects. If the attribute attempts to +attach to a subject that is not in the subject list, a diagnostic is issued automatically. Whether the diagnostic is a warning or an error depends on how the attribute's ``SubjectList`` is defined, but the default behavior is to warn. The diagnostics displayed to the user are automatically determined based on the subjects in the list, but a custom diagnostic parameter can also be specified in the ``SubjectList``. The diagnostics generated for subject list violations are -either ``diag::warn_attribute_wrong_decl_type`` or -``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is found -in `include/clang/Sema/ParsedAttr.h -`_ -If a previously unused Decl node is added to the ``SubjectList``, the logic used -to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp +calculated automatically or specified by the subject list itself. If a +previously unused Decl node is added to the ``SubjectList``, the logic used to +automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp `_ may need to be updated. @@ -2897,8 +2898,8 @@ instance, a ``NonBitField`` SubsetSubject appertains to a ``FieldDecl``, and tests whether the given FieldDecl is a bit field. When a SubsetSubject is specified in a SubjectList, a custom diagnostic parameter must also be provided. -Diagnostic checking for attribute subject lists is automated except when -``HasCustomParsing`` is set to ``1``. +Diagnostic checking for attribute subject lists for declaration and statement +attributes is automated except when ``HasCustomParsing`` is set to ``1``. Documentation ~~~~~~~~~~~~~ @@ -3045,8 +3046,8 @@ the switch statement. Please do not implement handling logic directly in the Unless otherwise specified by the attribute definition, common semantic checking of the parsed attribute is handled automatically. This includes diagnosing -parsed attributes that do not appertain to the given ``Decl``, ensuring the -correct minimum number of arguments are passed, etc. +parsed attributes that do not appertain to the given ``Decl`` or ``Stmt``, +ensuring the correct minimum number of arguments are passed, etc. If the attribute adds additional warnings, define a ``DiagGroup`` in `include/clang/Basic/DiagnosticGroups.td @@ -3072,6 +3073,10 @@ The ``clang::Decl`` object can be queried for the presence or absence of an attribute using ``hasAttr()``. To obtain a pointer to the semantic representation of the attribute, ``getAttr`` may be used. +The ``clang::AttributedStmt`` object can be queried for the presence or absence +of an attribute by calling ``getAttrs()`` and looping over the list of +attributes. + How to add an expression or statement ------------------------------------- diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index c405e7651ce3..2faaa4dc06ee 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1259,7 +1259,9 @@ The following type trait primitives are supported by Clang. Those traits marked * ``__is_sealed`` (Microsoft): Synonym for ``__is_final``. * ``__is_signed`` (C++, Embarcadero): - Returns false for enumeration types, and returns true for floating-point types. Note, before Clang 10, returned true for enumeration types if the underlying type was signed, and returned false for floating-point types. + Returns false for enumeration types, and returns true for floating-point + types. Note, before Clang 10, returned true for enumeration types if the + underlying type was signed, and returned false for floating-point types. * ``__is_standard_layout`` (C++, GNU, Microsoft, Embarcadero) * ``__is_trivial`` (C++, GNU, Microsoft, Embarcadero) * ``__is_trivially_assignable`` (C++, GNU, Microsoft) @@ -1267,10 +1269,9 @@ The following type trait primitives are supported by Clang. Those traits marked * ``__is_trivially_copyable`` (C++, GNU, Microsoft) * ``__is_trivially_destructible`` (C++, MSVC 2013) * ``__is_union`` (C++, GNU, Microsoft, Embarcadero) -* ``__is_unsigned`` (C++, Embarcadero) - Note that this currently returns true for enumeration types if the underlying - type is unsigned, in violation of the requirements for ``std::is_unsigned``. - This behavior is likely to change in a future version of Clang. +* ``__is_unsigned`` (C++, Embarcadero): + Returns false for enumeration types. Note, before Clang 13, returned true for + enumeration types if the underlying type was unsigned. * ``__is_void`` (C++, Embarcadero) * ``__is_volatile`` (C++, Embarcadero) * ``__reference_binds_to_temporary(T, U)`` (Clang): Determines whether a diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 0becf5ebfb8c..b8fb27b126fc 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -1337,6 +1337,16 @@

Node Matchers

+Matcher<Stmt>coawaitExprMatcher<CoawaitExpr>... +
Matches co_await expressions.
+
+Given
+  co_await 1;
+coawaitExpr()
+  matches 'co_await 1'
+
+ + Matcher<Stmt>compoundLiteralExprMatcher<CompoundLiteralExpr>...
Matches compound (i.e. non-scalar) literals
 
@@ -1383,6 +1393,26 @@ 

Node Matchers

+Matcher<Stmt>coreturnStmtMatcher<CoreturnStmt>... +
Matches co_return statements.
+
+Given
+  while (true) { co_return; }
+coreturnStmt()
+  matches 'co_return'
+
+ + +Matcher<Stmt>coyieldExprMatcher<CoyieldExpr>... +
Matches co_yield expressions.
+
+Given
+  co_yield 1;
+coyieldExpr()
+  matches 'co_yield 1'
+
+ + Matcher<Stmt>cudaKernelCallExprMatcher<CUDAKernelCallExpr>...
Matches CUDA kernel call expression.
 
@@ -1698,6 +1728,11 @@ 

Node Matchers

+Matcher<Stmt>dependentCoawaitExprMatcher<DependentCoawaitExpr>... +
Matches co_await expressions where the type of the promise is dependent
+
+ + Matcher<Stmt>designatedInitExprMatcher<DesignatedInitExpr>...
Matches C99 designated initializer expressions [C99 6.7.8].
 
@@ -7509,7 +7544,7 @@ 

AST Traversal Matchers

void f(); void f() {} void g(); -hasAnyBody(functionDecl()) +functionDecl(hasAnyBody(compoundStmt())) matches both 'void f();' and 'void f() {}' with compoundStmt() diff --git a/clang/docs/MatrixTypes.rst b/clang/docs/MatrixTypes.rst index 5d022af44121..616c88f8a474 100644 --- a/clang/docs/MatrixTypes.rst +++ b/clang/docs/MatrixTypes.rst @@ -118,15 +118,22 @@ more explicit. Matrix Type Binary Operators ---------------------------- -Each matrix type supports the following binary operators: ``+``, ``-`` and ``*``. The ``*`` -operator provides matrix multiplication, while ``+`` and ``-`` are performed -element-wise. There are also scalar versions of the operators, which take a -matrix type and the matrix element type. The operation is applied to all -elements of the matrix using the scalar value. - -For ``BIN_OP`` in ``+``, ``-``, ``*`` given the expression ``M1 BIN_OP M2`` where -at least one of ``M1`` or ``M2`` is of matrix type and, for `*`, the other is of -a real type: +Given two matrixes, the ``+`` and ``-`` operators perform element-wise addition +and subtraction, while the ``*`` operator performs matrix multiplication. +``+``, ``-``, ``*``, and ``/`` can also be used with a matrix and a scalar +value, applying the operation to each element of the matrix. + +Earlier versions of this extension did not support division by a scalar. +You can test for the availability of this feature with +``__has_extension(matrix_types_scalar_division)``. + +For the expression ``M1 BIN_OP M2`` where + +* ``BIN_OP`` is one of ``+`` or ``-``, one of ``M1`` and ``M2`` is of matrix + type, and the other is of matrix type or real type; or +* ``BIN_OP`` is ``*``, one of ``M1`` and ``M2`` is of matrix type, and the + other is of a real type; or +* ``BIN_OP`` is ``/``, ``M1`` is of matrix type, and ``M2`` is of a real type: * The usual arithmetic conversions are applied to ``M1`` and ``M2``. [ Note: if ``M1`` or ``M2`` are of a real type, they are broadcast to matrices here. — end note ] diff --git a/clang/docs/OpenCLSupport.rst b/clang/docs/OpenCLSupport.rst index 02522052e106..7ecc4f2bed0a 100644 --- a/clang/docs/OpenCLSupport.rst +++ b/clang/docs/OpenCLSupport.rst @@ -168,6 +168,8 @@ also :ref:`the section on the address space attribute `). $ clang -cc1 -ffake-address-space-map test.cl +.. _opencl_builtins: + OpenCL builtins --------------- @@ -210,6 +212,82 @@ of the following main components: inserted using ``InsertOCLBuiltinDeclarationsFromTable`` and overload resolution takes place. +OpenCL Extensions and Features +------------------------------ + +Clang implements various extensions to OpenCL kernel languages. + +New functionality is accepted as soon as the documentation is detailed to the +level sufficient to be implemented. There should be an evidence that the +extension is designed with implementation feasibility in consideration and +assessment of complexity for C/C++ based compilers. Alternatively, the +documentation can be accepted in a format of a draft that can be further +refined during the implementation. + +Implementation guidelines +^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section explains how to extend clang with the new functionality. + +**Parsing functionality** + +If an extension modifies the standard parsing it needs to be added to +the clang frontend source code. This also means that the associated macro +indicating the presence of the extension should be added to clang. + +The default flow for adding a new extension into the frontend is to +modify `OpenCLExtensions.def +`_ + +This will add the macro automatically and also add a field in the target +options ``clang::TargetOptions::OpenCLFeaturesMap`` to control the exposure +of the new extension during the compilation. + +Note that by default targets like `SPIR` or `X86` expose all the OpenCL +extensions. For all other targets the configuration has to be made explicitly. + +Note that the target extension support performed by clang can be overridden +with :ref:`-cl-ext ` command-line flags. + +**Library functionality** + +If an extension adds functionality that does not modify standard language +parsing it should not require modifying anything other than header files or +``OpenCLBuiltins.td`` detailed in :ref:`OpenCL builtins `. +Most commonly such extensions add functionality via libraries (by adding +non-native types or functions) parsed regularly. Similar to other languages this +is the most common way to add new functionality. + +Clang has standard headers where new types and functions are being added, +for more details refer to +:ref:`the section on the OpenCL Header `. The macros indicating +the presence of such extensions can be added in the standard header files +conditioned on target specific predefined macros or/and language version +predefined macros. + +**Pragmas** + +Some extensions alter standard parsing dynamically via pragmas. + +Clang provides a mechanism to add the standard extension pragma +``OPENCL EXTENSION`` by setting a dedicated flag in the extension list entry of +``OpenCLExtensions.def``. Note that there is no default behavior for the +standard extension pragmas as it is not specified (for the standards up to and +including version 3.0) in a sufficient level of detail and, therefore, +there is no default functionality provided by clang. + +Pragmas without detailed information of their behavior (e.g. an explanation of +changes it triggers in the parsing) should not be added to clang. Moreover, the +pragmas should provide useful functionality to the user. For example, such +functionality should address a practical use case and not be redundant i.e. +cannot be achieved using existing features. + +Note that some legacy extensions (published prior to OpenCL 3.0) still +provide some non-conformant functionality for pragmas e.g. add diagnostics on +the use of types or functions. This functionality is not guaranteed to remain in +future releases. However, any future changes should not affect backward +compatibility. + .. _opencl_addrsp: Address spaces attribute @@ -282,7 +360,7 @@ implementation status. +------------------------------+--------------------------------------------------------------+----------------------+---------------------------------------------------------------------------+ | Predefined macros | New version macro | :good:`done` | https://reviews.llvm.org/D88300 | +------------------------------+--------------------------------------------------------------+----------------------+---------------------------------------------------------------------------+ -| Predefined macros | Feature macros | :part:`worked on` | https://reviews.llvm.org/D89869 | +| Predefined macros | Feature macros | :good:`done` | https://reviews.llvm.org/D95776 | +------------------------------+--------------------------------------------------------------+----------------------+---------------------------------------------------------------------------+ | Feature optionality | Generic address space | :none:`unclaimed` | | +------------------------------+--------------------------------------------------------------+----------------------+---------------------------------------------------------------------------+ @@ -320,6 +398,8 @@ Feel free to contact us on `cfe-dev `_ or via `Bugzilla `__. +.. _opencl_experimenal_cxxlibs: + C++ libraries for OpenCL ------------------------ @@ -363,4 +443,5 @@ The possible clang invocation to compile the example is as follows: $ clang -cl-std=clc++ -I/include test.cl Note that `type_traits` is a header only library and therefore no extra -linking step against the standard libraries is required. +linking step against the standard libraries is required. See full example +in `Compiler Explorer `_. diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index e66d9a64a93f..6e15716f3bb4 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -272,7 +272,7 @@ want to help with the implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | 'present' motion modifier | :good:`done` | D84711, D84712 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device extension | 'present' in defaultmap clause | :part:`worked on` | D92427 | +| device extension | 'present' in defaultmap clause | :good:`done` | D92427 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | map clause reordering reordering based on 'present' modifier | :none:`unclaimed` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c78445b9be6f..d4c9f53b82c0 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -72,6 +72,13 @@ Modified Compiler Flags ----------------------- - -Wshadow now also checks for shadowed structured bindings +- ``-B `` (when ```` is a directory) was overloaded to additionally + detect GCC installations under ```` (``lib{,32,64}/gcc{,-cross}/$triple``). + This behavior was incompatible with GCC, caused interop issues with + ``--gcc-toolchain``, and was thus dropped. Specify ``--gcc-toolchain=`` + instead. ``-B``'s other GCC-compatible semantics are preserved: + ``$prefix/$triple-$file`` and ``$prefix$file`` are searched for executables, + libraries, includes, and data files used by the compiler. Removed Compiler Flags ------------------------- diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 28de4e3aac6f..c7b7f580ad93 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -674,6 +674,11 @@ control the crash diagnostics. The -fno-crash-diagnostics flag can be helpful for speeding the process of generating a delta reduced test case. +.. option:: -fcrash-diagnostics-dir= + + Specify where to write the crash diagnostics files; defaults to the + usual location for temporary files. + Clang is also capable of generating preprocessed source file(s) and associated run script(s) even without a crash. This is specially useful when trying to generate a reproducer for warnings or errors while using modules. @@ -2568,13 +2573,12 @@ While Clang generally emits standard DWARF debug info (http://dwarfstd.org), different debuggers may know how to take advantage of different specific DWARF features. You can "tune" the debug info for one of several different debuggers. -.. option:: -ggdb, -glldb, -gsce - - Tune the debug info for the ``gdb``, ``lldb``, or Sony PlayStation\ |reg| - debugger, respectively. Each of these options implies **-g**. (Therefore, if - you want both **-gline-tables-only** and debugger tuning, the tuning option - must come first.) +.. option:: -ggdb, -glldb, -gsce, -gdbx + Tune the debug info for the ``gdb``, ``lldb``, Sony PlayStation\ |reg| + debugger, or ``dbx``, respectively. Each of these options implies **-g**. + (Therefore, if you want both **-gline-tables-only** and debugger tuning, the + tuning option must come first.) Controlling LLVM IR Output -------------------------- @@ -3232,6 +3236,18 @@ compiling ``.cl`` file ``-cl-std=clc++``, ``-cl-std=CLC++``, ``-std=clc++`` or clang -cl-std=clc++ test.cl +Alternatively, files with ``.clcpp`` extension are compiled with the C++ for OpenCL +mode. + + .. code-block:: console + + clang test.clcpp + +C++ for OpenCL kernel sources can also be compiled online in drivers supporting +`cl_ext_cxx_for_opencl +`_ +extension. + Constructing and destroying global objects ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -3629,6 +3645,8 @@ Execute ``clang-cl /?`` to see a list of supported options: -fcomplete-member-pointers Require member pointer base types to be complete if they would be significant under the Microsoft ABI -fcoverage-mapping Generate coverage mapping to enable code coverage analysis + -fcrash-diagnostics-dir= + Put crash-report files in -fdebug-macro Emit macro debug information -fdelayed-template-parsing Parse templated function definitions at the end of the translation unit diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index d94296244c63..9a74dffc1658 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1476,6 +1476,9 @@ Reports similar pieces of code. return y; } +alpha.core +^^^^^^^^^^ + .. _alpha-core-BoolAssignment: alpha.core.BoolAssignment (ObjC) @@ -1488,9 +1491,6 @@ Warn about assigning non-{0,1} values to boolean variables. BOOL b = -1; // warn } -alpha.core -^^^^^^^^^^ - .. _alpha-core-C11Lock: alpha.core.C11Lock diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index b052501c6b24..696e271a7231 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2576,7 +2576,15 @@ enum CXCursorKind { */ CXCursor_OMPCanonicalLoop = 289, - CXCursor_LastStmt = CXCursor_OMPCanonicalLoop, + /** OpenMP interop directive. + */ + CXCursor_OMPInteropDirective = 290, + + /** OpenMP dispatch directive. + */ + CXCursor_OMPDispatchDirective = 291, + + CXCursor_LastStmt = CXCursor_OMPDispatchDirective, /** * Cursor that represents the translation unit itself. diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index af2979d87438..d0ce47b6bbd5 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -604,6 +604,9 @@ class ASTContext : public RefCountedBase { std::unique_ptr InterpContext; std::unique_ptr ParentMapCtx; + /// Keeps track of the deallocated DeclListNodes for future reuse. + DeclListNode *ListNodeFreeList = nullptr; + public: IdentifierTable &Idents; SelectorTable &Selectors; @@ -655,6 +658,24 @@ class ASTContext : public RefCountedBase { } void Deallocate(void *Ptr) const {} + /// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList + /// pool. + DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) { + if (DeclListNode *Alloc = ListNodeFreeList) { + ListNodeFreeList = Alloc->Rest.dyn_cast(); + Alloc->D = ND; + Alloc->Rest = nullptr; + return Alloc; + } + return new (*this) DeclListNode(ND); + } + /// Deallcates a \c DeclListNode by returning it to the \c ListNodeFreeList + /// pool. + void DeallocateDeclListNode(DeclListNode *N) { + N->Rest = ListNodeFreeList; + ListNodeFreeList = N; + } + /// Return the total amount of physical memory allocated for representing /// AST nodes and type information. size_t getASTAllocatedMemory() const { diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h index 630d220deff7..17e673a8471a 100644 --- a/clang/include/clang/AST/ASTImporter.h +++ b/clang/include/clang/AST/ASTImporter.h @@ -344,6 +344,12 @@ class TypeSourceInfo; Import(ExprWithCleanups::CleanupObject From); /// Import the given type from the "from" context into the "to" + /// context. + /// + /// \returns The equivalent type in the "to" context, or the import error. + llvm::Expected Import(const Type *FromT); + + /// Import the given qualified type from the "from" context into the "to" /// context. A null type is imported as a null type (no error). /// /// \returns The equivalent type in the "to" context, or the import error. diff --git a/clang/include/clang/AST/CXXInheritance.h b/clang/include/clang/AST/CXXInheritance.h index 709f08bff82a..946b9e318baa 100644 --- a/clang/include/clang/AST/CXXInheritance.h +++ b/clang/include/clang/AST/CXXInheritance.h @@ -76,9 +76,8 @@ class CXXBasePath : public SmallVector { CXXBasePath() = default; - /// The set of declarations found inside this base class - /// subobject. - DeclContext::lookup_result Decls; + /// The declarations found inside this base class subobject. + DeclContext::lookup_iterator Decls; void clear() { SmallVectorImpl::clear(); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 47c282f0a63d..66dda5c9761a 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -579,6 +579,16 @@ class NamespaceDecl : public NamedDecl, public DeclContext, AnonOrFirstNamespaceAndInline.setInt(Inline); } + /// Returns true if the inline qualifier for \c Name is redundant. + bool isRedundantInlineQualifierFor(DeclarationName Name) const { + if (!isInline()) + return false; + auto X = lookup(Name); + auto Y = getParent()->lookup(Name); + return std::distance(X.begin(), X.end()) == + std::distance(Y.begin(), Y.end()); + } + /// Get the original (first) namespace declaration. NamespaceDecl *getOriginalNamespace(); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 15eb29f72539..084ecb5389ce 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -1220,65 +1220,110 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { void print(raw_ostream &OS) const override; }; +} // namespace clang -/// The results of name lookup within a DeclContext. This is either a -/// single result (with no stable storage) or a collection of results (with -/// stable storage provided by the lookup table). -class DeclContextLookupResult { - using ResultTy = ArrayRef; - - ResultTy Result; - - // If there is only one lookup result, it would be invalidated by - // reallocations of the name table, so store it separately. - NamedDecl *Single = nullptr; - - static NamedDecl *const SingleElementDummyList; +// Required to determine the layout of the PointerUnion before +// seeing the NamedDecl definition being first used in DeclListNode::operator*. +namespace llvm { + template <> struct PointerLikeTypeTraits<::clang::NamedDecl *> { + static inline void *getAsVoidPointer(::clang::NamedDecl *P) { return P; } + static inline ::clang::NamedDecl *getFromVoidPointer(void *P) { + return static_cast<::clang::NamedDecl *>(P); + } + static constexpr int NumLowBitsAvailable = 3; + }; +} +namespace clang { +/// A list storing NamedDecls in the lookup tables. +class DeclListNode { + friend class ASTContext; // allocate, deallocate nodes. + friend class StoredDeclsList; public: - DeclContextLookupResult() = default; - DeclContextLookupResult(ArrayRef Result) - : Result(Result) {} - DeclContextLookupResult(NamedDecl *Single) - : Result(SingleElementDummyList), Single(Single) {} - - class iterator; - - using IteratorBase = - llvm::iterator_adaptor_base; - - class iterator : public IteratorBase { - value_type SingleElement; + using Decls = llvm::PointerUnion; + class iterator { + friend class DeclContextLookupResult; + friend class StoredDeclsList; + Decls Ptr; + iterator(Decls Node) : Ptr(Node) { } public: - explicit iterator(pointer Pos, value_type Single = nullptr) - : IteratorBase(Pos), SingleElement(Single) {} + using difference_type = ptrdiff_t; + using value_type = NamedDecl*; + using pointer = void; + using reference = value_type; + using iterator_category = std::forward_iterator_tag; + + iterator() = default; reference operator*() const { - return SingleElement ? SingleElement : IteratorBase::operator*(); + assert(Ptr && "dereferencing end() iterator"); + if (DeclListNode *CurNode = Ptr.dyn_cast()) + return CurNode->D; + return Ptr.get(); } + void operator->() const { } // Unsupported. + bool operator==(const iterator &X) const { return Ptr == X.Ptr; } + bool operator!=(const iterator &X) const { return Ptr != X.Ptr; } + inline iterator &operator++() { // ++It + assert(!Ptr.isNull() && "Advancing empty iterator"); + + if (DeclListNode *CurNode = Ptr.dyn_cast()) + Ptr = CurNode->Rest; + else + Ptr = nullptr; + return *this; + } + iterator operator++(int) { // It++ + iterator temp = *this; + ++(*this); + return temp; + } + // Enables the pattern for (iterator I =..., E = I.end(); I != E; ++I) + iterator end() { return iterator(); } }; +private: + NamedDecl *D = nullptr; + Decls Rest = nullptr; + DeclListNode(NamedDecl *ND) : D(ND) {} +}; + +/// The results of name lookup within a DeclContext. +class DeclContextLookupResult { + using Decls = DeclListNode::Decls; + /// When in collection form, this is what the Data pointer points to. + Decls Result; + +public: + DeclContextLookupResult() = default; + DeclContextLookupResult(Decls Result) : Result(Result) {} + + using iterator = DeclListNode::iterator; using const_iterator = iterator; - using pointer = iterator::pointer; using reference = iterator::reference; - iterator begin() const { return iterator(Result.begin(), Single); } - iterator end() const { return iterator(Result.end(), Single); } - - bool empty() const { return Result.empty(); } - pointer data() const { return Single ? &Single : Result.data(); } - size_t size() const { return Single ? 1 : Result.size(); } - reference front() const { return Single ? Single : Result.front(); } - reference back() const { return Single ? Single : Result.back(); } - reference operator[](size_t N) const { return Single ? Single : Result[N]; } - - // FIXME: Remove this from the interface - DeclContextLookupResult slice(size_t N) const { - DeclContextLookupResult Sliced = Result.slice(N); - Sliced.Single = Single; - return Sliced; + iterator begin() { return iterator(Result); } + iterator end() { return iterator(); } + const_iterator begin() const { + return const_cast(this)->begin(); + } + const_iterator end() const { return iterator(); } + + bool empty() const { return Result.isNull(); } + bool isSingleResult() const { return Result.dyn_cast(); } + reference front() const { return *begin(); } + + // Find the first declaration of the given type in the list. Note that this + // is not in general the earliest-declared declaration, and should only be + // used when it's not possible for there to be more than one match or where + // it doesn't matter which one is found. + template T *find_first() const { + for (auto *D : *this) + if (T *Decl = dyn_cast(D)) + return Decl; + + return nullptr; } }; diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index e6a4cd4381e4..3556044098c4 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H #define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -21,7 +22,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/SmallVector.h" #include #include @@ -31,231 +31,287 @@ class DependentDiagnostic; /// An array of decls optimized for the common case of only containing /// one entry. -struct StoredDeclsList { - /// When in vector form, this is what the Data pointer points to. - using DeclsTy = SmallVector; +class StoredDeclsList { + using Decls = DeclListNode::Decls; /// A collection of declarations, with a flag to indicate if we have /// further external declarations. - using DeclsAndHasExternalTy = llvm::PointerIntPair; + using DeclsAndHasExternalTy = llvm::PointerIntPair; /// The stored data, which will be either a pointer to a NamedDecl, - /// or a pointer to a vector with a flag to indicate if there are further + /// or a pointer to a list with a flag to indicate if there are further /// external declarations. - llvm::PointerUnion Data; + DeclsAndHasExternalTy Data; + + template + void erase_if(Fn ShouldErase) { + Decls List = Data.getPointer(); + if (!List) + return; + ASTContext &C = getASTContext(); + DeclListNode::Decls NewHead = nullptr; + DeclListNode::Decls *NewLast = nullptr; + DeclListNode::Decls *NewTail = &NewHead; + while (true) { + if (!ShouldErase(*DeclListNode::iterator(List))) { + NewLast = NewTail; + *NewTail = List; + if (auto *Node = List.dyn_cast()) { + NewTail = &Node->Rest; + List = Node->Rest; + } else { + break; + } + } else if (DeclListNode *N = List.dyn_cast()) { + List = N->Rest; + C.DeallocateDeclListNode(N); + } else { + // We're discarding the last declaration in the list. The last node we + // want to keep (if any) will be of the form DeclListNode(D, ); + // replace it with just D. + if (NewLast) { + DeclListNode *Node = NewLast->get(); + *NewLast = Node->D; + C.DeallocateDeclListNode(Node); + } + break; + } + } + Data.setPointer(NewHead); + + assert(llvm::find_if(getLookupResult(), ShouldErase) == + getLookupResult().end() && "Still exists!"); + } + + void erase(NamedDecl *ND) { + erase_if([ND](NamedDecl *D) { return D == ND; }); + } public: StoredDeclsList() = default; StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) { - RHS.Data = (NamedDecl *)nullptr; + RHS.Data.setPointer(nullptr); + RHS.Data.setInt(0); + } + + void MaybeDeallocList() { + if (isNull()) + return; + // If this is a list-form, free the list. + ASTContext &C = getASTContext(); + Decls List = Data.getPointer(); + while (DeclListNode *ToDealloc = List.dyn_cast()) { + List = ToDealloc->Rest; + C.DeallocateDeclListNode(ToDealloc); + } } ~StoredDeclsList() { - // If this is a vector-form, free the vector. - if (DeclsTy *Vector = getAsVector()) - delete Vector; + MaybeDeallocList(); } StoredDeclsList &operator=(StoredDeclsList &&RHS) { - if (DeclsTy *Vector = getAsVector()) - delete Vector; + MaybeDeallocList(); + Data = RHS.Data; - RHS.Data = (NamedDecl *)nullptr; + RHS.Data.setPointer(nullptr); + RHS.Data.setInt(0); return *this; } - bool isNull() const { return Data.isNull(); } + bool isNull() const { return Data.getPointer().isNull(); } - NamedDecl *getAsDecl() const { - return Data.dyn_cast(); + ASTContext &getASTContext() { + assert(!isNull() && "No ASTContext."); + if (NamedDecl *ND = getAsDecl()) + return ND->getASTContext(); + return getAsList()->D->getASTContext(); } - DeclsAndHasExternalTy getAsVectorAndHasExternal() const { - return Data.dyn_cast(); + DeclsAndHasExternalTy getAsListAndHasExternal() const { return Data; } + + NamedDecl *getAsDecl() const { + return getAsListAndHasExternal().getPointer().dyn_cast(); } - DeclsTy *getAsVector() const { - return getAsVectorAndHasExternal().getPointer(); + DeclListNode *getAsList() const { + return getAsListAndHasExternal().getPointer().dyn_cast(); } bool hasExternalDecls() const { - return getAsVectorAndHasExternal().getInt(); + return getAsListAndHasExternal().getInt(); } void setHasExternalDecls() { - if (DeclsTy *Vec = getAsVector()) - Data = DeclsAndHasExternalTy(Vec, true); - else { - DeclsTy *VT = new DeclsTy(); - if (NamedDecl *OldD = getAsDecl()) - VT->push_back(OldD); - Data = DeclsAndHasExternalTy(VT, true); - } - } - - void setOnlyValue(NamedDecl *ND) { - assert(!getAsVector() && "Not inline"); - Data = ND; - // Make sure that Data is a plain NamedDecl* so we can use its address - // at getLookupResult. - assert(*(NamedDecl **)&Data == ND && - "PointerUnion mangles the NamedDecl pointer!"); + Data.setInt(1); } void remove(NamedDecl *D) { assert(!isNull() && "removing from empty list"); - if (NamedDecl *Singleton = getAsDecl()) { - assert(Singleton == D && "list is different singleton"); - (void)Singleton; - Data = (NamedDecl *)nullptr; - return; - } - - DeclsTy &Vec = *getAsVector(); - DeclsTy::iterator I = llvm::find(Vec, D); - assert(I != Vec.end() && "list does not contain decl"); - Vec.erase(I); - - assert(llvm::find(Vec, D) == Vec.end() && "list still contains decl"); + erase(D); } - /// Remove any declarations which were imported from an external - /// AST source. + /// Remove any declarations which were imported from an external AST source. void removeExternalDecls() { - if (isNull()) { - // Nothing to do. - } else if (NamedDecl *Singleton = getAsDecl()) { - if (Singleton->isFromASTFile()) - *this = StoredDeclsList(); - } else { - DeclsTy &Vec = *getAsVector(); - Vec.erase(std::remove_if(Vec.begin(), Vec.end(), - [](Decl *D) { return D->isFromASTFile(); }), - Vec.end()); - // Don't have any external decls any more. - Data = DeclsAndHasExternalTy(&Vec, false); - } + erase_if([](NamedDecl *ND) { return ND->isFromASTFile(); }); + + // Don't have any pending external decls any more. + Data.setInt(0); } - /// getLookupResult - Return an array of all the decls that this list - /// represents. - DeclContext::lookup_result getLookupResult() { - if (isNull()) - return DeclContext::lookup_result(); + void replaceExternalDecls(ArrayRef Decls) { + // Remove all declarations that are either external or are replaced with + // external declarations. + erase_if([Decls](NamedDecl *ND) { + if (ND->isFromASTFile()) + return true; + for (NamedDecl *D : Decls) + if (D->declarationReplaces(ND, /*IsKnownNewer=*/false)) + return true; + return false; + }); - // If we have a single NamedDecl, return it. - if (NamedDecl *ND = getAsDecl()) { - assert(!isNull() && "Empty list isn't allowed"); + // Don't have any pending external decls any more. + Data.setInt(0); + + if (Decls.empty()) + return; + + // Convert Decls into a list, in order. + ASTContext &C = Decls.front()->getASTContext(); + DeclListNode::Decls DeclsAsList = Decls.back(); + for (size_t I = Decls.size() - 1; I != 0; --I) { + DeclListNode *Node = C.AllocateDeclListNode(Decls[I - 1]); + Node->Rest = DeclsAsList; + DeclsAsList = Node; + } - // Data is a raw pointer to a NamedDecl*, return it. - return DeclContext::lookup_result(ND); + DeclListNode::Decls Head = Data.getPointer(); + if (Head.isNull()) { + Data.setPointer(DeclsAsList); + return; } - assert(getAsVector() && "Must have a vector at this point"); - DeclsTy &Vector = *getAsVector(); + // Find the end of the existing list. + // FIXME: It would be possible to preserve information from erase_if to + // avoid this rescan looking for the end of the list. + DeclListNode::Decls *Tail = &Head; + while (DeclListNode *Node = Tail->dyn_cast()) + Tail = &Node->Rest; + + // Append the Decls. + DeclListNode *Node = C.AllocateDeclListNode(Tail->get()); + Node->Rest = DeclsAsList; + *Tail = Node; + Data.setPointer(Head); + } - // Otherwise, we have a range result. - return DeclContext::lookup_result(Vector); + /// Return an array of all the decls that this list represents. + DeclContext::lookup_result getLookupResult() const { + return DeclContext::lookup_result(Data.getPointer()); } - /// HandleRedeclaration - If this is a redeclaration of an existing decl, - /// replace the old one with D and return true. Otherwise return false. - bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer) { + /// If this is a redeclaration of an existing decl, replace the old one with + /// D. Otherwise, append D. + void addOrReplaceDecl(NamedDecl *D) { + const bool IsKnownNewer = true; + + if (isNull()) { + Data.setPointer(D); + return; + } + // Most decls only have one entry in their list, special case it. if (NamedDecl *OldD = getAsDecl()) { - if (!D->declarationReplaces(OldD, IsKnownNewer)) - return false; - setOnlyValue(D); - return true; + if (D->declarationReplaces(OldD, IsKnownNewer)) { + Data.setPointer(D); + return; + } + + // Add D after OldD. + ASTContext &C = D->getASTContext(); + DeclListNode *Node = C.AllocateDeclListNode(OldD); + Node->Rest = D; + Data.setPointer(Node); + return; } + // FIXME: Move the assert before the single decl case when we fix the + // duplication coming from the ASTReader reading builtin types. + assert(!llvm::is_contained(getLookupResult(), D) && "Already exists!"); // Determine if this declaration is actually a redeclaration. - DeclsTy &Vec = *getAsVector(); - for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); - OD != ODEnd; ++OD) { - NamedDecl *OldD = *OD; - if (D->declarationReplaces(OldD, IsKnownNewer)) { - *OD = D; - return true; + for (DeclListNode *N = getAsList(); /*return in loop*/; + N = N->Rest.dyn_cast()) { + if (D->declarationReplaces(N->D, IsKnownNewer)) { + N->D = D; + return; + } + if (auto *ND = N->Rest.dyn_cast()) { + if (D->declarationReplaces(ND, IsKnownNewer)) { + N->Rest = D; + return; + } + + // Add D after ND. + ASTContext &C = D->getASTContext(); + DeclListNode *Node = C.AllocateDeclListNode(ND); + N->Rest = Node; + Node->Rest = D; + return; } } - - return false; } - /// AddSubsequentDecl - This is called on the second and later decl when it is - /// not a redeclaration to merge it into the appropriate place in our list. - void AddSubsequentDecl(NamedDecl *D) { - assert(!isNull() && "don't AddSubsequentDecl when we have no decls"); + /// Add a declaration to the list without checking if it replaces anything. + void prependDeclNoReplace(NamedDecl *D) { + if (isNull()) { + Data.setPointer(D); + return; + } - // If this is the second decl added to the list, convert this to vector - // form. - if (NamedDecl *OldD = getAsDecl()) { - DeclsTy *VT = new DeclsTy(); - VT->push_back(OldD); - Data = DeclsAndHasExternalTy(VT, false); + ASTContext &C = D->getASTContext(); + DeclListNode *Node = C.AllocateDeclListNode(D); + Node->Rest = Data.getPointer(); + Data.setPointer(Node); + } + + LLVM_DUMP_METHOD void dump() const { + Decls D = Data.getPointer(); + if (!D) { + llvm::errs() << "\n"; + return; } - DeclsTy &Vec = *getAsVector(); - - // Using directives end up in a special entry which contains only - // other using directives, so all this logic is wasted for them. - // But avoiding the logic wastes time in the far-more-common case - // that we're *not* adding a new using directive. - - // Tag declarations always go at the end of the list so that an - // iterator which points at the first tag will start a span of - // decls that only contains tags. - if (D->hasTagIdentifierNamespace()) - Vec.push_back(D); - - // Resolved using declarations go at the front of the list so that - // they won't show up in other lookup results. Unresolved using - // declarations (which are always in IDNS_Using | IDNS_Ordinary) - // follow that so that the using declarations will be contiguous. - else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { - DeclsTy::iterator I = Vec.begin(); - if (D->getIdentifierNamespace() != Decl::IDNS_Using) { - while (I != Vec.end() && - (*I)->getIdentifierNamespace() == Decl::IDNS_Using) - ++I; + while (true) { + if (auto *Node = D.dyn_cast()) { + llvm::errs() << '[' << Node->D << "] -> "; + D = Node->Rest; + } else { + llvm::errs() << '[' << D.get() << "]\n"; + return; } - Vec.insert(I, D); - - // All other declarations go at the end of the list, but before any - // tag declarations. But we can be clever about tag declarations - // because there can only ever be one in a scope. - } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) { - NamedDecl *TagD = Vec.back(); - Vec.back() = D; - Vec.push_back(TagD); - } else - Vec.push_back(D); + } } }; class StoredDeclsMap : public llvm::SmallDenseMap { -public: - static void DestroyAll(StoredDeclsMap *Map, bool Dependent); - -private: friend class ASTContext; // walks the chain deleting these friend class DeclContext; llvm::PointerIntPair Previous; +public: + static void DestroyAll(StoredDeclsMap *Map, bool Dependent); }; class DependentStoredDeclsMap : public StoredDeclsMap { -public: - DependentStoredDeclsMap() = default; - -private: friend class DeclContext; // iterates over diagnostics friend class DependentDiagnostic; DependentDiagnostic *FirstDiagnostic = nullptr; +public: + DependentStoredDeclsMap() = default; }; } // namespace clang diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 958f2b9e0e6f..f71eb15feea2 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -7366,15 +7366,244 @@ class OMPOrderClause final : public OMPClause { } }; +/// This represents the 'init' clause in '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp interop init(target:obj) +/// \endcode +class OMPInitClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Location of interop variable. + SourceLocation VarLoc; + + bool IsTarget = false; + bool IsTargetSync = false; + + void setInteropVar(Expr *E) { varlist_begin()[0] = E; } + + void setIsTarget(bool V) { IsTarget = V; } + + void setIsTargetSync(bool V) { IsTargetSync = V; } + + /// Sets the location of the interop variable. + void setVarLoc(SourceLocation Loc) { VarLoc = Loc; } + + /// Build 'init' clause. + /// + /// \param IsTarget Uses the 'target' interop-type. + /// \param IsTargetSync Uses the 'targetsync' interop-type. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param VarLoc Location of the interop variable. + /// \param EndLoc Ending location of the clause. + /// \param N Number of expressions. + OMPInitClause(bool IsTarget, bool IsTargetSync, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation VarLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause(llvm::omp::OMPC_init, StartLoc, + LParenLoc, EndLoc, N), + VarLoc(VarLoc), IsTarget(IsTarget), IsTargetSync(IsTargetSync) {} + + /// Build an empty clause. + OMPInitClause(unsigned N) + : OMPVarListClause(llvm::omp::OMPC_init, SourceLocation(), + SourceLocation(), SourceLocation(), N) { + } + +public: + /// Creates a fully specified clause. + /// + /// \param C AST context. + /// \param InteropVar The interop variable. + /// \param PrefExprs The list of preference expressions. + /// \param IsTarget Uses the 'target' interop-type. + /// \param IsTargetSync Uses the 'targetsync' interop-type. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param VarLoc Location of the interop variable. + /// \param EndLoc Ending location of the clause. + static OMPInitClause *Create(const ASTContext &C, Expr *InteropVar, + ArrayRef PrefExprs, bool IsTarget, + bool IsTargetSync, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation VarLoc, + SourceLocation EndLoc); + + /// Creates an empty clause with \a N expressions. + /// + /// \param C AST context. + /// \param N Number of expression items. + static OMPInitClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// Returns the location of the interop variable. + SourceLocation getVarLoc() const { return VarLoc; } + + /// Returns the interop variable. + Expr *getInteropVar() { return varlist_begin()[0]; } + const Expr *getInteropVar() const { return varlist_begin()[0]; } + + /// Returns true is interop-type 'target' is used. + bool getIsTarget() const { return IsTarget; } + + /// Returns true is interop-type 'targetsync' is used. + bool getIsTargetSync() const { return IsTargetSync; } + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + using prefs_iterator = MutableArrayRef::iterator; + using const_prefs_iterator = ArrayRef::iterator; + using prefs_range = llvm::iterator_range; + using const_prefs_range = llvm::iterator_range; + + prefs_range prefs() { + return prefs_range(reinterpret_cast(std::next(varlist_begin())), + reinterpret_cast(varlist_end())); + } + + const_prefs_range prefs() const { + auto Prefs = const_cast(this)->prefs(); + return const_prefs_range(Prefs.begin(), Prefs.end()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_init; + } +}; + +/// This represents the 'use' clause in '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp interop use(obj) +/// \endcode +class OMPUseClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Location of interop variable. + SourceLocation VarLoc; + + /// The interop variable. + Stmt *InteropVar = nullptr; + + /// Set the interop variable. + void setInteropVar(Expr *E) { InteropVar = E; } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Sets the location of the interop variable. + void setVarLoc(SourceLocation Loc) { VarLoc = Loc; } + +public: + /// Build 'use' clause with and interop variable expression \a InteropVar. + /// + /// \param InteropVar The interop variable. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param VarLoc Location of the interop variable. + /// \param EndLoc Ending location of the clause. + OMPUseClause(Expr *InteropVar, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation VarLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_use, StartLoc, EndLoc), LParenLoc(LParenLoc), + VarLoc(VarLoc), InteropVar(InteropVar) {} + + /// Build an empty clause. + OMPUseClause() + : OMPClause(llvm::omp::OMPC_use, SourceLocation(), SourceLocation()) {} + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns the location of the interop variable. + SourceLocation getVarLoc() const { return VarLoc; } + + /// Returns the interop variable. + Expr *getInteropVar() const { return cast(InteropVar); } + + child_range children() { return child_range(&InteropVar, &InteropVar + 1); } + + const_child_range children() const { + return const_child_range(&InteropVar, &InteropVar + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_use; + } +}; + /// This represents 'destroy' clause in the '#pragma omp depobj' -/// directive. +/// directive or the '#pragma omp interop' directive.. /// /// \code /// #pragma omp depobj(a) destroy +/// #pragma omp interop destroy(obj) /// \endcode -/// In this example directive '#pragma omp depobj' has 'destroy' clause. +/// In these examples directive '#pragma omp depobj' and '#pragma omp interop' +/// have a 'destroy' clause. The 'interop' directive includes an object. class OMPDestroyClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Location of interop variable. + SourceLocation VarLoc; + + /// The interop variable. + Stmt *InteropVar = nullptr; + + /// Set the interop variable. + void setInteropVar(Expr *E) { InteropVar = E; } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Sets the location of the interop variable. + void setVarLoc(SourceLocation Loc) { VarLoc = Loc; } + public: + /// Build 'destroy' clause with an interop variable expression \a InteropVar. + /// + /// \param InteropVar The interop variable. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param VarLoc Location of the interop variable. + /// \param EndLoc Ending location of the clause. + OMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation VarLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc), + LParenLoc(LParenLoc), VarLoc(VarLoc), InteropVar(InteropVar) {} + /// Build 'destroy' clause. /// /// \param StartLoc Starting location of the clause. @@ -7387,11 +7616,24 @@ class OMPDestroyClause final : public OMPClause { : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { } + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns the location of the interop variable. + SourceLocation getVarLoc() const { return VarLoc; } + + /// Returns the interop variable. + Expr *getInteropVar() const { return cast_or_null(InteropVar); } + child_range children() { + if (InteropVar) + return child_range(&InteropVar, &InteropVar + 1); return child_range(child_iterator(), child_iterator()); } const_child_range children() const { + if (InteropVar) + return const_child_range(&InteropVar, &InteropVar + 1); return const_child_range(const_child_iterator(), const_child_iterator()); } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 8ec2c882a9f2..23864819bc07 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2968,6 +2968,12 @@ DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective, DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPInteropDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPDispatchDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + // OpenMP clauses. template bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { @@ -3195,7 +3201,20 @@ bool RecursiveASTVisitor::VisitOMPNogroupClause(OMPNogroupClause *) { } template -bool RecursiveASTVisitor::VisitOMPDestroyClause(OMPDestroyClause *) { +bool RecursiveASTVisitor::VisitOMPInitClause(OMPInitClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPUseClause(OMPUseClause *C) { + TRY_TO(TraverseStmt(C->getInteropVar())); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPDestroyClause(OMPDestroyClause *C) { + TRY_TO(TraverseStmt(C->getInteropVar())); return true; } diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 32b7778aa487..a59b36c302a3 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -5086,6 +5086,125 @@ class OMPScanDirective final : public OMPExecutableDirective { } }; +/// This represents '#pragma omp interop' directive. +/// +/// \code +/// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait +/// \endcode +/// In this example directive '#pragma omp interop' has +/// clauses 'init', 'device', 'depend' and 'nowait'. +/// +class OMPInteropDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive. + /// \param EndLoc Ending location of the directive. + /// + OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(OMPInteropDirectiveClass, + llvm::omp::OMPD_interop, StartLoc, EndLoc) {} + + /// Build an empty directive. + /// + explicit OMPInteropDirective() + : OMPExecutableDirective(OMPInteropDirectiveClass, + llvm::omp::OMPD_interop, SourceLocation(), + SourceLocation()) {} + +public: + /// Creates directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses The directive's clauses. + /// + static OMPInteropDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses); + + /// Creates an empty directive. + /// + /// \param C AST context. + /// + static OMPInteropDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPInteropDirectiveClass; + } +}; + +/// This represents '#pragma omp dispatch' directive. +/// +/// \code +/// #pragma omp dispatch device(dnum) +/// \endcode +/// This example shows a directive '#pragma omp dispatch' with a +/// device clause with variable 'dnum'. +/// +class OMPDispatchDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// The location of the target-call. + SourceLocation TargetCallLoc; + + /// Set the location of the target-call. + void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } + + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(OMPDispatchDirectiveClass, + llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} + + /// Build an empty directive. + /// + explicit OMPDispatchDirective() + : OMPExecutableDirective(OMPDispatchDirectiveClass, + llvm::omp::OMPD_dispatch, SourceLocation(), + SourceLocation()) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param TargetCallLoc Location of the target-call. + /// + static OMPDispatchDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef Clauses, Stmt *AssociatedStmt, + SourceLocation TargetCallLoc); + + /// Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPDispatchDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + /// Return location of target-call. + SourceLocation getTargetCallLoc() const { return TargetCallLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDispatchDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 885bc74ad3ea..fd0e9d6d7c1f 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2162,6 +2162,17 @@ extern const internal::VariadicDynCastAllOfMatcher breakStmt; extern const internal::VariadicDynCastAllOfMatcher continueStmt; +/// Matches co_return statements. +/// +/// Given +/// \code +/// while (true) { co_return; } +/// \endcode +/// coreturnStmt() +/// matches 'co_return' +extern const internal::VariadicDynCastAllOfMatcher + coreturnStmt; + /// Matches return statements. /// /// Given @@ -2379,6 +2390,30 @@ extern const internal::VariadicDynCastAllOfMatcher extern const internal::VariadicDynCastAllOfMatcher compoundLiteralExpr; +/// Matches co_await expressions. +/// +/// Given +/// \code +/// co_await 1; +/// \endcode +/// coawaitExpr() +/// matches 'co_await 1' +extern const internal::VariadicDynCastAllOfMatcher + coawaitExpr; +/// Matches co_await expressions where the type of the promise is dependent +extern const internal::VariadicDynCastAllOfMatcher + dependentCoawaitExpr; +/// Matches co_yield expressions. +/// +/// Given +/// \code +/// co_yield 1; +/// \endcode +/// coyieldExpr() +/// matches 'co_yield 1' +extern const internal::VariadicDynCastAllOfMatcher + coyieldExpr; + /// Matches nullptr literal. extern const internal::VariadicDynCastAllOfMatcher cxxNullPtrLiteralExpr; @@ -5217,7 +5252,7 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, /// void f() {} /// void g(); /// \endcode -/// hasAnyBody(functionDecl()) +/// functionDecl(hasAnyBody(compoundStmt())) /// matches both 'void f();' /// and 'void f() {}' /// with compoundStmt() diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 19b8941746dd..e8f427bafa25 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -541,12 +541,18 @@ class Matcher { /// Convert \c this into a \c Matcher by applying dyn_cast<> to the /// argument. /// \c To must be a base class of \c T. - template - Matcher dynCastTo() const { + template Matcher dynCastTo() const LLVM_LVALUE_FUNCTION { static_assert(std::is_base_of::value, "Invalid dynCast call."); return Matcher(Implementation); } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + template Matcher dynCastTo() && { + static_assert(std::is_base_of::value, "Invalid dynCast call."); + return Matcher(std::move(Implementation)); + } +#endif + /// Forwards the call to the underlying MatcherInterface pointer. bool matches(const T &Node, ASTMatchFinder *Finder, @@ -563,7 +569,13 @@ class Matcher { /// /// The returned matcher keeps the same restrictions as \c this and remembers /// that it is meant to support nodes of type \c T. - operator DynTypedMatcher() const { return Implementation; } + operator DynTypedMatcher() const LLVM_LVALUE_FUNCTION { + return Implementation; + } + +#if LLVM_HAS_RVALUE_REFERENCE_THIS + operator DynTypedMatcher() && { return std::move(Implementation); } +#endif /// Allows the conversion of a \c Matcher to a \c /// Matcher. @@ -870,7 +882,7 @@ class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface { Names, getOperatorSpelling(Node.getOverloadedOperator())); } - const std::vector Names; + std::vector Names; }; /// Matches named declarations with a specific name. @@ -904,8 +916,8 @@ class HasNameMatcher : public SingleNodeMatcherInterface { /// It is slower but simple and works on all cases. bool matchesNodeFullSlow(const NamedDecl &Node) const; - const bool UseUnqualifiedMatch; - const std::vector Names; + bool UseUnqualifiedMatch; + std::vector Names; }; /// Trampoline function to use VariadicFunction<> to construct a @@ -926,7 +938,7 @@ class HasDeclarationMatcher : public MatcherInterface { static_assert(std::is_same>::value, "instantiated with wrong types"); - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; public: explicit HasDeclarationMatcher(const Matcher &InnerMatcher) @@ -1315,20 +1327,36 @@ template class VariadicOperatorMatcher { VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params) : Op(Op), Params(std::forward(Params)...) {} - template operator Matcher() const { + template operator Matcher() const LLVM_LVALUE_FUNCTION { return DynTypedMatcher::constructVariadic( Op, ASTNodeKind::getFromNodeKind(), getMatchers(std::index_sequence_for())) .template unconditionalConvertTo(); } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + template operator Matcher() && { + return DynTypedMatcher::constructVariadic( + Op, ASTNodeKind::getFromNodeKind(), + getMatchers(std::index_sequence_for())) + .template unconditionalConvertTo(); + } +#endif private: // Helper method to unpack the tuple into a vector. template - std::vector getMatchers(std::index_sequence) const { + std::vector + getMatchers(std::index_sequence) const LLVM_LVALUE_FUNCTION { return {Matcher(std::get(Params))...}; } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + template + std::vector getMatchers(std::index_sequence) && { + return {Matcher(std::get(std::move(Params)))...}; + } +#endif + const DynTypedMatcher::VariadicOperator Op; std::tuple Params; }; @@ -1386,8 +1414,7 @@ struct MapAnyOfMatcherImpl { internal::DynTypedMatcher::VO_AnyOf}, applyMatcher( [&](auto... Matcher) { - return std::make_tuple(Matcher( - std::forward(InnerMatcher)...)...); + return std::make_tuple(Matcher(InnerMatcher...)...); }, std::tuple< VariadicDynCastAllOfMatcher...>()))); @@ -1418,12 +1445,18 @@ class ArgumentAdaptingMatcherFuncAdaptor { using ReturnTypes = ToTypes; - template operator Matcher() const { + template operator Matcher() const LLVM_LVALUE_FUNCTION { return Matcher(new ArgumentAdapterT(InnerMatcher)); } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + template operator Matcher() && { + return Matcher(new ArgumentAdapterT(std::move(InnerMatcher))); + } +#endif + private: - const Matcher InnerMatcher; + Matcher InnerMatcher; }; /// Converts a \c Matcher to a matcher of desired type \c To by @@ -1465,7 +1498,7 @@ struct ArgumentAdaptingMatcherFunc { }; template class TraversalMatcher : public MatcherInterface { - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; clang::TraversalKind Traversal; public: @@ -1491,13 +1524,22 @@ template class TraversalWrapper { TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher) : TK(TK), InnerMatcher(InnerMatcher) {} - template operator Matcher() const { + template operator Matcher() const LLVM_LVALUE_FUNCTION { return internal::DynTypedMatcher::constructRestrictedWrapper( new internal::TraversalMatcher(TK, InnerMatcher), ASTNodeKind::getFromNodeKind()) .template unconditionalConvertTo(); } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + template operator Matcher() && { + return internal::DynTypedMatcher::constructRestrictedWrapper( + new internal::TraversalMatcher(TK, std::move(InnerMatcher)), + ASTNodeKind::getFromNodeKind()) + .template unconditionalConvertTo(); + } +#endif + private: TraversalKind TK; MatcherType InnerMatcher; @@ -1523,15 +1565,23 @@ class PolymorphicMatcher { using ReturnTypes = typename ExtractFunctionArgMeta::type; - template - operator Matcher() const { + template operator Matcher() const LLVM_LVALUE_FUNCTION { static_assert(TypeListContainsSuperOf::value, "right polymorphic conversion"); return Matcher(new_from_tuple>(Params)); } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + template operator Matcher() && { + static_assert(TypeListContainsSuperOf::value, + "right polymorphic conversion"); + return Matcher( + new_from_tuple>(std::move(Params))); + } +#endif + private: - const std::tuple Params; + std::tuple Params; }; /// Matches nodes of type T that have child nodes of type ChildT for @@ -1540,7 +1590,7 @@ class PolymorphicMatcher { /// ChildT must be an AST base type. template class HasMatcher : public MatcherInterface { - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; public: explicit HasMatcher(const Matcher &InnerMatcher) @@ -1563,7 +1613,7 @@ class ForEachMatcher : public MatcherInterface { static_assert(IsBaseType::value, "for each only accepts base type matcher"); - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; public: explicit ForEachMatcher(const Matcher &InnerMatcher) @@ -1593,7 +1643,7 @@ class HasDescendantMatcher : public MatcherInterface { static_assert(IsBaseType::value, "has descendant only accepts base type matcher"); - const DynTypedMatcher DescendantMatcher; + DynTypedMatcher DescendantMatcher; public: explicit HasDescendantMatcher(const Matcher &DescendantMatcher) @@ -1615,7 +1665,7 @@ class HasParentMatcher : public MatcherInterface { static_assert(IsBaseType::value, "has parent only accepts base type matcher"); - const DynTypedMatcher ParentMatcher; + DynTypedMatcher ParentMatcher; public: explicit HasParentMatcher(const Matcher &ParentMatcher) @@ -1637,7 +1687,7 @@ class HasAncestorMatcher : public MatcherInterface { static_assert(IsBaseType::value, "has ancestor only accepts base type matcher"); - const DynTypedMatcher AncestorMatcher; + DynTypedMatcher AncestorMatcher; public: explicit HasAncestorMatcher(const Matcher &AncestorMatcher) @@ -1661,7 +1711,7 @@ class ForEachDescendantMatcher : public MatcherInterface { static_assert(IsBaseType::value, "for each descendant only accepts base type matcher"); - const DynTypedMatcher DescendantMatcher; + DynTypedMatcher DescendantMatcher; public: explicit ForEachDescendantMatcher( @@ -1694,7 +1744,7 @@ class ValueEqualsMatcher : public SingleNodeMatcherInterface { } private: - const ValueT ExpectedValue; + ValueT ExpectedValue; }; /// Template specializations to easily write matchers for floating point @@ -1727,7 +1777,7 @@ inline bool ValueEqualsMatcher::matchesNode( /// \c Matcher matches. template class LocMatcher : public MatcherInterface { - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; public: explicit LocMatcher(const Matcher &InnerMatcher) @@ -1751,7 +1801,7 @@ class LocMatcher : public MatcherInterface { /// /// Used to implement the \c loc() matcher. class TypeLocTypeMatcher : public MatcherInterface { - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; public: explicit TypeLocTypeMatcher(const Matcher &InnerMatcher) @@ -1770,7 +1820,7 @@ class TypeLocTypeMatcher : public MatcherInterface { /// another node of type \c T that can be reached using a given traverse /// function. template class TypeTraverseMatcher : public MatcherInterface { - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; public: explicit TypeTraverseMatcher(const Matcher &InnerMatcher, @@ -1795,7 +1845,7 @@ template class TypeTraverseMatcher : public MatcherInterface { /// given traverse function. template class TypeLocTraverseMatcher : public MatcherInterface { - const DynTypedMatcher InnerMatcher; + DynTypedMatcher InnerMatcher; public: explicit TypeLocTraverseMatcher(const Matcher &InnerMatcher, @@ -1850,7 +1900,7 @@ class TypeTraversePolymorphicMatcher { }; private: - const Matcher InnerMatcher; + Matcher InnerMatcher; }; /// A simple memoizer of T(*)() functions. @@ -2194,7 +2244,7 @@ class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface { return BinaryOperator::getOpcodeStr(*optBinaryOpcode); } - const std::vector Names; + std::vector Names; }; using HasOpNameMatcher = diff --git a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h index b7fe907f9414..592a3898a295 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -143,7 +143,7 @@ *Builder) const override; \ \ private: \ - ParamType const Param; \ + ParamType Param; \ }; \ } \ inline ::clang::ast_matchers::internal::Matcher DefineMatcher( \ @@ -151,7 +151,7 @@ return ::clang::ast_matchers::internal::makeMatcher( \ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ } \ - typedef ::clang::ast_matchers::internal::Matcher( \ + typedef ::clang::ast_matchers::internal::Matcher ( \ &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ const Type &Node, \ @@ -192,8 +192,8 @@ *Builder) const override; \ \ private: \ - ParamType1 const Param1; \ - ParamType2 const Param2; \ + ParamType1 Param1; \ + ParamType2 Param2; \ }; \ } \ inline ::clang::ast_matchers::internal::Matcher DefineMatcher( \ @@ -202,7 +202,7 @@ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ Param2)); \ } \ - typedef ::clang::ast_matchers::internal::Matcher( \ + typedef ::clang::ast_matchers::internal::Matcher ( \ &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \ ParamType2 const &Param2); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ @@ -281,7 +281,7 @@ *Builder) const override; \ \ private: \ - ParamType const Param; \ + ParamType Param; \ }; \ } \ inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ @@ -333,8 +333,8 @@ *Builder) const override; \ \ private: \ - ParamType1 const Param1; \ - ParamType2 const Param2; \ + ParamType1 Param1; \ + ParamType2 Param2; \ }; \ } \ inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ @@ -469,7 +469,7 @@ *Builder) const override; \ \ private: \ - std::shared_ptr const Param; \ + std::shared_ptr Param; \ }; \ } \ inline ::clang::ast_matchers::internal::Matcher DefineMatcher( \ @@ -521,7 +521,7 @@ *Builder) const override; \ \ private: \ - std::shared_ptr const Param; \ + std::shared_ptr Param; \ }; \ } \ inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ diff --git a/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h b/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h index fc574c680a44..a0c767bf92d2 100644 --- a/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h +++ b/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h @@ -17,6 +17,7 @@ namespace clang { class AnalysisDeclContext; +class BlockDecl; class CFG; class Decl; class DeclContext; @@ -79,6 +80,7 @@ class CalledOnceCheckHandler { /// the path containing the call and not containing the call. This helps us /// to pinpoint a bad path for the user. /// \param Parameter -- parameter that should be called once. + /// \param Function -- function declaration where the problem occured. /// \param Where -- the least common ancestor statement. /// \param Reason -- a reason describing the path without a call. /// \param IsCalledDirectly -- true, if parameter actually gets called on @@ -86,9 +88,22 @@ class CalledOnceCheckHandler { /// collection, passed as a parameter, etc.). /// \param IsCompletionHandler -- true, if parameter is a completion handler. virtual void handleNeverCalled(const ParmVarDecl *Parameter, - const Stmt *Where, NeverCalledReason Reason, + const Decl *Function, const Stmt *Where, + NeverCalledReason Reason, bool IsCalledDirectly, bool IsCompletionHandler) {} + + /// Called when the block is guaranteed to be called exactly once. + /// It means that we can be stricter with what we report on that block. + /// \param Block -- block declaration that is known to be called exactly once. + virtual void + handleBlockThatIsGuaranteedToBeCalledOnce(const BlockDecl *Block) {} + + /// Called when the block has no guarantees about how many times it can get + /// called. + /// It means that we should be more lenient with reporting warnings in it. + /// \param Block -- block declaration in question. + virtual void handleBlockWithNoGuarantees(const BlockDecl *Block) {} }; /// Check given CFG for 'called once' parameter violations. diff --git a/clang/include/clang/Analysis/AnyCall.h b/clang/include/clang/Analysis/AnyCall.h index 16371eb1da18..846ff7719ce1 100644 --- a/clang/include/clang/Analysis/AnyCall.h +++ b/clang/include/clang/Analysis/AnyCall.h @@ -107,8 +107,8 @@ class AnyCall { } - /// If {@code E} is a generic call (to ObjC method /function/block/etc), - /// return a constructed {@code AnyCall} object. Return None otherwise. + /// If @c E is a generic call (to ObjC method /function/block/etc), + /// return a constructed @c AnyCall object. Return None otherwise. static Optional forExpr(const Expr *E) { if (const auto *ME = dyn_cast(E)) { return AnyCall(ME); @@ -127,8 +127,8 @@ class AnyCall { } } - /// If {@code D} is a callable (Objective-C method or a function), return - /// a constructed {@code AnyCall} object. Return None otherwise. + /// If @c D is a callable (Objective-C method or a function), return + /// a constructed @c AnyCall object. Return None otherwise. // FIXME: block support. static Optional forDecl(const Decl *D) { if (const auto *FD = dyn_cast(D)) { @@ -186,7 +186,7 @@ class AnyCall { } /// \returns Function identifier if it is a named declaration, - /// {@code nullptr} otherwise. + /// @c nullptr otherwise. const IdentifierInfo *getIdentifier() const { if (const auto *ND = dyn_cast_or_null(D)) return ND->getIdentifier(); diff --git a/clang/include/clang/Analysis/RetainSummaryManager.h b/clang/include/clang/Analysis/RetainSummaryManager.h index 6acefb563d8c..b7ccb0317830 100644 --- a/clang/include/clang/Analysis/RetainSummaryManager.h +++ b/clang/include/clang/Analysis/RetainSummaryManager.h @@ -613,8 +613,8 @@ class RetainSummaryManager { const FunctionType *FT, bool &AllowAnnotations); - /// Apply the annotation of {@code pd} in function {@code FD} - /// to the resulting summary stored in out-parameter {@code Template}. + /// Apply the annotation of @c pd in function @c FD + /// to the resulting summary stored in out-parameter @c Template. /// \return whether an annotation was applied. bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx, const NamedDecl *FD, @@ -715,8 +715,8 @@ class RetainSummaryManager { /// Set argument types for arguments which are not doing anything. void updateSummaryForArgumentTypes(const AnyCall &C, const RetainSummary *&RS); - /// Determine whether a declaration {@code D} of correspondent type (return - /// type for functions/methods) {@code QT} has any of the given attributes, + /// Determine whether a declaration @c D of correspondent type (return + /// type for functions/methods) @c QT has any of the given attributes, /// provided they pass necessary validation checks AND tracking the given /// attribute is enabled. /// Returns the object kind corresponding to the present attribute, or None, diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 9625e7f8f322..c7b68856aab0 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -730,7 +730,8 @@ def XRayLogArgs : InheritableAttr { def PatchableFunctionEntry : InheritableAttr, - TargetSpecificAttr> { + TargetSpecificAttr> { let Spellings = [GCC<"patchable_function_entry">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>]; @@ -1182,9 +1183,9 @@ def OpenCLKernel : InheritableAttr { def OpenCLUnrollHint : StmtAttr { let Spellings = [GNU<"opencl_unroll_hint">]; -// let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], -// ErrorDiag, "'for', 'while', and 'do' statements">; - let Args = [UnsignedArgument<"UnrollHint">]; + let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], + ErrorDiag, "'for', 'while', and 'do' statements">; + let Args = [UnsignedArgument<"UnrollHint", /*opt*/1>]; let Documentation = [OpenCLUnrollHintDocs]; } @@ -1325,7 +1326,10 @@ def FallThrough : StmtAttr { let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough", 201904>, CXX11<"clang", "fallthrough">, GCC<"fallthrough">]; -// let Subjects = [NullStmt]; + // The attribute only applies to a NullStmt, but we have special fix-it + // behavior if applied to a case label. + let Subjects = SubjectList<[NullStmt, SwitchCase], ErrorDiag, + "empty statements">; let Documentation = [FallthroughDocs]; } @@ -1343,7 +1347,8 @@ def NoMerge : DeclOrStmtAttr { let Spellings = [Clang<"nomerge">]; let Documentation = [NoMergeDocs]; let InheritEvenIfAlreadyPresent = 1; - let Subjects = SubjectList<[Function], ErrorDiag, "functions and statements">; + let Subjects = SubjectList<[Function, Stmt], ErrorDiag, + "functions and statements">; let SimpleHandler = 1; } @@ -1673,6 +1678,14 @@ def NoDebug : InheritableAttr { let Documentation = [NoDebugDocs]; } +def StandaloneDebug : InheritableAttr { + let Spellings = [Clang<"standalone_debug", /*allowInC =*/0>]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [StandaloneDebugDocs]; + let SimpleHandler = 1; + let LangOpts = [CPlusPlus]; +} + def NoDuplicate : InheritableAttr { let Spellings = [Clang<"noduplicate">]; let Subjects = SubjectList<[Function]>; @@ -3458,6 +3471,7 @@ def LoopHint : Attr { }]; let Documentation = [LoopHintDocs, UnrollHintDocs]; + let HasCustomParsing = 1; } def CapturedRecord : InheritableAttr { diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index deda68b64f90..eabf30eda8cc 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1102,6 +1102,16 @@ data member, or for a typedef or using declaration. }]; } +def StandaloneDebugDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``standalone_debug`` attribute causes debug info to be emitted for a record +type regardless of the debug info optimizations that are enabled with +-fno-standalone-debug. This attribute only has an effect when debug info +optimizations are enabled (e.g. with -fno-standalone-debug), and is C++-only. + }]; +} + def NoDuplicateDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -3016,16 +3026,55 @@ It is only supported when using the Microsoft C++ ABI. def LifetimeBoundDocs : Documentation { let Category = DocCatFunction; let Content = [{ -The ``lifetimebound`` attribute indicates that a resource owned by -a function parameter or implicit object parameter -is retained by the return value of the annotated function -(or, for a parameter of a constructor, in the value of the constructed object). -It is only supported in C++. +The ``lifetimebound`` attribute on a function parameter or implicit object +parameter indicates that objects that are referred to by that parameter may +also be referred to by the return value of the annotated function (or, for a +parameter of a constructor, by the value of the constructed object). It is only +supported in C++. + +By default, a reference is considered to refer to its referenced object, a +pointer is considered to refer to its pointee, a ``std::initializer_list`` +is considered to refer to its underlying array, and aggregates (arrays and +simple ``struct``\s) are considered to refer to all objects that their +transitive subobjects refer to. + +Clang warns if it is able to detect that an object or reference refers to +another object with a shorter lifetime. For example, Clang will warn if a +function returns a reference to a local variable, or if a reference is bound to +a temporary object whose lifetime is not extended. By using the +``lifetimebound`` attribute, this determination can be extended to look through +user-declared functions. For example: + +.. code-block:: c++ + + // Returns m[key] if key is present, or default_value if not. + template + const U &get_or_default(const std::map &m [[clang::lifetimebound]], + const T &key, /* note, not lifetimebound */ + const U &default_value [[clang::lifetimebound]]); -This attribute provides an experimental implementation of the facility -described in the C++ committee paper `P0936R0 `_, -and is subject to change as the design of the corresponding functionality -changes. + std::map m; + // warning: temporary "bar"s that might be bound to local reference 'val' + // will be destroyed at the end of the full-expression + const std::string &val = get_or_default(m, "foo"s, "bar"s); + + // No warning in this case. + std::string def_val = "bar"s; + const std::string &val = get_or_default(m, "foo"s, def_val); + +The attribute can be applied to the implicit ``this`` parameter of a member +function by writing the attribute after the function type: + +.. code-block:: c++ + + struct string { + // The returned pointer should not outlive ``*this``. + const char *data() const [[clang::lifetimebound]]; + }; + +This attribute is inspired by the C++ committee paper `P0936R0 +`_, but does not affect whether temporary objects +have their lifetimes extended. }]; } @@ -4800,6 +4849,9 @@ def PatchableFunctionEntryDocs : Documentation { before the function entry and N-M NOPs after the function entry. This attribute takes precedence over the command line option ``-fpatchable-function-entry=N,M``. ``M`` defaults to 0 if omitted. + +This attribute is only supported on +aarch64/aarch64-be/riscv32/riscv64/i386/x86-64 targets. }]; } diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index ab1b5866c8a7..153e22f00f52 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1639,6 +1639,9 @@ BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt") // OpenMP 4.0 LANGBUILTIN(omp_is_initial_device, "i", "nc", OMP_LANG) +// CUDA/HIP +LANGBUILTIN(__builtin_get_device_side_mangled_name, "cC*.", "ncT", CUDA_LANG) + // Builtins for XRay BUILTIN(__xray_customevent, "vcC*z", "") BUILTIN(__xray_typedevent, "vzcC*z", "") diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 15bfcf797917..efd6cb897293 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -36,6 +36,7 @@ enum LanguageID { OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only. OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only. OMP_LANG = 0x80, // builtin requires OpenMP. + CUDA_LANG = 0x100, // builtin requires CUDA. ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages. ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode. ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG, // builtin requires MS mode. diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index b35510f8b691..1dac5d2371d4 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -99,6 +99,20 @@ BUILTIN(__builtin_arm_tcommit, "v", "n") BUILTIN(__builtin_arm_tcancel, "vWUIi", "n") BUILTIN(__builtin_arm_ttest, "WUi", "nc") +// Armv8.5-A FP rounding intrinsics +BUILTIN(__builtin_arm_frint32zf, "ff", "") +BUILTIN(__builtin_arm_frint32z, "dd", "") +BUILTIN(__builtin_arm_frint64zf, "ff", "") +BUILTIN(__builtin_arm_frint64z, "dd", "") +BUILTIN(__builtin_arm_frint32xf, "ff", "") +BUILTIN(__builtin_arm_frint32x, "dd", "") +BUILTIN(__builtin_arm_frint64xf, "ff", "") +BUILTIN(__builtin_arm_frint64x, "dd", "") + +// Armv8.5-A Random number generation intrinsics +BUILTIN(__builtin_arm_rndr, "iWUi*", "n") +BUILTIN(__builtin_arm_rndrrs, "iWUi*", "n") + // Armv8.7-A load/store 64-byte intrinsics BUILTIN(__builtin_arm_ld64b, "vvC*WUi*", "n") BUILTIN(__builtin_arm_st64b, "vv*WUiC*", "n") diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index 415d8cb3e73a..9677b1aadb51 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -193,13 +193,13 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts") // Deep learning builtins. //===----------------------------------------------------------------------===// -TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot7-insts") TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot2-insts") TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot2-insts") TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot1-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot7-insts") TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot1-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot7-insts") //===----------------------------------------------------------------------===// // GFX10+ only builtins. diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 39c66f5daeb1..66c35a9a82be 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -39,6 +39,7 @@ BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vaddeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vaddcuq, "V1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vaddecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vadduqm, "V1ULLLiV16UcV16Uc","") BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "") BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "") @@ -49,6 +50,7 @@ BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vsubeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vsubcuq, "V1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vsubecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vsubuqm, "V1ULLLiV16UcV16Uc","") BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "") BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "") diff --git a/clang/include/clang/Basic/BuiltinsRISCV.def b/clang/include/clang/Basic/BuiltinsRISCV.def index 9fbfa9369507..c91b3d1b1f5c 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.def +++ b/clang/include/clang/Basic/BuiltinsRISCV.def @@ -15,186 +15,7 @@ # define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif -#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN) -#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, ATTRS, "experimental-v") -#endif - -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m1_vl, "q8Scq8Scq8Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m1_m_vl, "q8Scq8bq8Scq8Scq8Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m1_vl, "q4Ssq4Ssq4Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m1_m_vl, "q4Ssq4bq4Ssq4Ssq4Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m1_vl, "q2Siq2Siq2Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m1_m_vl, "q2Siq2bq2Siq2Siq2Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m1_vl, "q1SWiq1SWiq1SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m1_m_vl, "q1SWiq1bq1SWiq1SWiq1SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m2_vl, "q16Scq16Scq16Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m2_m_vl, "q16Scq16bq16Scq16Scq16Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m2_vl, "q8Ssq8Ssq8Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m2_m_vl, "q8Ssq8bq8Ssq8Ssq8Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m2_vl, "q4Siq4Siq4Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m2_m_vl, "q4Siq4bq4Siq4Siq4Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m2_vl, "q2SWiq2SWiq2SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m2_m_vl, "q2SWiq2bq2SWiq2SWiq2SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m4_vl, "q32Scq32Scq32Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m4_m_vl, "q32Scq32bq32Scq32Scq32Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m4_vl, "q16Ssq16Ssq16Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m4_m_vl, "q16Ssq16bq16Ssq16Ssq16Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m4_vl, "q8Siq8Siq8Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m4_m_vl, "q8Siq8bq8Siq8Siq8Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m4_vl, "q4SWiq4SWiq4SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m4_m_vl, "q4SWiq4bq4SWiq4SWiq4SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m8_vl, "q64Scq64Scq64Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8m8_m_vl, "q64Scq64bq64Scq64Scq64Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m8_vl, "q32Ssq32Ssq32Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16m8_m_vl, "q32Ssq32bq32Ssq32Ssq32Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m8_vl, "q16Siq16Siq16Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32m8_m_vl, "q16Siq16bq16Siq16Siq16Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m8_vl, "q8SWiq8SWiq8SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i64m8_m_vl, "q8SWiq8bq8SWiq8SWiq8SWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8mf2_vl, "q4Scq4Scq4Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8mf2_m_vl, "q4Scq4bq4Scq4Scq4Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16mf2_vl, "q2Ssq2Ssq2Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16mf2_m_vl, "q2Ssq2bq2Ssq2Ssq2Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32mf2_vl, "q1Siq1Siq1Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i32mf2_m_vl, "q1Siq1bq1Siq1Siq1Siz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8mf4_vl, "q2Scq2Scq2Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8mf4_m_vl, "q2Scq2bq2Scq2Scq2Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16mf4_vl, "q1Ssq1Ssq1Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i16mf4_m_vl, "q1Ssq1bq1Ssq1Ssq1Ssz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8mf8_vl, "q1Scq1Scq1Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_i8mf8_m_vl, "q1Scq1bq1Scq1Scq1Scz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m1_vl, "q8Scq8ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m1_m_vl, "q8Scq8bq8Scq8ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m1_vl, "q4Ssq4SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m1_m_vl, "q4Ssq4bq4Ssq4SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m1_vl, "q2Siq2SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m1_m_vl, "q2Siq2bq2Siq2SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m1_vl, "q1SWiq1SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m1_m_vl, "q1SWiq1bq1SWiq1SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m2_vl, "q16Scq16ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m2_m_vl, "q16Scq16bq16Scq16ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m2_vl, "q8Ssq8SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m2_m_vl, "q8Ssq8bq8Ssq8SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m2_vl, "q4Siq4SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m2_m_vl, "q4Siq4bq4Siq4SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m2_vl, "q2SWiq2SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m2_m_vl, "q2SWiq2bq2SWiq2SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m4_vl, "q32Scq32ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m4_m_vl, "q32Scq32bq32Scq32ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m4_vl, "q16Ssq16SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m4_m_vl, "q16Ssq16bq16Ssq16SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m4_vl, "q8Siq8SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m4_m_vl, "q8Siq8bq8Siq8SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m4_vl, "q4SWiq4SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m4_m_vl, "q4SWiq4bq4SWiq4SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m8_vl, "q64Scq64ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8m8_m_vl, "q64Scq64bq64Scq64ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m8_vl, "q32Ssq32SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16m8_m_vl, "q32Ssq32bq32Ssq32SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m8_vl, "q16Siq16SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32m8_m_vl, "q16Siq16bq16Siq16SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m8_vl, "q8SWiq8SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i64m8_m_vl, "q8SWiq8bq8SWiq8SWiSWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8mf2_vl, "q4Scq4ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8mf2_m_vl, "q4Scq4bq4Scq4ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16mf2_vl, "q2Ssq2SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16mf2_m_vl, "q2Ssq2bq2Ssq2SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32mf2_vl, "q1Siq1SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i32mf2_m_vl, "q1Siq1bq1Siq1SiSiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8mf4_vl, "q2Scq2ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8mf4_m_vl, "q2Scq2bq2Scq2ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16mf4_vl, "q1Ssq1SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i16mf4_m_vl, "q1Ssq1bq1Ssq1SsSsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8mf8_vl, "q1Scq1ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_i8mf8_m_vl, "q1Scq1bq1Scq1ScScz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m1_vl, "q8Ucq8Ucq8Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m1_m_vl, "q8Ucq8bq8Ucq8Ucq8Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m1_vl, "q4Usq4Usq4Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m1_m_vl, "q4Usq4bq4Usq4Usq4Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m1_vl, "q2Uiq2Uiq2Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m1_m_vl, "q2Uiq2bq2Uiq2Uiq2Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m1_vl, "q1UWiq1UWiq1UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m1_m_vl, "q1UWiq1bq1UWiq1UWiq1UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m2_vl, "q16Ucq16Ucq16Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m2_m_vl, "q16Ucq16bq16Ucq16Ucq16Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m2_vl, "q8Usq8Usq8Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m2_m_vl, "q8Usq8bq8Usq8Usq8Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m2_vl, "q4Uiq4Uiq4Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m2_m_vl, "q4Uiq4bq4Uiq4Uiq4Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m2_vl, "q2UWiq2UWiq2UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m2_m_vl, "q2UWiq2bq2UWiq2UWiq2UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m4_vl, "q32Ucq32Ucq32Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m4_m_vl, "q32Ucq32bq32Ucq32Ucq32Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m4_vl, "q16Usq16Usq16Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m4_m_vl, "q16Usq16bq16Usq16Usq16Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m4_vl, "q8Uiq8Uiq8Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m4_m_vl, "q8Uiq8bq8Uiq8Uiq8Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m4_vl, "q4UWiq4UWiq4UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m4_m_vl, "q4UWiq4bq4UWiq4UWiq4UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m8_vl, "q64Ucq64Ucq64Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8m8_m_vl, "q64Ucq64bq64Ucq64Ucq64Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m8_vl, "q32Usq32Usq32Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16m8_m_vl, "q32Usq32bq32Usq32Usq32Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m8_vl, "q16Uiq16Uiq16Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32m8_m_vl, "q16Uiq16bq16Uiq16Uiq16Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m8_vl, "q8UWiq8UWiq8UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u64m8_m_vl, "q8UWiq8bq8UWiq8UWiq8UWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8mf2_vl, "q4Ucq4Ucq4Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8mf2_m_vl, "q4Ucq4bq4Ucq4Ucq4Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16mf2_vl, "q2Usq2Usq2Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16mf2_m_vl, "q2Usq2bq2Usq2Usq2Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32mf2_vl, "q1Uiq1Uiq1Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u32mf2_m_vl, "q1Uiq1bq1Uiq1Uiq1Uiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8mf4_vl, "q2Ucq2Ucq2Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8mf4_m_vl, "q2Ucq2bq2Ucq2Ucq2Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16mf4_vl, "q1Usq1Usq1Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u16mf4_m_vl, "q1Usq1bq1Usq1Usq1Usz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8mf8_vl, "q1Ucq1Ucq1Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vv_u8mf8_m_vl, "q1Ucq1bq1Ucq1Ucq1Ucz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m1_vl, "q8Ucq8UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m1_m_vl, "q8Ucq8bq8Ucq8UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m1_vl, "q4Usq4UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m1_m_vl, "q4Usq4bq4Usq4UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m1_vl, "q2Uiq2UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m1_m_vl, "q2Uiq2bq2Uiq2UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m1_vl, "q1UWiq1UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m1_m_vl, "q1UWiq1bq1UWiq1UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m2_vl, "q16Ucq16UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m2_m_vl, "q16Ucq16bq16Ucq16UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m2_vl, "q8Usq8UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m2_m_vl, "q8Usq8bq8Usq8UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m2_vl, "q4Uiq4UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m2_m_vl, "q4Uiq4bq4Uiq4UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m2_vl, "q2UWiq2UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m2_m_vl, "q2UWiq2bq2UWiq2UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m4_vl, "q32Ucq32UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m4_m_vl, "q32Ucq32bq32Ucq32UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m4_vl, "q16Usq16UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m4_m_vl, "q16Usq16bq16Usq16UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m4_vl, "q8Uiq8UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m4_m_vl, "q8Uiq8bq8Uiq8UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m4_vl, "q4UWiq4UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m4_m_vl, "q4UWiq4bq4UWiq4UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m8_vl, "q64Ucq64UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8m8_m_vl, "q64Ucq64bq64Ucq64UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m8_vl, "q32Usq32UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16m8_m_vl, "q32Usq32bq32Usq32UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m8_vl, "q16Uiq16UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32m8_m_vl, "q16Uiq16bq16Uiq16UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m8_vl, "q8UWiq8UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u64m8_m_vl, "q8UWiq8bq8UWiq8UWiUWiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8mf2_vl, "q4Ucq4UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8mf2_m_vl, "q4Ucq4bq4Ucq4UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16mf2_vl, "q2Usq2UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16mf2_m_vl, "q2Usq2bq2Usq2UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32mf2_vl, "q1Uiq1UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u32mf2_m_vl, "q1Uiq1bq1Uiq1UiUiz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8mf4_vl, "q2Ucq2UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8mf4_m_vl, "q2Ucq2bq2Ucq2UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16mf4_vl, "q1Usq1UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u16mf4_m_vl, "q1Usq1bq1Usq1UsUsz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8mf8_vl, "q1Ucq1UcUcz", "n") -RISCVV_BUILTIN(__builtin_rvv_vadd_vx_u8mf8_m_vl, "q1Ucq1bq1Ucq1UcUcz", "n") +#include "clang/Basic/riscv_vector_builtins.inc" #undef BUILTIN -#undef RISCVV_BUILTIN +#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index 84f346bcb928..3f8b050aabfd 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -84,15 +84,15 @@ TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "simd TARGET_BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_add_sat_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_add_sat_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_add_sat_s_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_add_sat_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_sub_sat_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_sub_sat_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_sub_sat_s_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_sub_sat_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_abs_i8x16, "V16ScV16Sc", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_abs_i16x8, "V8sV8s", "nc", "simd128") @@ -116,7 +116,7 @@ TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_popcnt_i8x16, "V16ScV16Sc", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_q15mulr_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_q15mulr_sat_s_i16x8, "V8sV8sV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_extmul_low_i8x16_s_i16x8, "V8sV16ScV16Sc", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_extmul_high_i8x16_s_i16x8, "V8sV16ScV16Sc", "nc", "simd128") @@ -141,21 +141,16 @@ TARGET_BUILTIN(__builtin_wasm_extadd_pairwise_i16x8_u_i32x4, "V4UiV8Us", "nc", " TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_signselect_i8x16, "V16ScV16ScV16ScV16Sc", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_signselect_i16x8, "V8sV8sV8sV8s", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_signselect_i32x4, "V4iV4iV4iV4i", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_signselect_i64x2, "V2LLiV2LLiV2LLiV2LLi", "nc", "simd128") - TARGET_BUILTIN(__builtin_wasm_shuffle_v8x16, "V16ScV16ScV16ScIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16Sc", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_any_true_i16x8, "iV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_any_true_i32x4, "iV4i", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_any_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_any_true_i64x2, "iV2LLi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_all_true_i8x16, "iV16Sc", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_bitmask_i8x16, "iV16Sc", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_bitmask_i16x8, "iV8s", "nc", "simd128") @@ -188,11 +183,6 @@ TARGET_BUILTIN(__builtin_wasm_dot_s_i32x4_i16x8, "V4iV8sV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_qfma_f32x4, "V4fV4fV4fV4f", "nc", "unimplemented-simd128") -TARGET_BUILTIN(__builtin_wasm_qfms_f32x4, "V4fV4fV4fV4f", "nc", "unimplemented-simd128") -TARGET_BUILTIN(__builtin_wasm_qfma_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128") -TARGET_BUILTIN(__builtin_wasm_qfms_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128") - TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128") @@ -201,18 +191,15 @@ TARGET_BUILTIN(__builtin_wasm_narrow_u_i8x16_i16x8, "V16UcV8UsV8Us", "nc", "simd TARGET_BUILTIN(__builtin_wasm_narrow_s_i16x8_i32x4, "V8sV4iV4i", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_narrow_u_i16x8_i32x4, "V8UsV4UiV4Ui", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_widen_low_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_widen_high_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_widen_low_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_widen_high_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128") - -TARGET_BUILTIN(__builtin_wasm_widen_s_i8x16_i32x4, "V4iV16ScIi", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_widen_u_i8x16_i32x4, "V4UiV16UcIi", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_extend_low_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_extend_high_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_extend_low_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_extend_high_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_convert_low_s_i32x4_f64x2, "V2dV4i", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_convert_low_u_i32x4_f64x2, "V2dV4Ui", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_trunc_sat_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_demote_zero_f64x2_f32x4, "V4fV2d", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_promote_low_f32x4_f64x2, "V2dV4f", "nc", "simd128") @@ -228,10 +215,5 @@ TARGET_BUILTIN(__builtin_wasm_store16_lane, "vs*V8sIi", "n", "simd128") TARGET_BUILTIN(__builtin_wasm_store32_lane, "vi*V4iIi", "n", "simd128") TARGET_BUILTIN(__builtin_wasm_store64_lane, "vLLi*V2LLiIi", "n", "simd128") -TARGET_BUILTIN(__builtin_wasm_eq_i64x2, "V2LLiV2LLiV2LLi", "nc", "simd128") - -TARGET_BUILTIN(__builtin_wasm_prefetch_t, "vv*", "n", "simd128") -TARGET_BUILTIN(__builtin_wasm_prefetch_nt, "vv*", "n", "simd128") - #undef BUILTIN #undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 47a3198a0e91..8cd891385a48 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -84,3 +84,9 @@ clang_tablegen(arm_cde_builtin_sema.inc -gen-arm-cde-builtin-sema clang_tablegen(arm_cde_builtin_aliases.inc -gen-arm-cde-builtin-aliases SOURCE arm_cde.td TARGET ClangARMCdeBuiltinAliases) +clang_tablegen(riscv_vector_builtins.inc -gen-riscv-vector-builtins + SOURCE riscv_vector.td + TARGET ClangRISCVVectorBuiltins) +clang_tablegen(riscv_vector_builtin_cg.inc -gen-riscv-vector-builtin-codegen + SOURCE riscv_vector.td + TARGET ClangRISCVVectorBuiltinCG) diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a1db1b101620..900e61eb828b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -39,7 +39,6 @@ CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) o CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe. CODEGENOPT(Backchain , 1, 0) ///< -mbackchain -CODEGENOPT(IgnoreXCOFFVisibility , 1, 0) ///< -mignore-xcoff-visibility CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard CODEGENOPT(EHContGuard , 1, 0) ///< -ehcontguard @@ -71,6 +70,10 @@ CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. CODEGENOPT(EmitCallSiteInfo, 1, 0) ///< Emit call site info only in the case of ///< '-g' + 'O>0' level. +CODEGENOPT(EnableDIPreservationVerify, 1, 0) ///< Enable di preservation verify + ///< each (it means check + ///< the original debug info + ///< metadata preservation). CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs ///< is specified. CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. @@ -337,7 +340,7 @@ ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 4, codegenoptions::NoD CODEGENOPT(MacroDebugInfo, 1, 0) /// Tune the debug info for this debugger. -ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 2, +ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 3, llvm::DebuggerKind::Default) /// Dwarf version. Version zero indicates to LLVM that no DWARF should be diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 40068b4f6649..778340b34272 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -190,6 +190,10 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The ABI to use for passing floating point arguments. std::string FloatABI; + /// The file to use for dumping bug report by `Debugify` for original + /// debug info. + std::string DIBugsReportFilePath; + /// The floating-point denormal mode to use. llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::getIEEE(); @@ -415,10 +419,6 @@ class CodeGenOptions : public CodeGenOptionsBase { CodeGenOptions(); - /// Is this a libc/libm function that is no longer recognized as a - /// builtin because a -fno-builtin-* option has been specified? - bool isNoBuiltinFunc(const char *Name) const; - const std::vector &getNoBuiltinFuncs() const { return NoBuiltinFuncs; } diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index f6b936f5ccd9..496d86ee2fe7 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -349,6 +349,8 @@ def note_constexpr_new_delete_mismatch : Note< "used to delete pointer to " "%select{array object of type %2|non-array object of type %2|" "object allocated with 'new'}0}1">; +def note_constexpr_deallocate_null : Note< + "'std::allocator<...>::deallocate' used to delete a null pointer">; def note_constexpr_delete_subobject : Note< "delete of pointer%select{ to subobject|}1 '%0' " "%select{|that does not point to complete object}1">; diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index a237d492de20..eab8206b104d 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -187,6 +187,17 @@ def ext_cxx11_longlong : Extension< def warn_cxx98_compat_longlong : Warning< "'long long' is incompatible with C++98">, InGroup, DefaultIgnore; +def ext_cxx2b_size_t_suffix : ExtWarn< + "'size_t' suffix for literals is a C++2b extension">, + InGroup; +def warn_cxx20_compat_size_t_suffix : Warning< + "'size_t' suffix for literals is incompatible with C++ standards before " + "C++2b">, InGroup, DefaultIgnore; +def err_cxx2b_size_t_suffix: Error< + "'size_t' suffix for literals is a C++2b feature">; +def err_size_t_literal_too_large: Error< + "%select{signed |}0'size_t' literal is out of range of possible " + "%select{signed |}0'size_t' values">; def err_integer_literal_too_large : Error< "integer literal is too large to be represented in any %select{signed |}0" "integer type">; diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 6f50774d8f1c..5e580cc4fbb7 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -342,6 +342,10 @@ def warn_drv_disabling_vptr_no_rtti_default : Warning< def warn_drv_object_size_disabled_O0 : Warning< "the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">, InGroup, DefaultWarnNoWerror; +def warn_ignoring_verify_debuginfo_preserve_export : Warning< + "ignoring -fverify-debuginfo-preserve-export=%0 because " + "-fverify-debuginfo-preserve wasn't enabled">, + InGroup; def err_invalid_branch_protection: Error < "invalid branch protection option '%0' in '%1'">; def err_invalid_sls_hardening : Error< diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 34876e9945b5..85f798013a3d 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -253,22 +253,30 @@ def : DiagGroup<"c++1z-compat-mangling", [CXX17CompatMangling]>; // Name of this warning in GCC. def NoexceptType : DiagGroup<"noexcept-type", [CXX17CompatMangling]>; -// Warnings for C2x code which is not compatible with prior C standards. +// Warnings for C code which is not compatible with previous C standards. def CPre2xCompat : DiagGroup<"pre-c2x-compat">; def CPre2xCompatPedantic : DiagGroup<"pre-c2x-compat-pedantic", [CPre2xCompat]>; -// Warnings for C++1y code which is not compatible with prior C++ standards. -def CXXPre14Compat : DiagGroup<"c++98-c++11-compat">; -def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic", +// Warnings for C++ code which is not compatible with previous C++ standards. +def CXXPre14Compat : DiagGroup<"pre-c++14-compat">; +def : DiagGroup<"c++98-c++11-compat", [CXXPre14Compat]>; +def CXXPre14CompatPedantic : DiagGroup<"pre-c++14-compat-pedantic", [CXXPre14Compat, CXXPre14CompatBinaryLiteral]>; -def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">; -def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic", +def : DiagGroup<"c++98-c++11-compat-pedantic", [CXXPre14CompatPedantic]>; +def CXXPre17Compat : DiagGroup<"pre-c++17-compat">; +def : DiagGroup<"c++98-c++11-c++14-compat", [CXXPre17Compat]>; +def CXXPre17CompatPedantic : DiagGroup<"pre-c++17-compat-pedantic", [CXXPre17Compat]>; -def CXXPre20Compat : DiagGroup<"c++98-c++11-c++14-c++17-compat">; -def CXXPre20CompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic", +def : DiagGroup<"c++98-c++11-c++14-compat-pedantic", + [CXXPre17CompatPedantic]>; +def CXXPre20Compat : DiagGroup<"pre-c++20-compat">; +def : DiagGroup<"c++98-c++11-c++14-c++17-compat", [CXXPre20Compat]>; +def CXXPre20CompatPedantic : DiagGroup<"pre-c++20-compat-pedantic", [CXXPre20Compat]>; +def : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic", + [CXXPre20CompatPedantic]>; def CXXPre2bCompat : DiagGroup<"pre-c++2b-compat">; def CXXPre2bCompatPedantic : DiagGroup<"pre-c++2b-compat-pedantic", [CXXPre2bCompat]>; @@ -491,6 +499,7 @@ def PrivateExtern : DiagGroup<"private-extern">; def SelTypeCast : DiagGroup<"cast-of-sel-type">; def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">; def BadFunctionCast : DiagGroup<"bad-function-cast">; +def CastFunctionType : DiagGroup<"cast-function-type">; def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">; def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">; def ObjCPropertyAssignOnObjectType : DiagGroup<"objc-property-assign-on-object-type">; diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 130e7687bad2..64026a1ee922 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -179,6 +179,9 @@ def err_invalid_suffix_constant : Error< def warn_cxx11_compat_digit_separator : Warning< "digit separators are incompatible with C++ standards before C++14">, InGroup, DefaultIgnore; +def warn_c2x_compat_digit_separator : Warning< + "digit separators are incompatible with C standards before C2x">, + InGroup, DefaultIgnore; def err_digit_separator_not_between_digits : Error< "digit separator cannot appear at %select{start|end}0 of digit sequence">; def warn_extraneous_char_constant : Warning< diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 4608905f1b26..b0f9b317a020 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -949,9 +949,6 @@ def err_expected_lambda_body : Error<"expected body of lambda expression">; def warn_cxx98_compat_lambda : Warning< "lambda expressions are incompatible with C++98">, InGroup, DefaultIgnore; -def err_lambda_missing_parens : Error< - "lambda requires '()' before %select{'mutable'|return type|" - "attribute specifier|'constexpr'|'consteval'|'requires' clause}0">; def err_lambda_decl_specifier_repeated : Error< "%select{'mutable'|'constexpr'|'consteval'}0 cannot appear multiple times in a lambda declarator">; def err_lambda_capture_misplaced_ellipsis : Error< @@ -964,6 +961,9 @@ def err_capture_default_first : Error< def ext_decl_attrs_on_lambda : ExtWarn< "an attribute specifier sequence in this position is a C++2b extension">, InGroup; +def ext_lambda_missing_parens : ExtWarn< + "lambda without a parameter clause is a C++2b extension">, + InGroup; def warn_cxx20_compat_decl_attrs_on_lambda : Warning< "an attribute specifier sequence in this position is incompatible with C++ " "standards before C++2b">, InGroup, DefaultIgnore; @@ -1400,6 +1400,13 @@ def err_omp_variant_ctx_second_match_extension : Error< "only a single match extension allowed per OpenMP context selector">; def err_omp_invalid_dsa: Error< "data-sharing attribute '%0' in '%1' clause requires OpenMP version %2 or above">; +def err_omp_expected_punc_after_interop_mod : Error< + "expected ',' after interop modifier">; +def err_omp_expected_interop_type : Error< + "expected interop type: 'target' and/or 'targetsync'">; +def warn_omp_more_one_interop_type + : Warning<"interop type '%0' cannot be specified more than once">, + InGroup; // Pragma loop support. def err_pragma_loop_missing_argument : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7076274dcb6b..d51a01837fc9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5776,6 +5776,9 @@ def note_goto_ms_asm_label : Note< def warn_unused_label : Warning<"unused label %0">, InGroup, DefaultIgnore; +def err_continue_from_cond_var_init : Error< + "cannot jump from this continue statement to the loop increment; " + "jump bypasses initialization of loop condition variable">; def err_goto_into_protected_scope : Error< "cannot jump from this goto statement to its label">; def ext_goto_into_protected_scope : ExtWarn< @@ -7462,6 +7465,8 @@ let CategoryName = "Lambda Issue" in { "duration">; def err_this_capture : Error< "'this' cannot be %select{implicitly |}0captured in this context">; + def note_lambda_this_capture_fixit : Note< + "explicitly capture 'this'">; def err_lambda_capture_anonymous_var : Error< "unnamed variable cannot be implicitly captured in a lambda expression">; def err_lambda_capture_flexarray_type : Error< @@ -7470,6 +7475,10 @@ let CategoryName = "Lambda Issue" in { def err_lambda_impcap : Error< "variable %0 cannot be implicitly captured in a lambda with no " "capture-default specified">; + def note_lambda_variable_capture_fixit : Note< + "capture %0 by %select{value|reference}1">; + def note_lambda_default_capture_fixit : Note< + "default capture by %select{value|reference}0">; def note_lambda_decl : Note<"lambda expression begins here">; def err_lambda_unevaluated_operand : Error< "lambda expression in an unevaluated operand">; @@ -8294,6 +8303,9 @@ def note_cuda_device_builtin_surftex_should_be_template_class : Note< "%0 needs to be instantiated from a class template with proper " "template arguments">; +def err_hip_invalid_args_builtin_mangled_name : Error< + "invalid argument: symbol must be a device-side function or global variable">; + def warn_non_pod_vararg_with_format_string : Warning< "cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic " "%select{function|block|method|constructor}2; expected type from format " @@ -8377,6 +8389,9 @@ def note_change_calling_conv_fixit : Note< def warn_bad_function_cast : Warning< "cast from function call of type %0 to non-matching type %1">, InGroup, DefaultIgnore; +def warn_cast_function_type : Warning< + "cast %diff{from $ to $ |}0,1converts to incompatible function type">, + InGroup, DefaultIgnore; def err_cast_pointer_to_non_pointer_int : Error< "pointer cannot be cast to type %0">; def err_cast_to_bfloat16 : Error<"cannot type-cast to __bf16">; @@ -8597,6 +8612,15 @@ def warn_initializer_out_of_order : Warning< "%select{field|base class}0 %1 will be initialized after " "%select{field|base}2 %3">, InGroup, DefaultIgnore; + +def warn_some_initializers_out_of_order : Warning< + "initializer order does not match the declaration order">, + InGroup, DefaultIgnore; + +def note_initializer_out_of_order : Note< + "%select{field|base class}0 %1 will be initialized after " + "%select{field|base}2 %3">; + def warn_abstract_vbase_init_ignored : Warning< "initializer for virtual base class %0 of abstract class %1 " "will never be used">, @@ -8973,8 +8997,8 @@ def note_defaulted_comparison_calls_deleted : Note< "defaulted %0 is implicitly deleted because it would invoke a deleted " "comparison function%select{| for member %2| for base class %2}1">; def note_defaulted_comparison_no_viable_function : Note< - "defaulted %0 is implicitly deleted because there is no viable comparison " - "function%select{| for member %2| for base class %2}1">; + "defaulted %0 is implicitly deleted because there is no viable three-way " + "comparison function for%select{| member| base class}1 %2">; def note_defaulted_comparison_no_viable_function_synthesized : Note< "three-way comparison cannot be synthesized because there is no viable " "function for %select{'=='|'<'}0 comparison">; @@ -9917,7 +9941,7 @@ def warn_opencl_attr_deprecated_ignored : Warning < def err_opencl_variadic_function : Error< "invalid prototype, variadic arguments are not allowed in OpenCL">; def err_opencl_requires_extension : Error< - "use of %select{type|declaration}0 %1 requires %2 extension to be enabled">; + "use of %select{type|declaration}0 %1 requires %2 support">; def warn_opencl_generic_address_space_arg : Warning< "passing non-generic address space pointer to %0" " may cause dynamic conversion affecting performance">, @@ -10581,6 +10605,20 @@ def note_omp_protected_structured_block : Note<"jump bypasses OpenMP structured block">; def note_omp_exits_structured_block : Note<"jump exits scope of OpenMP structured block">; +def err_omp_interop_variable_expected : Error< + "expected%select{| non-const}0 variable of type 'omp_interop_t'">; +def err_omp_interop_variable_wrong_type : Error< + "interop variable must be of type 'omp_interop_t'">; +def err_omp_interop_prefer_type : Error< + "prefer_list item must be a string literal or constant integral " + "expression">; +def err_omp_interop_bad_depend_clause : Error< + "'depend' clause requires the 'targetsync' interop type">; +def err_omp_interop_var_multiple_actions : Error< + "interop variable %0 used in multiple action clauses">; +def err_omp_dispatch_statement_call + : Error<"statement after '#pragma omp dispatch' must be a direct call" + " to a target function or an assignment to one">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 32830a3a532c..4f7e2db7683d 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -257,6 +257,7 @@ EXTENSION(statement_attributes_with_gnu_syntax, true) EXTENSION(gnu_asm, LangOpts.GNUAsm) EXTENSION(gnu_asm_goto_with_outputs, LangOpts.GNUAsm) EXTENSION(matrix_types, LangOpts.MatrixTypes) +EXTENSION(matrix_types_scalar_division, true) FEATURE(cxx_abi_relative_vtable, LangOpts.CPlusPlus && LangOpts.RelativeCXXABIVTables) diff --git a/clang/include/clang/Basic/LLVM.h b/clang/include/clang/Basic/LLVM.h index 02e422051071..4ac2d744af3c 100644 --- a/clang/include/clang/Basic/LLVM.h +++ b/clang/include/clang/Basic/LLVM.h @@ -22,6 +22,9 @@ // None.h includes an enumerator that is desired & cannot be forward declared // without a definition of NoneType. #include "llvm/ADT/None.h" +// Add this header as a workaround to prevent `too few template arguments for +// class template 'SmallVector'` building error with build compilers like XL. +#include "llvm/ADT/SmallVector.h" namespace llvm { // ADT's. diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 346638549719..1560a1f38aeb 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -109,6 +109,7 @@ LANGOPT(Bool , 1, 0, "bool, true, and false keywords") LANGOPT(Half , 1, 0, "half keyword") LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword") LANGOPT(Char8 , 1, 0, "char8_t keyword") +LANGOPT(IEEE128 , 1, 0, "__ieee128 keyword") LANGOPT(DeclSpecKeyword , 1, 0, "__declspec keyword") BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers") BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode") @@ -248,8 +249,8 @@ LANGOPT(GPUMaxThreadsPerBlock, 32, 1024, "default max threads per block for kern LANGOPT(GPUDeferDiag, 1, 0, "defer host/device related diagnostic messages for CUDA/HIP") LANGOPT(GPUExcludeWrongSideOverloads, 1, 0, "always exclude wrong side overloads in overloading resolution for CUDA/HIP") -LANGOPT(SYCL , 1, 0, "SYCL") LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device") +LANGOPT(SYCLIsHost , 1, 0, "SYCL host compilation") ENUM_LANGOPT(SYCLVersion , SYCLMajorVersion, 1, SYCL_None, "Version of the SYCL standard used") LANGOPT(HIPUseNewLaunchAPI, 1, 0, "Use new kernel launching API for HIP") @@ -267,6 +268,7 @@ BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd re BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables") LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings") BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden visibility for inline C++ methods") +BENIGN_LANGOPT(IgnoreXCOFFVisibility, 1, 0, "All the visibility attributes that are specified in the source code are ignored in aix XCOFF.") BENIGN_LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0, "hidden visibility for static local variables in inline C++ " "methods when -fvisibility-inlines hidden is enabled") diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h index f82ce05a6369..b0785409628c 100644 --- a/clang/include/clang/Basic/LangStandard.h +++ b/clang/include/clang/Basic/LangStandard.h @@ -32,6 +32,7 @@ enum class Language : uint8_t { ObjC, ObjCXX, OpenCL, + OpenCLCXX, CUDA, RenderScript, HIP, diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 82ea1f462949..16f34d11398a 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -637,7 +637,7 @@ class Module { } /// Print the module map for this module to the given stream. - void print(raw_ostream &OS, unsigned Indent = 0) const; + void print(raw_ostream &OS, unsigned Indent = 0, bool Dump = false) const; /// Dump the contents of this module to the given output stream. void dump() const; diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def index c5352dadc0de..5e2977f478f3 100644 --- a/clang/include/clang/Basic/OpenCLExtensions.def +++ b/clang/include/clang/Basic/OpenCLExtensions.def @@ -68,7 +68,7 @@ OPENCL_OPTIONALCOREFEATURE(cl_khr_fp64, true, 100, OCL_C_12P) OPENCL_EXTENSION(cl_khr_fp16, true, 100) OPENCL_EXTENSION(cl_khr_int64_base_atomics, true, 100) OPENCL_EXTENSION(cl_khr_int64_extended_atomics, true, 100) -OPENCL_COREFEATURE(cl_khr_3d_image_writes, true, 100, OCL_C_20) +OPENCL_GENERIC_EXTENSION(cl_khr_3d_image_writes, true, 100, OCL_C_20, OCL_C_30) // EMBEDDED_PROFILE OPENCL_EXTENSION(cles_khr_int64, true, 110) diff --git a/clang/include/clang/Basic/OpenCLOptions.h b/clang/include/clang/Basic/OpenCLOptions.h index 0f7cffb262c0..9ad3a5681054 100644 --- a/clang/include/clang/Basic/OpenCLOptions.h +++ b/clang/include/clang/Basic/OpenCLOptions.h @@ -112,7 +112,10 @@ class OpenCLOptions { bool isKnown(llvm::StringRef Ext) const; - bool isEnabled(llvm::StringRef Ext) const; + // For core or optional core feature check that it is supported + // by a target, for any other option (extension) check that it is + // enabled via pragma + bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const; bool isWithPragma(llvm::StringRef Ext) const; @@ -160,15 +163,15 @@ class OpenCLOptions { // Disable all extensions void disableAll(); - // Enable supported core and optional core features - void enableSupportedCore(const LangOptions &LO); - friend class ASTWriter; friend class ASTReader; using OpenCLOptionInfoMap = llvm::StringMap; private: + // Option is enabled via pragma + bool isEnabled(llvm::StringRef Ext) const; + OpenCLOptionInfoMap OptMap; }; diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 66df4d363e0e..d2e8fa69a584 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -275,3 +275,5 @@ def OMPTargetTeamsDistributeDirective : StmtNode; def OMPTargetTeamsDistributeParallelForDirective : StmtNode; def OMPTargetTeamsDistributeParallelForSimdDirective : StmtNode; def OMPTargetTeamsDistributeSimdDirective : StmtNode; +def OMPInteropDirective : StmtNode; +def OMPDispatchDirective : StmtNode; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 9791cb6bbee7..3ddb706dcf52 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -155,12 +155,20 @@ struct TransferrableTargetInfo { /// zero-length bitfield. unsigned UseZeroLengthBitfieldAlignment : 1; + /// Whether zero length bitfield alignment is respected if they are the + /// leading members. + unsigned UseLeadingZeroLengthBitfield : 1; + /// Whether explicit bit field alignment attributes are honored. unsigned UseExplicitBitFieldAlignment : 1; /// If non-zero, specifies a fixed alignment value for bitfields that follow /// zero length bitfield, regardless of the zero length bitfield type. unsigned ZeroLengthBitfieldBoundary; + + /// If non-zero, specifies a maximum alignment to truncate alignment + /// specified in the aligned attribute of a static variable to this value. + unsigned MaxAlignedAttribute; }; /// OpenCL type kinds. @@ -768,12 +776,22 @@ class TargetInfo : public virtual TransferrableTargetInfo, return UseZeroLengthBitfieldAlignment; } + /// Check whether zero length bitfield alignment is respected if they are + /// leading members. + bool useLeadingZeroLengthBitfield() const { + return UseLeadingZeroLengthBitfield; + } + /// Get the fixed alignment value in bits for a member that follows /// a zero length bitfield. unsigned getZeroLengthBitfieldBoundary() const { return ZeroLengthBitfieldBoundary; } + /// Get the maximum alignment in bits for a static variable with + /// aligned attribute. + unsigned getMaxAlignedAttribute() const { return MaxAlignedAttribute; } + /// Check whether explicit bitfield alignment attributes should be // honored, as in "__attribute__((aligned(2))) int b : 1;". bool useExplicitBitFieldAlignment() const { diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td new file mode 100644 index 000000000000..2932ee1ab0f2 --- /dev/null +++ b/clang/include/clang/Basic/riscv_vector.td @@ -0,0 +1,400 @@ +//==--- riscv_vector.td - RISC-V V-ext Builtin function list --------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the builtins for RISC-V V-extension. See: +// +// https://github.com/riscv/rvv-intrinsic-doc +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction definitions +//===----------------------------------------------------------------------===// +// Each record of the class RVVBuiltin defines a collection of builtins (i.e. +// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1", +// "vadd_vv_i32m2", etc). +// +// The elements of this collection are defined by an instantiation process the +// range of which is specified by the cross product of the LMUL attribute and +// every element in the attribute TypeRange. By default builtins have LMUL = [1, +// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we +// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL. +// +// LMUL represents the fact that the types of values used by that builtin are +// values generated by instructions that are executed under that LMUL. However, +// this does not mean the builtin is necessarily lowered into an instruction +// that executes under the specified LMUL. An example where this happens are +// loads and stores of masks. A mask like `vbool8_t` can be generated, for +// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two +// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will +// be performed under LMUL=1 because mask registers are not grouped. +// +// TypeRange is a non-empty sequence of basic types: +// +// c: int8_t (i8) +// s: int16_t (i16) +// i: int32_t (i32) +// l: int64_t (i64) +// h: float16_t (half) +// f: float32_t (float) +// d: float64_t (double) +// +// This way, given an LMUL, a record with a TypeRange "sil" will cause the +// definition of 3 builtins. Each type "t" in the TypeRange (in this example +// they are int16_t, int32_t, int64_t) is used as a parameter that drives the +// definition of that particular builtin (for the given LMUL). +// +// During the instantiation, types can be transformed or modified using type +// transformers. Given a type "t" the following primitive type transformers can +// be applied to it to yield another type. +// +// e: type of "t" as is (identity) +// v: computes a vector type whose element type is "t" for the current LMUL +// w: computes a vector type identical to what 'v' computes except for the +// element type which is twice as wide as the element type of 'v' +// q: computes a vector type identical to what 'v' computes except for the +// element type which is four times as wide as the element type of 'v' +// o: computes a vector type identical to what 'v' computes except for the +// element type which is eight times as wide as the element type of 'v' +// m: computes a vector type identical to what 'v' computes except for the +// element type which is bool +// 0: void type, ignores "t" +// z: size_t, ignores "t" +// t: ptrdiff_t, ignores "t" +// c: uint8_t, ignores "t" +// +// So for instance if t is "i", i.e. int, then "e" will yield int again. "v" +// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t. +// Accordingly "w" would yield __rvv_int64m2_t. +// +// A type transformer can be prefixed by other non-primitive type transformers. +// +// P: constructs a pointer to the current type +// C: adds const to the type +// K: requires the integer type to be a constant expression +// U: given an integer type or vector type, computes its unsigned variant +// I: given a vector type, compute the vector type with integer type +// elements of the same width +// F: given a vector type, compute the vector type with floating-point type +// elements of the same width +// S: given a vector type, computes its equivalent one for LMUL=1. This is a +// no-op if the vector was already LMUL=1 +// (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a +// vector type (SEW and LMUL) and EEW (8/16/32/64), computes its +// equivalent integer vector type with EEW and corresponding ELMUL (elmul = +// (eew/sew) * lmul). For example, vector type is __rvv_float16m4 +// (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector +// type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new +// builtins if its equivalent type has illegal lmul. +// +// Following with the example above, if t is "i", then "Ue" will yield unsigned +// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would +// yield __rvv_float64m2_t, etc. +// +// Each builtin is then defined by applying each type in TypeRange against the +// sequence of type transformers described in Suffix and Prototype. +// +// The name of the builtin is defined by the Name attribute (which defaults to +// the name of the class) appended (separated with an underscore) the Suffix +// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il", +// the builtin generated will be __builtin_rvv_foo_i32m1 and +// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one +// type transformer (say "vv") each of the types is separated with an +// underscore as in "__builtin_rvv_foo_i32m1_i32m1". +// +// The C/C++ prototype of the builtin is defined by the Prototype attribute. +// Prototype is a non-empty sequence of type transformers, the first of which +// is the return type of the builtin and the rest are the parameters of the +// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si" +// a first builtin will have type +// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin +// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again +// under LMUL=1). +// +// There are a number of attributes that are used to constraint the number and +// shape of the builtins generated. Refer to the comments below for them. +class RVVBuiltin { + // Base name that will be prepended in __builtin_rvv_ and appended the + // computed Suffix. + string Name = NAME; + + // If not empty, each instantiated builtin will have this appended after an + // underscore (_). It is instantiated like Prototype. + string Suffix = suffix; + + // If empty, default MangledName is sub string of `Name` which end of first + // '_'. For example, the default mangled name is `vadd` for Name `vadd_vv`. + // It's used for describe some special naming cases. + string MangledName = ""; + + // The different variants of the builtin, parameterised with a type. + string TypeRange = type_range; + + // We use each type described in TypeRange and LMUL with prototype to + // instantiate a specific element of the set of builtins being defined. + // Prototype attribute defines the C/C++ prototype of the builtin. It is a + // non-empty sequence of type transformers, the first of which is the return + // type of the builtin and the rest are the parameters of the builtin, in + // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a + // first builtin will have type + // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin + // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t). + string Prototype = prototype; + + // This builtin has a masked form. + bit HasMask = true; + + // If HasMask, this flag states that this builtin has a maskedoff operand. It + // is always the first operand in builtin and IR intrinsic. + bit HasMaskedOffOperand = true; + + // This builtin has a granted vector length parameter in the last position. + bit HasVL = true; + + // This builtin supports non-masked function overloading api. + // All masked operations support overloading api. + bit HasNoMaskedOverloaded = true; + + // Reads or writes "memory" or has other side-effects. + bit HasSideEffects = false; + + // This builtin is valid for the given Log2LMULs. + list Log2LMUL = [0, 1, 2, 3, -1, -2, -3]; + + // Manual code in clang codegen riscv_vector_builtin_cg.inc + code ManualCodegen = [{}]; + code ManualCodegenMask = [{}]; + + // When emit the automatic clang codegen, it describes what types we have to use + // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise, + // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd + // parameter of the unmasked version. k can't be the mask operand's position. + list IntrinsicTypes = []; + + // When the order of the parameters of clang builtin do not match the order of + // C/C++ api, we use permutation index to mapping the operand from clang + // builtin to C/C++. It is parameter of the unmasked version without VL + // operand. If empty, the default permutation is [0, 1, 2, ...]. + list PermuteOperands = []; + + // If these names are not empty, this is the ID of the LLVM intrinsic + // we want to lower to. + string IRName = NAME; + + // If HasMask, this is the ID of the LLVM intrinsic we want to lower to. + string IRNameMask = NAME #"_mask"; + + // If non empty, this is the code emitted in the header, otherwise + // an automatic definition in header is emitted. + string HeaderCode = ""; + +} + +//===----------------------------------------------------------------------===// +// Basic classes with automatic codegen. +//===----------------------------------------------------------------------===// + +class RVVBinBuiltin + : RVVBuiltin { + let IntrinsicTypes = [-1, 1]; +} + +multiclass RVVBinBuiltinSet> suffixes_prototypes> { + let IRName = intrinsic_name, IRNameMask = intrinsic_name # "_mask" in { + foreach s_p = suffixes_prototypes in { + let Name = NAME # "_" # s_p[0] in { + defvar suffix = s_p[1]; + defvar prototype = s_p[2]; + def : RVVBinBuiltin; + } + } + } +} + +defvar TypeList = ["c","s","i","l","f","d"]; +defvar EEWList = [["8", "(Log2EEW:3)"], + ["16", "(Log2EEW:4)"], + ["32", "(Log2EEW:5)"], + ["64", "(Log2EEW:6)"]]; + +class IsFloat { + bit val = !or(!eq(type, "h"), !eq(type, "f"), !eq(type, "d")); +} + +multiclass RVVVLEBuiltin types> { + let Name = NAME # "_v", + IRName = "vle", + IRNameMask ="vle_mask", + HasNoMaskedOverloaded = false, + ManualCodegen = [{ + IntrinsicTypes = {ResultType, Ops[1]->getType()}; + Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo()); + }], + ManualCodegenMask= [{ + IntrinsicTypes = {ResultType, Ops[3]->getType()}; + Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo()); + }] in { + foreach type = types in { + def : RVVBuiltin<"v", "vPCe", type>; + if !not(IsFloat.val) then { + def : RVVBuiltin<"Uv", "UvPCUe", type>; + } + } + } +} + +multiclass RVVIndexedLoad { + let ManualCodegen = [{ + IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()}; + Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo()); + }], + ManualCodegenMask = [{ + IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops[4]->getType()}; + Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo()); + }] in { + foreach type = TypeList in { + foreach eew_list = EEWList in { + defvar eew = eew_list[0]; + defvar eew_type = eew_list[1]; + let Name = op # eew # "_v", IRName = op, IRNameMask = op # "_mask" in { + def: RVVBuiltin<"v", "vPCe" # eew_type # "Uv", type>; + if !not(IsFloat.val) then { + def: RVVBuiltin<"Uv", "UvPCUe" # eew_type # "Uv", type>; + } + } + } + } + } +} + +multiclass RVVVSEBuiltin types> { + let Name = NAME # "_v", + IRName = "vse", + IRNameMask = "vse_mask", + HasMaskedOffOperand = false, + PermuteOperands = [1, 0], // C/C++ Operand: (ptr, value, vl). Builtin: (value, ptr, vl) + ManualCodegen = [{ + Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo()); + IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType()}; + }], + ManualCodegenMask= [{ + Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo()); + IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()}; + }] in { + foreach type = types in { + def : RVVBuiltin<"v", "0vPe", type>; + if !not(IsFloat.val) then { + def : RVVBuiltin<"Uv", "0UvPUe", type>; + } + } + } +} + +// 6. Configuration-Setting Instructions +// 6.1. vsetvli/vsetvl instructions +let HasVL = false, + HasMask = false, + HasSideEffects = true, + Log2LMUL = [0], + ManualCodegen = [{IntrinsicTypes = {ResultType};}] in // Set XLEN type +{ + // vsetvl is a macro because for it require constant integers in SEW and LMUL. + let HeaderCode = +[{ +#define vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5) +#define vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6) +#define vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7) +#define vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0) +#define vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1) +#define vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2) +#define vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3) + +#define vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6) +#define vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7) +#define vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0) +#define vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1) +#define vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2) +#define vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3) + +#define vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7) +#define vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0) +#define vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1) +#define vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2) +#define vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3) + +#define vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0) +#define vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1) +#define vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2) +#define vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3) + +}] in + def vsetvli : RVVBuiltin<"", "zzKzKz", "i">; + + let HeaderCode = +[{ +#define vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5) +#define vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6) +#define vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7) +#define vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0) +#define vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1) +#define vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2) +#define vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3) + +#define vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6) +#define vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7) +#define vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0) +#define vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1) +#define vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2) +#define vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3) + +#define vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7) +#define vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0) +#define vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1) +#define vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2) +#define vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3) + +#define vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0) +#define vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1) +#define vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2) +#define vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3) + +}] in + def vsetvlimax : RVVBuiltin<"", "zKzKz", "i">; +} + +// 7. Vector Loads and Stores +// 7.4. Vector Unit-Stride Instructions +defm vle8: RVVVLEBuiltin<["c"]>; +defm vle16: RVVVLEBuiltin<["s"]>; +defm vle32: RVVVLEBuiltin<["i","f"]>; +defm vle64: RVVVLEBuiltin<["l","d"]>; + +defm vse8 : RVVVSEBuiltin<["c"]>; +defm vse16: RVVVSEBuiltin<["s"]>; +defm vse32: RVVVSEBuiltin<["i","f"]>; +defm vse64: RVVVSEBuiltin<["l","d"]>; + +// 7.6. Vector Indexed Instructions +defm : RVVIndexedLoad<"vluxei">; +defm : RVVIndexedLoad<"vloxei">; + +// 12. Vector Integer Arithmetic Instructions +// 12.1. Vector Single-Width Integer Add and Subtract +defm vadd : RVVBinBuiltinSet<"vadd", "csil", + [["vv", "v", "vvv"], + ["vx", "v", "vve"], + ["vv", "Uv", "UvUvUv"], + ["vx", "Uv", "UvUvUe"]]>; + +// 14. Vector Floating-Point Instructions +// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions +defm vfadd : RVVBinBuiltinSet<"vfadd", "fd", + [["vv", "v", "vvv"], + ["vf", "v", "vve"]]>; diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index 54c20620910b..469c000c952c 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -157,16 +157,16 @@ class Driver { std::string HostBits, HostMachine, HostSystem, HostRelease; /// The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled. - const char *CCPrintStatReportFilename; + std::string CCPrintStatReportFilename; /// The file to log CC_PRINT_OPTIONS output to, if enabled. - const char *CCPrintOptionsFilename; + std::string CCPrintOptionsFilename; /// The file to log CC_PRINT_HEADERS output to, if enabled. - const char *CCPrintHeadersFilename; + std::string CCPrintHeadersFilename; /// The file to log CC_LOG_DIAGNOSTICS output to, if enabled. - const char *CCLogDiagnosticsFilename; + std::string CCLogDiagnosticsFilename; /// A list of inputs and their types for the given arguments. typedef SmallVector, 16> diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 13b0dc8c8c63..8618bfdbd004 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -603,8 +603,14 @@ def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[NoXarchOption, CoreOption, Flan def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>, Flags<[NoXarchOption, CoreOption]>; def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>, Group; -def B : JoinedOrSeparate<["-"], "B">, MetaVarName<"">, - HelpText<"Add to search path for binaries and object files used implicitly">; +def B : JoinedOrSeparate<["-"], "B">, MetaVarName<"">, + HelpText<"Search $prefix/$triple-$file and $prefix$file for executables, libraries, " + "includes, and data files used by the compiler. $prefix may or may not be a directory">; +def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>, + HelpText<"Search for GCC installation in the specified directory on targets which commonly use GCC. " + "The directory usually contains 'lib{,32,64}/gcc{,-cross}/$triple' and 'include'. If specified, " + "sysroot is skipped for GCC detection. Note: executables (e.g. ld) used by the compiler are not " + "overridden by the selected GCC installation">; def CC : Flag<["-"], "CC">, Flags<[CC1Option]>, Group, HelpText<"Include comments from within macros in preprocessed output">, MarshallingInfoFlag>; @@ -982,11 +988,6 @@ def dependency_dot : Separate<["-"], "dependency-dot">, Flags<[CC1Option]>, def module_dependency_dir : Separate<["-"], "module-dependency-dir">, Flags<[CC1Option]>, HelpText<"Directory to dump module dependencies to">, MarshallingInfoString>; -def module_dir : Separate<["-"], "module-dir">, Flags<[FlangOption,FC1Option]>, MetaVarName<"">, - HelpText<"Put MODULE files in ">, - DocBrief<[{This option specifies where to put .mod files for compiled modules. -It is also added to the list of directories to be searched by an USE statement. -The default is the current directory.}]>; def dsym_dir : JoinedOrSeparate<["-"], "dsym-dir">, Flags<[NoXarchOption, RenderAsInput]>, HelpText<"Directory to output dSYM's (if any) to">, MetaVarName<"">; @@ -1127,6 +1128,7 @@ def fcoverage_compilation_dir_EQ : Joined<["-"], "fcoverage-compilation-dir=">, HelpText<"The compilation directory to embed in the coverage mapping.">, MarshallingInfoString>; def ffile_compilation_dir_EQ : Joined<["-"], "ffile-compilation-dir=">, Group, + Flags<[CoreOption]>, HelpText<"The compilation directory to embed in the debug info and coverage mapping.">; defm debug_info_for_profiling : BoolFOption<"debug-info-for-profiling", CodeGenOpts<"DebugInfoForProfiling">, DefaultFalse, @@ -1279,7 +1281,9 @@ def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit="> Group; def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group, Flags<[NoArgumentUnused, CoreOption]>, HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">; -def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, Group, Flags<[NoArgumentUnused, CoreOption]>; +def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, + Group, Flags<[NoArgumentUnused, CoreOption]>, + HelpText<"Put crash-report files in ">, MetaVarName<"">; def fcreate_profile : Flag<["-"], "fcreate-profile">, Group; defm cxx_exceptions: BoolFOption<"cxx-exceptions", LangOpts<"CXXExceptions">, DefaultFalse, @@ -2375,7 +2379,10 @@ defm signed_char : BoolFOption<"signed-char", LangOpts<"CharIsSigned">, DefaultTrue, NegFlag, PosFlag>, ShouldParseIf; -def fsplit_stack : Flag<["-"], "fsplit-stack">, Group; +defm split_stack : BoolFOption<"split-stack", + CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, + NegFlag, + PosFlag>; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", @@ -2717,6 +2724,7 @@ def ggdb2 : Flag<["-"], "ggdb2">, Group; def ggdb3 : Flag<["-"], "ggdb3">, Group; def glldb : Flag<["-"], "glldb">, Group; def gsce : Flag<["-"], "gsce">, Group; +def gdbx : Flag<["-"], "gdbx">, Group; // Equivalent to our default dwarf version. Forces usual dwarf emission when // CodeView is enabled. def gdwarf : Flag<["-"], "gdwarf">, Group, Flags<[CoreOption]>, @@ -3126,8 +3134,6 @@ def mharden_sls_EQ : Joined<["-"], "mharden-sls=">, HelpText<"Select straight-line speculation hardening scope">; def msimd128 : Flag<["-"], "msimd128">, Group; -def munimplemented_simd128 : Flag<["-"], "munimplemented-simd128">, Group; -def mno_unimplemented_simd128 : Flag<["-"], "mno-unimplemented-simd128">, Group; def mno_simd128 : Flag<["-"], "mno-simd128">, Group; def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group; def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group; @@ -3245,7 +3251,9 @@ def mno_longcall : Flag<["-"], "mno-longcall">, Group; def mmma: Flag<["-"], "mmma">, Group; def mno_mma: Flag<["-"], "mno-mma">, Group; -def mrop_protection : Flag<["-"], "mrop-protection">, +def mrop_protect : Flag<["-"], "mrop-protect">, + Group; +def mprivileged : Flag<["-"], "mprivileged">, Group; def maix_struct_return : Flag<["-"], "maix-struct-return">, Group, Flags<[CC1Option]>, @@ -3320,10 +3328,6 @@ def mstack_protector_guard_offset_EQ : Joined<["-"], "mstack-protector-guard-off def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg=">, Group, Flags<[CC1Option]>, HelpText<"Use the given reg for addressing the stack-protector guard">, MarshallingInfoString, [{"none"}]>; -def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">, - Alias, Group; -def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, - Alias, Group; def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">, Flags<[CC1Option]>, Group, MarshallingInfoFlag>; @@ -3534,8 +3538,8 @@ def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">; def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>; def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group, Flags<[CC1Option]>, MarshallingInfoFlag>; -def pedantic : Flag<["-", "--"], "pedantic">, Group, Flags<[CC1Option]>, - MarshallingInfoFlag>; +def pedantic : Flag<["-", "--"], "pedantic">, Group, Flags<[CC1Option,FlangOption,FC1Option]>, + HelpText<"Warn on language extensions">, MarshallingInfoFlag>; def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">, Flags<[CC1Option]>, MarshallingInfoFlag>; def pipe : Flag<["-", "--"], "pipe">, @@ -3569,6 +3573,8 @@ def print_targets : Flag<["-", "--"], "print-targets">, HelpText<"Print the registered targets">; def print_rocm_search_dirs : Flag<["-", "--"], "print-rocm-search-dirs">, HelpText<"Print the paths used for finding ROCm installation">; +def print_runtime_dir : Flag<["-", "--"], "print-runtime-dir">, + HelpText<"Print the directory pathname containing clangs runtime libraries">; def private__bundle : Flag<["-"], "private_bundle">; def pthreads : Flag<["-"], "pthreads">; defm pthread : BoolOption<"", "pthread", @@ -3635,7 +3641,7 @@ def static_libgcc : Flag<["-"], "static-libgcc">; def static_libstdcxx : Flag<["-"], "static-libstdc++">; def static : Flag<["-", "--"], "static">, Group, Flags<[NoArgumentUnused]>; def std_default_EQ : Joined<["-"], "std-default=">; -def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>, +def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option,FlangOption,FC1Option]>, Group, HelpText<"Language standard to compile for">, ValuesCode<[{ const char *Values = @@ -3674,8 +3680,6 @@ def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">, MarshallingInfoFlag>; def mcpu_EQ_QUESTION : Flag<["-"], "mcpu=?">, Alias; def mtune_EQ_QUESTION : Flag<["-"], "mtune=?">, Alias; -def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>, - HelpText<"Use the gcc toolchain at the given directory">; def time : Flag<["-"], "time">, HelpText<"Time individual commands">; def traditional_cpp : Flag<["-", "--"], "traditional-cpp">, Flags<[CC1Option]>, @@ -4242,7 +4246,6 @@ defm devirtualize_speculatively : BooleanFFlag<"devirtualize-speculatively">, // Generic gfortran options. def A_DASH : Joined<["-"], "A-">, Group; -def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined,FlangOption,FC1Option]>, Group, Alias; def cpp : Flag<["-"], "cpp">, Group; def nocpp : Flag<["-"], "nocpp">, Group; def static_libgfortran : Flag<["-"], "static-libgfortran">, Group; @@ -4284,7 +4287,6 @@ defm f2c : BooleanFFlag<"f2c">, Group; defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group; defm init_local_zero : BooleanFFlag<"init-local-zero">, Group; defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group; -defm intrinsic_modules_path : BooleanFFlag<"intrinsic-modules-path">, Group; defm max_identifier_length : BooleanFFlag<"max-identifier-length">, Group; defm module_private : BooleanFFlag<"module-private">, Group; defm pack_derived : BooleanFFlag<"pack-derived">, Group; @@ -4306,15 +4308,10 @@ defm underscoring : BooleanFFlag<"underscoring">, Group; defm whole_file : BooleanFFlag<"whole-file">, Group; // C++ SYCL options -defm sycl : BoolOption<"f", "sycl", - LangOpts<"SYCL">, DefaultFalse, - PosFlag, NegFlag, - BothFlags<[CoreOption], " SYCL kernels compilation for device">>, - Group; -def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group, Flags<[CC1Option, NoArgumentUnused, CoreOption]>, - HelpText<"SYCL language standard to compile for.">, Values<"2017,121,1.2.1,sycl-1.2.1">, - NormalizedValues<["SYCL_2017", "SYCL_2017", "SYCL_2017", "SYCL_2017"]>, NormalizedValuesScope<"LangOptions">, - MarshallingInfoEnum, "SYCL_None">, ShouldParseIf; +def fsycl : Flag<["-"], "fsycl">, Flags<[NoXarchOption, CoreOption]>, + Group, HelpText<"Enables SYCL kernels compilation for device">; +def fno_sycl : Flag<["-"], "fno-sycl">, Flags<[NoXarchOption, CoreOption]>, + Group, HelpText<"Disables SYCL kernels compilation for device">; //===----------------------------------------------------------------------===// // FLangOption + CoreOption + NoXarchOption @@ -4330,6 +4327,12 @@ def Xflang : Separate<["-"], "Xflang">, //===----------------------------------------------------------------------===// let Flags = [FC1Option, FlangOption, FlangOnlyOption] in { +def module_dir : Separate<["-"], "module-dir">, MetaVarName<"">, + HelpText<"Put MODULE files in ">, + DocBrief<[{This option specifies where to put .mod files for compiled modules. +It is also added to the list of directories to be searched by an USE statement. +The default is the current directory.}]>; + def ffixed_form : Flag<["-"], "ffixed-form">, Group, HelpText<"Process source files in fixed form">; def ffree_form : Flag<["-"], "ffree-form">, Group, @@ -4365,8 +4368,17 @@ def fimplicit_none : Flag<["-"], "fimplicit-none">, Group, def fno_implicit_none : Flag<["-"], "fno-implicit-none">, Group; def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group, HelpText<"Enable the old style PARAMETER statement">; +def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group, MetaVarName<"">, + HelpText<"Specify where to find the compiled intrinsic modules">, + DocBrief<[{This option specifies the location of pre-compiled intrinsic modules, + if they are not in the default location expected by the compiler.}]>; } +def J : JoinedOrSeparate<["-"], "J">, + Flags<[RenderJoined, FlangOption, FC1Option, FlangOnlyOption]>, + Group, + Alias; + //===----------------------------------------------------------------------===// // FC1 Options //===----------------------------------------------------------------------===// @@ -4384,10 +4396,16 @@ def fdebug_dump_parse_tree : Flag<["-"], "fdebug-dump-parse-tree">, Group; def fdebug_dump_provenance : Flag<["-"], "fdebug-dump-provenance">, Group, HelpText<"Dump provenance">; +def fdebug_dump_parsing_log : Flag<["-"], "fdebug-dump-parsing-log">, Group, + HelpText<"Run instrumented parse and dump the parsing log">; def fdebug_measure_parse_tree : Flag<["-"], "fdebug-measure-parse-tree">, Group, HelpText<"Measure the parse tree">; def fdebug_pre_fir_tree : Flag<["-"], "fdebug-pre-fir-tree">, Group, HelpText<"Dump the pre-FIR tree">; +def fdebug_module_writer : Flag<["-"],"fdebug-module-writer">, + HelpText<"Enable debug messages while writing module files">; +def fget_symbols_sources : Flag<["-"], "fget-symbols-sources">, Group, + HelpText<"Dump symbols and their source code locations">; } @@ -4618,8 +4636,8 @@ def default_function_attr : Separate<["-"], "default-function-attr">, def dwarf_version_EQ : Joined<["-"], "dwarf-version=">, MarshallingInfoInt>; def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">, - Values<"gdb,lldb,sce">, - NormalizedValuesScope<"llvm::DebuggerKind">, NormalizedValues<["GDB", "LLDB", "SCE"]>, + Values<"gdb,lldb,sce,dbx">, + NormalizedValuesScope<"llvm::DebuggerKind">, NormalizedValues<["GDB", "LLDB", "SCE", "DBX"]>, MarshallingInfoEnum, "Default">; def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, HelpText<"The string to embed in the Dwarf debug flags record.">, @@ -4763,9 +4781,6 @@ def mtp : Separate<["-"], "mtp">, def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, HelpText<"Limit float precision to the given value">, MarshallingInfoString>; -def split_stacks : Flag<["-"], "split-stacks">, - HelpText<"Try to use a split stack if possible.">, - MarshallingInfoFlag>; def mregparm : Separate<["-"], "mregparm">, HelpText<"Limit the number of registers available for integer arguments">, MarshallingInfoInt>; @@ -4886,6 +4901,18 @@ def fexperimental_debug_variable_locations : Flag<["-"], "fexperimental-debug-variable-locations">, HelpText<"Use experimental new value-tracking variable locations">, MarshallingInfoFlag>; +def fverify_debuginfo_preserve + : Flag<["-"], "fverify-debuginfo-preserve">, + HelpText<"Enable Debug Info Metadata preservation testing in " + "optimizations.">, + MarshallingInfoFlag>; +def fverify_debuginfo_preserve_export + : Joined<["-"], "fverify-debuginfo-preserve-export=">, + MetaVarName<"">, + HelpText<"Export debug info (by testing original Debug Info) failures " + "into specified (JSON) file (should be abs path as we use " + "append mode to insert new JSON objects).">, + MarshallingInfoString>; // The driver option takes the key as a parameter to the -msign-return-address= // and -mbranch-protection= options, but CC1 has a separate option so we // don't have to parse the parameter twice. @@ -5565,11 +5592,22 @@ def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">, def fsycl_is_device : Flag<["-"], "fsycl-is-device">, HelpText<"Generate code for SYCL device.">, - MarshallingInfoFlag>, - ShouldParseIf; + MarshallingInfoFlag>; +def fsycl_is_host : Flag<["-"], "fsycl-is-host">, + HelpText<"SYCL host compilation">, + MarshallingInfoFlag>; } // let Flags = [CC1Option, NoDriverOption] +def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group, + Flags<[CC1Option, NoArgumentUnused, CoreOption]>, + HelpText<"SYCL language standard to compile for.">, + Values<"2017,121,1.2.1,sycl-1.2.1">, + NormalizedValues<["SYCL_2017", "SYCL_2017", "SYCL_2017", "SYCL_2017"]>, + NormalizedValuesScope<"LangOptions">, + MarshallingInfoEnum, "SYCL_None">, + ShouldParseIf; + defm cuda_approx_transcendentals : BoolFOption<"cuda-approx-transcendentals", LangOpts<"CUDADeviceApproxTranscendentals">, DefaultFalse, PosFlag, NegFlag, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index e7e5a1f7a6ad..e5c6b8104c6f 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -603,6 +603,9 @@ class ToolChain { // given compilation arguments. virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const; + // Detect the highest available version of libc++ in include path. + virtual std::string detectLibcxxVersion(StringRef IncludePath) const; + /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set /// the include paths to use for the given C++ standard library type. virtual void diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 79e8d109cd97..997eea445c22 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -38,6 +38,7 @@ TYPE("cpp-output", PP_C, INVALID, "i", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("c", C, PP_C, "c", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("cl", CL, PP_C, "cl", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("clcpp", CLCXX, PP_CXX, "clcpp", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("cuda-cpp-output", PP_CUDA, INVALID, "cui", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("cuda", CUDA, PP_CUDA, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("cuda", CUDA_DEVICE, PP_CUDA, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 0c4f0fe277b7..f131f045a73e 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -63,6 +63,7 @@ class NumericLiteralParser { bool isUnsigned : 1; bool isLong : 1; // This is *not* set for long long. bool isLongLong : 1; + bool isSizeT : 1; // 1z, 1uz (C++2b) bool isHalf : 1; // 1.0h bool isFloat : 1; // 1.0f bool isImaginary : 1; // 1.0i diff --git a/clang/include/clang/Lex/MacroInfo.h b/clang/include/clang/Lex/MacroInfo.h index 550abf35c841..0347a7a37186 100644 --- a/clang/include/clang/Lex/MacroInfo.h +++ b/clang/include/clang/Lex/MacroInfo.h @@ -521,7 +521,7 @@ class ModuleMacro : public llvm::FoldingSetNode { } static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule, - IdentifierInfo *II) { + const IdentifierInfo *II) { ID.AddPointer(OwningModule); ID.AddPointer(II); } diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h index f6423e5b4258..64562e6760df 100644 --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -696,6 +696,9 @@ class ModuleMap { module_iterator module_begin() const { return Modules.begin(); } module_iterator module_end() const { return Modules.end(); } + llvm::iterator_range modules() const { + return {module_begin(), module_end()}; + } /// Cache a module load. M might be nullptr. void cacheModuleLoad(const IdentifierInfo &II, Module *M) { diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 68139cb24b31..d89c4753f8d1 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1151,7 +1151,7 @@ class Preprocessor { /// Register an exported macro for a module and identifier. ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef Overrides, bool &IsNew); - ModuleMacro *getModuleMacro(Module *Mod, IdentifierInfo *II); + ModuleMacro *getModuleMacro(Module *Mod, const IdentifierInfo *II); /// Get the list of leaf (non-overridden) module macros for a name. ArrayRef getLeafModuleMacros(const IdentifierInfo *II) const { @@ -1163,6 +1163,11 @@ class Preprocessor { return None; } + /// Get the list of submodules that we're currently building. + ArrayRef getBuildingSubmodules() const { + return BuildingSubmoduleStack; + } + /// \{ /// Iterators for the macro history table. Currently defined macros have /// IdentifierInfo::hasMacroDefinition() set and an empty diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 09a0dd2cf233..b67e541836d5 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -941,8 +941,8 @@ class Parser : public CodeCompletionHandler { bool isActive; public: - explicit TentativeParsingAction(Parser& p) : P(p) { - PrevPreferredType = P.PreferredType; + explicit TentativeParsingAction(Parser &p) + : P(p), PrevPreferredType(P.PreferredType) { PrevTok = P.Tok; PrevTentativelyDeclaredIdentifierCount = P.TentativelyDeclaredIdentifiers.size(); @@ -1991,7 +1991,8 @@ class Parser : public CodeCompletionHandler { Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc, Sema::ConditionKind CK, - ForRangeInfo *FRI = nullptr); + ForRangeInfo *FRI = nullptr, + bool EnterForConditionScope = false); //===--------------------------------------------------------------------===// // C++ Coroutines @@ -2638,7 +2639,8 @@ class Parser : public CodeCompletionHandler { // which standard permits but we don't supported yet, for example, attributes // appertain to decl specifiers. void ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, - unsigned DiagID); + unsigned DiagID, + bool DiagnoseEmptyAttrs = false); /// Skip C++11 and C2x attributes and return the end location of the /// last one. @@ -3292,6 +3294,14 @@ class Parser : public CodeCompletionHandler { /// '(' { [ '(' ')' ] }+ ')' OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind); + /// Parses clause with an interop variable of kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// \param ParseOnly true to skip the clause's semantic actions and return + /// nullptr. + // + OMPClause *ParseOpenMPInteropClause(OpenMPClauseKind Kind, bool ParseOnly); + public: /// Parses simple expression in parens for single-expression clauses of OpenMP /// constructs. diff --git a/clang/include/clang/Sema/AnalysisBasedWarnings.h b/clang/include/clang/Sema/AnalysisBasedWarnings.h index e13fe955eaf4..49b69c585ff7 100644 --- a/clang/include/clang/Sema/AnalysisBasedWarnings.h +++ b/clang/include/clang/Sema/AnalysisBasedWarnings.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H #include "llvm/ADT/DenseMap.h" +#include namespace clang { @@ -47,6 +48,9 @@ class AnalysisBasedWarnings { Sema &S; Policy DefaultPolicy; + class InterProceduralData; + std::unique_ptr IPData; + enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 }; llvm::DenseMap VisitedFD; @@ -88,6 +92,7 @@ class AnalysisBasedWarnings { public: AnalysisBasedWarnings(Sema &s); + ~AnalysisBasedWarnings(); void IssueWarnings(Policy P, FunctionScopeInfo *fscope, const Decl *D, QualType BlockType); @@ -97,6 +102,7 @@ class AnalysisBasedWarnings { void PrintStats() const; }; -}} // end namespace clang::sema +} // namespace sema +} // namespace clang #endif diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index dcdfa3c3cf64..a764a36d3312 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -187,8 +187,8 @@ class alignas(8) InitializedEntity { ObjCMethodDecl *MethodDecl; /// When Kind == EK_Parameter, the ParmVarDecl, with the - /// low bit indicating whether the parameter is "consumed". - uintptr_t Parameter; + /// integer indicating whether the parameter is "consumed". + llvm::PointerIntPair Parameter; /// When Kind == EK_Temporary or EK_CompoundLiteralInit, the type /// source information for the temporary. @@ -197,9 +197,9 @@ class alignas(8) InitializedEntity { struct LN LocAndNRVO; /// When Kind == EK_Base, the base specifier that provides the - /// base class. The lower bit specifies whether the base is an inherited + /// base class. The integer specifies whether the base is an inherited /// virtual base. - uintptr_t Base; + llvm::PointerIntPair Base; /// When Kind == EK_ArrayElement, EK_VectorElement, or /// EK_ComplexElement, the index of the array or vector element being @@ -252,15 +252,14 @@ class alignas(8) InitializedEntity { /// Create the initialization entity for a parameter. static InitializedEntity InitializeParameter(ASTContext &Context, - const ParmVarDecl *Parm) { + ParmVarDecl *Parm) { return InitializeParameter(Context, Parm, Parm->getType()); } /// Create the initialization entity for a parameter, but use /// another type. - static InitializedEntity InitializeParameter(ASTContext &Context, - const ParmVarDecl *Parm, - QualType Type) { + static InitializedEntity + InitializeParameter(ASTContext &Context, ParmVarDecl *Parm, QualType Type) { bool Consumed = (Context.getLangOpts().ObjCAutoRefCount && Parm->hasAttr()); @@ -269,8 +268,7 @@ class alignas(8) InitializedEntity { Entity.Type = Context.getVariableArrayDecayedType(Type.getUnqualifiedType()); Entity.Parent = nullptr; - Entity.Parameter - = (static_cast(Consumed) | reinterpret_cast(Parm)); + Entity.Parameter = {Parm, Consumed}; return Entity; } @@ -283,7 +281,7 @@ class alignas(8) InitializedEntity { Entity.Kind = EK_Parameter; Entity.Type = Context.getVariableArrayDecayedType(Type); Entity.Parent = nullptr; - Entity.Parameter = (Consumed); + Entity.Parameter = {nullptr, Consumed}; return Entity; } @@ -466,19 +464,19 @@ class alignas(8) InitializedEntity { /// parameter. bool isParameterConsumed() const { assert(isParameterKind() && "Not a parameter"); - return (Parameter & 1); + return Parameter.getInt(); } /// Retrieve the base specifier. const CXXBaseSpecifier *getBaseSpecifier() const { assert(getKind() == EK_Base && "Not a base specifier"); - return reinterpret_cast(Base & ~0x1); + return Base.getPointer(); } /// Return whether the base is an inherited virtual base. bool isInheritedVirtualBase() const { assert(getKind() == EK_Base && "Not a base specifier"); - return Base & 0x1; + return Base.getInt(); } /// Determine whether this is an array new with an unknown bound. diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index 43c21faaece9..a3d82fcd84f7 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -39,6 +39,7 @@ class IdentifierInfo; class LangOptions; class ParsedAttr; class Sema; +class Stmt; class TargetInfo; struct ParsedAttrInfo { @@ -80,6 +81,11 @@ struct ParsedAttrInfo { const Decl *D) const { return true; } + /// Check if this attribute appertains to St, and issue a diagnostic if not. + virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, + const Stmt *St) const { + return true; + } /// Check if this attribute is allowed by the language we are compiling, and /// issue a diagnostic if not. virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) const { @@ -573,6 +579,16 @@ class ParsedAttr final return MacroExpansionLoc; } + /// Check if the attribute has exactly as many args as Num. May output an + /// error. Returns false if a diagnostic is produced. + bool checkExactlyNumArgs(class Sema &S, unsigned Num) const; + /// Check if the attribute has at least as many args as Num. May output an + /// error. Returns false if a diagnostic is produced. + bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const; + /// Check if the attribute has at most as many args as Num. May output an + /// error. Returns false if a diagnostic is produced. + bool checkAtMostNumArgs(class Sema &S, unsigned Num) const; + bool isTargetSpecificAttr() const; bool isTypeAttr() const; bool isStmtAttr() const; @@ -582,6 +598,7 @@ class ParsedAttr final unsigned getMaxArgs() const; bool hasVariadicArg() const; bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const; + bool diagnoseAppertainsTo(class Sema &S, const Stmt *St) const; bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const; void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl> diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index b7260f15fe1b..b499ba1e7c2a 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -129,11 +129,17 @@ class Scope { /// This is a compound statement scope. CompoundStmtScope = 0x400000, - /// We are between inheritance colon and the real class/struct definition scope. + /// We are between inheritance colon and the real class/struct definition + /// scope. ClassInheritanceScope = 0x800000, /// This is the scope of a C++ catch statement. CatchScope = 0x1000000, + + /// This is a scope in which a condition variable is currently being + /// parsed. If such a scope is a ContinueScope, it's invalid to jump to the + /// continue block from here. + ConditionVarScope = 0x2000000, }; private: @@ -247,6 +253,17 @@ class Scope { return const_cast(this)->getContinueParent(); } + // Set whether we're in the scope of a condition variable, where 'continue' + // is disallowed despite being a continue scope. + void setIsConditionVarScope(bool InConditionVarScope) { + Flags = (Flags & ~ConditionVarScope) | + (InConditionVarScope ? ConditionVarScope : 0); + } + + bool isConditionVarScope() const { + return Flags & ConditionVarScope; + } + /// getBreakParent - Return the closest scope that a break statement /// would be affected by. Scope *getBreakParent() { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 73c4d74687c1..15ccaac85103 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -286,14 +286,13 @@ class FileNullabilityMap { } }; -/// Keeps track of expected type during expression parsing. The type is tied to -/// a particular token, all functions that update or consume the type take a -/// start location of the token they are looking at as a parameter. This allows -/// to avoid updating the type on hot paths in the parser. +/// Tracks expected type during expression parsing, for use in code completion. +/// The type is tied to a particular token, all functions that update or consume +/// the type take a start location of the token they are looking at as a +/// parameter. This avoids updating the type on hot paths in the parser. class PreferredTypeBuilder { public: - PreferredTypeBuilder() = default; - explicit PreferredTypeBuilder(QualType Type) : Type(Type) {} + PreferredTypeBuilder(bool Enabled) : Enabled(Enabled) {} void enterCondition(Sema &S, SourceLocation Tok); void enterReturn(Sema &S, SourceLocation Tok); @@ -307,6 +306,9 @@ class PreferredTypeBuilder { /// Clients should be very careful when using this funciton, as it stores a /// function_ref, clients should make sure all calls to get() with the same /// location happen while function_ref is alive. + /// + /// The callback should also emit signature help as a side-effect, but only + /// if the completion point has been reached. void enterFunctionArgument(SourceLocation Tok, llvm::function_ref ComputeType); @@ -319,8 +321,14 @@ class PreferredTypeBuilder { /// Handles all type casts, including C-style cast, C++ casts, etc. void enterTypeCast(SourceLocation Tok, QualType CastType); + /// Get the expected type associated with this location, if any. + /// + /// If the location is a function argument, determining the expected type + /// involves considering all function overloads and the arguments so far. + /// In this case, signature help for these function overloads will be reported + /// as a side-effect (only if the completion point has been reached). QualType get(SourceLocation Tok) const { - if (Tok != ExpectedLoc) + if (!Enabled || Tok != ExpectedLoc) return QualType(); if (!Type.isNull()) return Type; @@ -330,6 +338,7 @@ class PreferredTypeBuilder { } private: + bool Enabled; /// Start position of a token for which we store expected type. SourceLocation ExpectedLoc; /// Expected type for a token starting at ExpectedLoc. @@ -2284,6 +2293,7 @@ class Sema final { const CXXScopeSpec &SS, QualType T, TagDecl *OwnedTagDecl = nullptr); + QualType getDecltypeForParenthesizedExpr(Expr *E); QualType BuildTypeofExprType(Expr *E, SourceLocation Loc); /// If AsUnevaluated is false, E is treated as though it were an evaluated /// context, such as when building a type for decltype(auto). @@ -2693,8 +2703,7 @@ class Sema final { void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc); void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc); - ExprResult ConvertParamDefaultArgument(const ParmVarDecl *Param, - Expr *DefaultArg, + ExprResult ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); @@ -4251,6 +4260,13 @@ class Sema final { void checkUnusedDeclAttributes(Declarator &D); + /// Handles semantic checking for features that are common to all attributes, + /// such as checking whether a parameter was properly specified, or the + /// correct number of arguments were passed, etc. Returns true if the + /// attribute has been diagnosed. + bool checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A); + bool checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A); + /// Determine if type T is a valid subject for a nonnull and similar /// attributes. By default, we look through references (the behavior used by /// nonnull), but if the second parameter is true, then we treat a reference @@ -5565,6 +5581,9 @@ class Sema final { ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc); + ExprResult BuildAsTypeExpr(Expr *E, QualType DestTy, + SourceLocation BuiltinLoc, + SourceLocation RParenLoc); //===---------------------------- C++ Features --------------------------===// @@ -10781,6 +10800,15 @@ class Sema final { StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective( ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); + /// Called on well-formed '\#pragma omp interop'. + StmtResult ActOnOpenMPInteropDirective(ArrayRef Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed '\#pragma omp dispatch' after parsing of the + // /associated statement. + StmtResult ActOnOpenMPDispatchDirective(ArrayRef Clauses, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); /// Checks correctness of linear modifiers. bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, @@ -10970,9 +10998,26 @@ class Sema final { /// Called on well-formed 'relaxed' clause. OMPClause *ActOnOpenMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc); + + /// Called on well-formed 'init' clause. + OMPClause *ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef PrefExprs, + bool IsTarget, bool IsTargetSync, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, + SourceLocation EndLoc); + + /// Called on well-formed 'use' clause. + OMPClause *ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, SourceLocation EndLoc); + /// Called on well-formed 'destroy' clause. - OMPClause *ActOnOpenMPDestroyClause(SourceLocation StartLoc, + OMPClause *ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, SourceLocation EndLoc); + /// Called on well-formed 'threads' clause. OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc); @@ -12217,8 +12262,14 @@ class Sema final { const VirtSpecifiers *VS = nullptr); void CodeCompleteBracketDeclarator(Scope *S); void CodeCompleteCase(Scope *S); - /// Reports signatures for a call to CodeCompleteConsumer and returns the - /// preferred type for the current argument. Returned type can be null. + /// Determines the preferred type of the current function argument, by + /// examining the signatures of all possible overloads. + /// Returns null if unknown or ambiguous, or if code completion is off. + /// + /// If the code completion point has been reached, also reports the function + /// signatures that were considered. + /// + /// FIXME: rename to GuessCallArgumentType to reduce confusion. QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef Args, SourceLocation OpenParLoc); QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 03ec8da289de..17690b901eac 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -41,7 +41,7 @@ namespace serialization { /// Version 4 of AST files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// AST files at this time. -const unsigned VERSION_MAJOR = 12; +const unsigned VERSION_MAJOR = 13; /// AST file minor version number supported by this version of /// Clang. @@ -1940,6 +1940,8 @@ enum StmtCode { STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE, STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, + STMT_OMP_INTEROP_DIRECTIVE, + STMT_OMP_DISPATCH_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, EXPR_OMP_ARRAY_SHAPING, EXPR_OMP_ITERATOR, diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 12073a38a77a..ea67d6990a8a 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -84,7 +84,7 @@ class RecordDecl; class Sema; class SourceManager; class Stmt; -struct StoredDeclsList; +class StoredDeclsList; class SwitchCase; class TemplateParameterList; class Token; diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h index 58a88f452ed9..2975d50de333 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h @@ -93,7 +93,7 @@ enum class TrackingKind { /// gathered about the tracked expression value as possible. Thorough, /// Specifies that a more moderate tracking should be used for the expression - /// value. This will essentially make sure that functions relevant to the it + /// value. This will essentially make sure that functions relevant to it /// aren't pruned, but otherwise relies on the user reading the code or /// following the arrows. Condition diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h index 062a604a7551..392bc484bf62 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h @@ -21,6 +21,7 @@ extern const char *const UnixAPI; extern const char *const CXXObjectLifecycle; extern const char *const CXXMoveSemantics; extern const char *const SecurityError; +extern const char *const UnusedCode; } // namespace categories } // namespace ento } // namespace clang diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index 9f464e82304f..f59b254094db 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -139,6 +139,12 @@ class BasicValueFactory { /// Returns the type of the APSInt used to store values of the given QualType. APSIntType getAPSIntType(QualType T) const { + // For the purposes of the analysis and constraints, we treat atomics + // as their underlying types. + if (const AtomicType *AT = T->getAs()) { + T = AT->getValueType(); + } + assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T)); return APSIntType(Ctx.getIntWidth(T), !T->isSignedIntegerOrEnumerationType()); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h index bc5d5f57cd68..4a118074463d 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h @@ -16,6 +16,8 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/Support/Allocator.h" namespace clang { @@ -24,21 +26,19 @@ namespace ento { /// A Range represents the closed range [from, to]. The caller must /// guarantee that from <= to. Note that Range is immutable, so as not /// to subvert RangeSet's immutability. -class Range : public std::pair { +class Range { public: - Range(const llvm::APSInt &from, const llvm::APSInt &to) - : std::pair(&from, &to) { - assert(from <= to); + Range(const llvm::APSInt &From, const llvm::APSInt &To) : Impl(&From, &To) { + assert(From <= To); } - Range(const llvm::APSInt &point) - : std::pair(&point, &point) {} + Range(const llvm::APSInt &Point) : Range(Point, Point) {} - bool Includes(const llvm::APSInt &v) const { - return *first <= v && v <= *second; + bool Includes(const llvm::APSInt &Point) const { + return From() <= Point && Point <= To(); } - const llvm::APSInt &From() const { return *first; } - const llvm::APSInt &To() const { return *second; } + const llvm::APSInt &From() const { return *Impl.first; } + const llvm::APSInt &To() const { return *Impl.second; } const llvm::APSInt *getConcreteValue() const { return &From() == &To() ? &From() : nullptr; } @@ -47,93 +47,264 @@ class Range : public std::pair { ID.AddPointer(&From()); ID.AddPointer(&To()); } -}; + void dump(raw_ostream &OS) const; -class RangeTrait : public llvm::ImutContainerInfo { -public: - // When comparing if one Range is less than another, we should compare - // the actual APSInt values instead of their pointers. This keeps the order - // consistent (instead of comparing by pointer values) and can potentially - // be used to speed up some of the operations in RangeSet. - static inline bool isLess(key_type_ref lhs, key_type_ref rhs) { - return *lhs.first < *rhs.first || - (!(*rhs.first < *lhs.first) && *lhs.second < *rhs.second); - } + // In order to keep non-overlapping ranges sorted, we can compare only From + // points. + bool operator<(const Range &RHS) const { return From() < RHS.From(); } + + bool operator==(const Range &RHS) const { return Impl == RHS.Impl; } + bool operator!=(const Range &RHS) const { return !operator==(RHS); } + +private: + std::pair Impl; }; -/// RangeSet contains a set of ranges. If the set is empty, then -/// there the value of a symbol is overly constrained and there are no -/// possible values for that symbol. +/// @class RangeSet is a persistent set of non-overlapping ranges. +/// +/// New RangeSet objects can be ONLY produced by RangeSet::Factory object, which +/// also supports the most common operations performed on range sets. +/// +/// Empty set corresponds to an overly constrained symbol meaning that there +/// are no possible values for that symbol. class RangeSet { - typedef llvm::ImmutableSet PrimRangeSet; - PrimRangeSet ranges; // no need to make const, since it is an - // ImmutableSet - this allows default operator= - // to work. public: - typedef PrimRangeSet::Factory Factory; - typedef PrimRangeSet::iterator iterator; - - RangeSet(PrimRangeSet RS) : ranges(RS) {} - - /// Create a new set with all ranges of this set and RS. - /// Possible intersections are not checked here. - RangeSet addRange(Factory &F, const RangeSet &RS) { - PrimRangeSet Ranges(RS.ranges); - for (const auto &range : ranges) - Ranges = F.add(Ranges, range); - return RangeSet(Ranges); - } - - iterator begin() const { return ranges.begin(); } - iterator end() const { return ranges.end(); } + class Factory; - bool isEmpty() const { return ranges.isEmpty(); } +private: + // We use llvm::SmallVector as the underlying container for the following + // reasons: + // + // * Range sets are usually very simple, 1 or 2 ranges. + // That's why llvm::ImmutableSet is not perfect. + // + // * Ranges in sets are NOT overlapping, so it is natural to keep them + // sorted for efficient operations and queries. For this reason, + // llvm::SmallSet doesn't fit the requirements, it is not sorted when it + // is a vector. + // + // * Range set operations usually a bit harder than add/remove a range. + // Complex operations might do many of those for just one range set. + // Formerly it used to be llvm::ImmutableSet, which is inefficient for our + // purposes as we want to make these operations BOTH immutable AND + // efficient. + // + // * Iteration over ranges is widespread and a more cache-friendly + // structure is preferred. + using ImplType = llvm::SmallVector; + + struct ContainerType : public ImplType, public llvm::FoldingSetNode { + void Profile(llvm::FoldingSetNodeID &ID) const { + for (const Range &It : *this) { + It.Profile(ID); + } + } + }; + // This is a non-owning pointer to an actual container. + // The memory is fully managed by the factory and is alive as long as the + // factory itself is alive. + // It is a pointer as opposed to a reference, so we can easily reassign + // RangeSet objects. + using UnderlyingType = const ContainerType *; + UnderlyingType Impl; - /// Construct a new RangeSet representing '{ [from, to] }'. - RangeSet(Factory &F, const llvm::APSInt &from, const llvm::APSInt &to) - : ranges(F.add(F.getEmptySet(), Range(from, to))) {} +public: + using const_iterator = ImplType::const_iterator; + + const_iterator begin() const { return Impl->begin(); } + const_iterator end() const { return Impl->end(); } + size_t size() const { return Impl->size(); } + + bool isEmpty() const { return Impl->empty(); } + + class Factory { + public: + Factory(BasicValueFactory &BV) : ValueFactory(BV) {} + + /// Create a new set with all ranges from both LHS and RHS. + /// Possible intersections are not checked here. + /// + /// Complexity: O(N + M) + /// where N = size(LHS), M = size(RHS) + RangeSet add(RangeSet LHS, RangeSet RHS); + /// Create a new set with all ranges from the original set plus the new one. + /// Possible intersections are not checked here. + /// + /// Complexity: O(N) + /// where N = size(Original) + RangeSet add(RangeSet Original, Range Element); + /// Create a new set with all ranges from the original set plus the point. + /// Possible intersections are not checked here. + /// + /// Complexity: O(N) + /// where N = size(Original) + RangeSet add(RangeSet Original, const llvm::APSInt &Point); + + RangeSet getEmptySet() { return &EmptySet; } + + /// Create a new set with just one range. + /// @{ + RangeSet getRangeSet(Range Origin); + RangeSet getRangeSet(const llvm::APSInt &From, const llvm::APSInt &To) { + return getRangeSet(Range(From, To)); + } + RangeSet getRangeSet(const llvm::APSInt &Origin) { + return getRangeSet(Origin, Origin); + } + /// @} + + /// Intersect the given range sets. + /// + /// Complexity: O(N + M) + /// where N = size(LHS), M = size(RHS) + RangeSet intersect(RangeSet LHS, RangeSet RHS); + /// Intersect the given set with the closed range [Lower, Upper]. + /// + /// Unlike the Range type, this range uses modular arithmetic, corresponding + /// to the common treatment of C integer overflow. Thus, if the Lower bound + /// is greater than the Upper bound, the range is taken to wrap around. This + /// is equivalent to taking the intersection with the two ranges [Min, + /// Upper] and [Lower, Max], or, alternatively, /removing/ all integers + /// between Upper and Lower. + /// + /// Complexity: O(N) + /// where N = size(What) + RangeSet intersect(RangeSet What, llvm::APSInt Lower, llvm::APSInt Upper); + /// Intersect the given range with the given point. + /// + /// The result can be either an empty set or a set containing the given + /// point depending on whether the point is in the range set. + /// + /// Complexity: O(logN) + /// where N = size(What) + RangeSet intersect(RangeSet What, llvm::APSInt Point); + + /// Delete the given point from the range set. + /// + /// Complexity: O(N) + /// where N = size(From) + RangeSet deletePoint(RangeSet From, const llvm::APSInt &Point); + /// Negate the given range set. + /// + /// Turn all [A, B] ranges to [-B, -A], when "-" is a C-like unary minus + /// operation under the values of the type. + /// + /// We also handle MIN because applying unary minus to MIN does not change + /// it. + /// Example 1: + /// char x = -128; // -128 is a MIN value in a range of 'char' + /// char y = -x; // y: -128 + /// + /// Example 2: + /// unsigned char x = 0; // 0 is a MIN value in a range of 'unsigned char' + /// unsigned char y = -x; // y: 0 + /// + /// And it makes us to separate the range + /// like [MIN, N] to [MIN, MIN] U [-N, MAX]. + /// For instance, whole range is {-128..127} and subrange is [-128,-126], + /// thus [-128,-127,-126,...] negates to [-128,...,126,127]. + /// + /// Negate restores disrupted ranges on bounds, + /// e.g. [MIN, B] => [MIN, MIN] U [-B, MAX] => [MIN, B]. + /// + /// Negate is a self-inverse function, i.e. negate(negate(R)) == R. + /// + /// Complexity: O(N) + /// where N = size(What) + RangeSet negate(RangeSet What); + + private: + /// Return a persistent version of the given container. + RangeSet makePersistent(ContainerType &&From); + /// Construct a new persistent version of the given container. + ContainerType *construct(ContainerType &&From); + + RangeSet intersect(const ContainerType &LHS, const ContainerType &RHS); + + // Many operations include producing new APSInt values and that's why + // we need this factory. + BasicValueFactory &ValueFactory; + // Allocator for all the created containers. + // Containers might own their own memory and that's why it is specific + // for the type, so it calls container destructors upon deletion. + llvm::SpecificBumpPtrAllocator Arena; + // Usually we deal with the same ranges and range sets over and over. + // Here we track all created containers and try not to repeat ourselves. + llvm::FoldingSet Cache; + static ContainerType EmptySet; + }; + + RangeSet(const RangeSet &) = default; + RangeSet &operator=(const RangeSet &) = default; + RangeSet(RangeSet &&) = default; + RangeSet &operator=(RangeSet &&) = default; + ~RangeSet() = default; + + /// Construct a new RangeSet representing '{ [From, To] }'. + RangeSet(Factory &F, const llvm::APSInt &From, const llvm::APSInt &To) + : RangeSet(F.getRangeSet(From, To)) {} /// Construct a new RangeSet representing the given point as a range. - RangeSet(Factory &F, const llvm::APSInt &point) : RangeSet(F, point, point) {} + RangeSet(Factory &F, const llvm::APSInt &Point) + : RangeSet(F.getRangeSet(Point)) {} + + static void Profile(llvm::FoldingSetNodeID &ID, const RangeSet &RS) { + ID.AddPointer(RS.Impl); + } /// Profile - Generates a hash profile of this RangeSet for use /// by FoldingSet. - void Profile(llvm::FoldingSetNodeID &ID) const { ranges.Profile(ID); } + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, *this); } /// getConcreteValue - If a symbol is contrained to equal a specific integer /// constant then this method returns that value. Otherwise, it returns /// NULL. const llvm::APSInt *getConcreteValue() const { - return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : nullptr; + return Impl->size() == 1 ? begin()->getConcreteValue() : nullptr; } - /// Get a minimal value covered by the ranges in the set + /// Get the minimal value covered by the ranges in the set. + /// + /// Complexity: O(1) const llvm::APSInt &getMinValue() const; - /// Get a maximal value covered by the ranges in the set + /// Get the maximal value covered by the ranges in the set. + /// + /// Complexity: O(1) const llvm::APSInt &getMaxValue() const; -private: - void IntersectInRange(BasicValueFactory &BV, Factory &F, - const llvm::APSInt &Lower, const llvm::APSInt &Upper, - PrimRangeSet &newRanges, PrimRangeSet::iterator &i, - PrimRangeSet::iterator &e) const; + /// Test whether the given point is contained by any of the ranges. + /// + /// Complexity: O(logN) + /// where N = size(this) + bool contains(llvm::APSInt Point) const { return containsImpl(Point); } + + void dump(raw_ostream &OS) const; + + bool operator==(const RangeSet &Other) const { return *Impl == *Other.Impl; } + bool operator!=(const RangeSet &Other) const { return !(*this == Other); } +private: + /* implicit */ RangeSet(ContainerType *RawContainer) : Impl(RawContainer) {} + /* implicit */ RangeSet(UnderlyingType Ptr) : Impl(Ptr) {} + + /// Pin given points to the type represented by the current range set. + /// + /// This makes parameter points to be in-out parameters. + /// In order to maintain consistent types across all of the ranges in the set + /// and to keep all the operations to compare ONLY points of the same type, we + /// need to pin every point before any operation. + /// + /// @Returns true if the given points can be converted to the target type + /// without changing the values (i.e. trivially) and false otherwise. + /// @{ bool pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const; + bool pin(llvm::APSInt &Point) const; + /// @} -public: - RangeSet Intersect(BasicValueFactory &BV, Factory &F, llvm::APSInt Lower, - llvm::APSInt Upper) const; - RangeSet Intersect(BasicValueFactory &BV, Factory &F, - const RangeSet &Other) const; - RangeSet Negate(BasicValueFactory &BV, Factory &F) const; - RangeSet Delete(BasicValueFactory &BV, Factory &F, - const llvm::APSInt &Point) const; - - void print(raw_ostream &os) const; - - bool operator==(const RangeSet &other) const { - return ranges == other.ranges; - } + // This version of this function modifies its arguments (pins it). + bool containsImpl(llvm::APSInt &Point) const; + + friend class Factory; }; using ConstraintMap = llvm::ImmutableMap; diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index 1c106ed4b765..b4fa27f531e3 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -22,19 +22,10 @@ namespace dependencies{ /// The full dependencies and module graph for a specific input. struct FullDependencies { - /// The name of the C++20 module this translation unit exports. This may - /// include `:` for C++20 module partitons. + /// The identifier of the C++20 module this translation unit exports. /// - /// If the translation unit is not a module then this will be empty. - std::string ExportedModuleName; - - /// The context hash represents the set of compiler options that may make one - /// version of a module incompatible with another. This includes things like - /// language mode, predefined macros, header search paths, etc... - /// - /// Modules with the same name but a different \c ContextHash should be - /// treated as separate modules for the purpose of a build. - std::string ContextHash; + /// If the translation unit is not a module then \c ID.ModuleName is empty. + ModuleID ID; /// A collection of absolute paths to files that this translation unit /// directly depends on, not including transitive dependencies. @@ -45,7 +36,7 @@ struct FullDependencies { /// /// This may include modules with a different context hash when it can be /// determined that the differences are benign for this compilation. - std::vector ClangModuleDeps; + std::vector ClangModuleDeps; /// A partial addtional set of command line arguments that can be used to /// build this translation unit. @@ -65,8 +56,8 @@ struct FullDependencies { /// transitive set of dependencies for this /// compilation. std::vector getAdditionalCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const; + std::function LookupPCMPath, + std::function LookupModuleDeps) const; }; struct FullDependenciesResult { diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h index c490bb38c167..87bb1b86c279 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -28,16 +28,9 @@ namespace dependencies { class DependencyConsumer; -/// This is used to refer to a specific module. -/// -/// See \c ModuleDeps for details about what these members mean. -struct ClangModuleDep { - std::string ModuleName; - std::string ContextHash; -}; - -struct ModuleDeps { - /// The name of the module. This may include `:` for C++20 module partitons, +/// This is used to identify a specific module. +struct ModuleID { + /// The name of the module. This may include `:` for C++20 module partitions, /// or a header-name for C++20 header units. std::string ModuleName; @@ -48,6 +41,11 @@ struct ModuleDeps { /// Modules with the same name but a different \c ContextHash should be /// treated as separate modules for the purpose of a build. std::string ContextHash; +}; + +struct ModuleDeps { + /// The identifier of the module. + ModuleID ID; /// The path to the modulemap file which defines this module. /// @@ -62,12 +60,12 @@ struct ModuleDeps { /// on, not including transitive dependencies. llvm::StringSet<> FileDeps; - /// A list of modules this module directly depends on, not including - /// transitive dependencies. + /// A list of module identifiers this module directly depends on, not + /// including transitive dependencies. /// /// This may include modules with a different context hash when it can be /// determined that the differences are benign for this compilation. - std::vector ClangModuleDeps; + std::vector ClangModuleDeps; /// A partial command line that can be used to build this module. /// @@ -89,8 +87,8 @@ struct ModuleDeps { /// transitive set of dependencies for this /// compilation. std::vector getFullCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const; + std::function LookupPCMPath, + std::function LookupModuleDeps) const; }; namespace detail { @@ -98,14 +96,18 @@ namespace detail { /// modules in \c Modules transitively, along with other needed arguments to /// use explicitly built modules. void appendCommonModuleArguments( - llvm::ArrayRef Modules, - std::function LookupPCMPath, - std::function LookupModuleDeps, + llvm::ArrayRef Modules, + std::function LookupPCMPath, + std::function LookupModuleDeps, std::vector &Result); } // namespace detail class ModuleDepCollector; +/// Callback that records textual includes and direct modular includes/imports +/// during preprocessing. At the end of the main file, it also collects +/// transitive modular dependencies and passes everything to the +/// \c DependencyConsumer of the parent \c ModuleDepCollector. class ModuleDepCollectorPP final : public PPCallbacks { public: ModuleDepCollectorPP(CompilerInstance &I, ModuleDepCollector &MDC) @@ -126,11 +128,18 @@ class ModuleDepCollectorPP final : public PPCallbacks { void EndOfMainFile() override; private: + /// The compiler instance for the current translation unit. CompilerInstance &Instance; + /// The parent dependency collector. ModuleDepCollector &MDC; - llvm::DenseSet DirectDeps; + /// Working set of direct modular dependencies. + llvm::DenseSet DirectModularDeps; void handleImport(const Module *Imported); + + /// Traverses the previously collected direct modular dependencies to discover + /// transitive modular dependencies and fills the parent \c ModuleDepCollector + /// with both. void handleTopLevelModule(const Module *M); void addAllSubmoduleDeps(const Module *M, ModuleDeps &MD, llvm::DenseSet &AddedModules); @@ -138,6 +147,8 @@ class ModuleDepCollectorPP final : public PPCallbacks { llvm::DenseSet &AddedModules); }; +/// Collects modular and non-modular dependencies of the main file by attaching +/// \c ModuleDepCollectorPP to the preprocessor. class ModuleDepCollector final : public DependencyCollector { public: ModuleDepCollector(std::unique_ptr Opts, @@ -149,12 +160,20 @@ class ModuleDepCollector final : public DependencyCollector { private: friend ModuleDepCollectorPP; + /// The compiler instance for the current translation unit. CompilerInstance &Instance; + /// The consumer of collected dependency information. DependencyConsumer &Consumer; + /// Path to the main source file. std::string MainFile; + /// The module hash identifying the compilation conditions. std::string ContextHash; - std::vector MainDeps; - std::unordered_map Deps; + /// Non-modular file dependencies. This includes the main source file and + /// textually included header files. + std::vector FileDeps; + /// Direct and transitive modular dependencies of the main source file. + std::unordered_map ModularDeps; + /// Options that control the dependency output generation. std::unique_ptr Opts; }; diff --git a/clang/include/clang/Tooling/NodeIntrospection.h b/clang/include/clang/Tooling/NodeIntrospection.h new file mode 100644 index 000000000000..3b40e68df24e --- /dev/null +++ b/clang/include/clang/Tooling/NodeIntrospection.h @@ -0,0 +1,87 @@ +//===- NodeIntrospection.h ------------------------------------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the implementation of the NodeIntrospection. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_NODEINTROSPECTION_H +#define LLVM_CLANG_TOOLING_NODEINTROSPECTION_H + +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/DeclarationName.h" + +#include +#include + +namespace clang { + +class Stmt; +class Decl; + +namespace tooling { + +class LocationCall { +public: + enum LocationCallFlags { NoFlags, ReturnsPointer, IsCast }; + LocationCall(std::shared_ptr on, std::string name, + LocationCallFlags flags = NoFlags) + : m_on(on), m_name(name), m_flags(flags) {} + LocationCall(std::shared_ptr on, std::string name, + std::vector const &args, + LocationCallFlags flags = NoFlags) + : m_on(on), m_name(name), m_flags(flags) {} + + LocationCall *on() const { return m_on.get(); } + StringRef name() const { return m_name; } + std::vector const &args() const { return m_args; } + bool returnsPointer() const { return m_flags & ReturnsPointer; } + bool isCast() const { return m_flags & IsCast; } + +private: + std::shared_ptr m_on; + std::string m_name; + std::vector m_args; + LocationCallFlags m_flags; +}; + +class LocationCallFormatterCpp { +public: + static std::string format(LocationCall *Call); +}; + +namespace internal { +struct RangeLessThan { + bool operator()( + std::pair> const &LHS, + std::pair> const &RHS) const; +}; +} // namespace internal + +template >> +using UniqueMultiMap = std::set, Comp>; + +using SourceLocationMap = + UniqueMultiMap>; +using SourceRangeMap = + UniqueMultiMap, + internal::RangeLessThan>; + +struct NodeLocationAccessors { + SourceLocationMap LocationAccessors; + SourceRangeMap RangeAccessors; +}; + +namespace NodeIntrospection { +NodeLocationAccessors GetLocations(clang::Stmt const *Object); +NodeLocationAccessors GetLocations(clang::Decl const *Object); +NodeLocationAccessors GetLocations(clang::DynTypedNode const &Node); +} // namespace NodeIntrospection +} // namespace tooling +} // namespace clang +#endif diff --git a/clang/include/clang/Tooling/Syntax/Tokens.h b/clang/include/clang/Tooling/Syntax/Tokens.h index 98320bd54d6f..e4bc1553c2d6 100644 --- a/clang/include/clang/Tooling/Syntax/Tokens.h +++ b/clang/include/clang/Tooling/Syntax/Tokens.h @@ -34,6 +34,7 @@ #include "clang/Basic/TokenKinds.h" #include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" @@ -192,8 +193,13 @@ class TokenBuffer { return ExpandedTokens; } + /// Builds a cache to make future calls to expandedToken(SourceRange) faster. + /// Creates an index only once. Further calls to it will be no-op. + void indexExpandedTokens(); + /// Returns the subrange of expandedTokens() corresponding to the closed /// token range R. + /// Consider calling indexExpandedTokens() before for faster lookups. llvm::ArrayRef expandedTokens(SourceRange R) const; /// Returns the subrange of spelled tokens corresponding to AST node spanning @@ -366,6 +372,8 @@ class TokenBuffer { /// same stream as 'clang -E' (excluding the preprocessor directives like /// #file, etc.). std::vector ExpandedTokens; + // Index of ExpandedTokens for faster lookups by SourceLocation. + llvm::DenseMap ExpandedTokIndex; llvm::DenseMap Files; // The value is never null, pointer instead of reference to avoid disabling // implicit assignment operator. diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp index a4120120a01c..75100fde59b8 100644 --- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp +++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp @@ -551,7 +551,9 @@ struct Module { llvm::Optional SwiftInferImportAsMember = {llvm::None}; +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void dump() /*const*/; +#endif }; } // namespace @@ -571,10 +573,12 @@ template <> struct MappingTraits { } // namespace yaml } // namespace llvm -void Module::dump() { +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void Module::dump() { llvm::yaml::Output OS(llvm::errs()); OS << *this; } +#endif namespace { bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag, diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 68a51a49c718..c8069b51567c 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -613,7 +613,7 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, continue; HasAtleastOneRequiredProperty = true; DeclContext::lookup_result R = IDecl->lookup(Property->getDeclName()); - if (R.size() == 0) { + if (R.empty()) { // Relax the rule and look into class's implementation for a synthesize // or dynamic declaration. Class is implementing a property coming from // another protocol. This still makes the target protocol as conforming. @@ -621,14 +621,12 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, Property->getDeclName().getAsIdentifierInfo(), Property->getQueryKind())) return false; - } - else if (ObjCPropertyDecl *ClassProperty = dyn_cast(R[0])) { - if ((ClassProperty->getPropertyAttributes() - != Property->getPropertyAttributes()) || - !Ctx.hasSameType(ClassProperty->getType(), Property->getType())) - return false; - } - else + } else if (auto *ClassProperty = R.find_first()) { + if ((ClassProperty->getPropertyAttributes() != + Property->getPropertyAttributes()) || + !Ctx.hasSameType(ClassProperty->getType(), Property->getType())) + return false; + } else return false; } @@ -645,12 +643,12 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, if (MD->getImplementationControl() == ObjCMethodDecl::Optional) continue; DeclContext::lookup_result R = ImpDecl->lookup(MD->getDeclName()); - if (R.size() == 0) + if (R.empty()) return false; bool match = false; HasAtleastOneRequiredMethod = true; - for (unsigned I = 0, N = R.size(); I != N; ++I) - if (ObjCMethodDecl *ImpMD = dyn_cast(R[0])) + for (NamedDecl *ND : R) + if (ObjCMethodDecl *ImpMD = dyn_cast(ND)) if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) { match = true; break; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 2e3e381d9d67..f53c0a81c5b6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1783,6 +1783,13 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { } } + // Some targets have hard limitation on the maximum requestable alignment in + // aligned attribute for static variables. + const unsigned MaxAlignedAttr = getTargetInfo().getMaxAlignedAttribute(); + const auto *VD = dyn_cast(D); + if (MaxAlignedAttr && VD && VD->getStorageClass() == SC_Static) + Align = std::min(Align, MaxAlignedAttr); + return toCharUnitsFromBits(Align); } @@ -10895,6 +10902,9 @@ void ASTContext::forEachMultiversionedFunctionVersion( assert(FD->isMultiVersion() && "Only valid for multiversioned functions"); llvm::SmallDenseSet SeenDecls; FD = FD->getMostRecentDecl(); + // FIXME: The order of traversal here matters and depends on the order of + // lookup results, which happens to be (mostly) oldest-to-newest, but we + // shouldn't rely on that. for (auto *CurDecl : FD->getDeclContext()->getRedeclContext()->lookup(FD->getDeclName())) { FunctionDecl *CurFD = CurDecl->getAsFunction()->getMostRecentDecl(); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index f4dfc54b36cb..dd11e3662148 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -358,6 +358,8 @@ namespace clang { ExpectedType VisitDecltypeType(const DecltypeType *T); ExpectedType VisitUnaryTransformType(const UnaryTransformType *T); ExpectedType VisitAutoType(const AutoType *T); + ExpectedType VisitDeducedTemplateSpecializationType( + const DeducedTemplateSpecializationType *T); ExpectedType VisitInjectedClassNameType(const InjectedClassNameType *T); // FIXME: DependentDecltypeType ExpectedType VisitRecordType(const RecordType *T); @@ -574,6 +576,7 @@ namespace clang { // Importing expressions ExpectedStmt VisitExpr(Expr *E); + ExpectedStmt VisitSourceLocExpr(SourceLocExpr *E); ExpectedStmt VisitVAArgExpr(VAArgExpr *E); ExpectedStmt VisitChooseExpr(ChooseExpr *E); ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E); @@ -1375,6 +1378,20 @@ ExpectedType ASTNodeImporter::VisitAutoType(const AutoType *T) { ToTemplateArgs); } +ExpectedType ASTNodeImporter::VisitDeducedTemplateSpecializationType( + const DeducedTemplateSpecializationType *T) { + // FIXME: Make sure that the "to" context supports C++17! + Expected ToTemplateNameOrErr = import(T->getTemplateName()); + if (!ToTemplateNameOrErr) + return ToTemplateNameOrErr.takeError(); + ExpectedType ToDeducedTypeOrErr = import(T->getDeducedType()); + if (!ToDeducedTypeOrErr) + return ToDeducedTypeOrErr.takeError(); + + return Importer.getToContext().getDeducedTemplateSpecializationType( + *ToTemplateNameOrErr, *ToDeducedTypeOrErr, T->isDependentType()); +} + ExpectedType ASTNodeImporter::VisitInjectedClassNameType( const InjectedClassNameType *T) { Expected ToDeclOrErr = import(T->getDecl()); @@ -2715,7 +2732,20 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { D2->setBraceRange(ToBraceRange); D2->setAccess(D->getAccess()); D2->setLexicalDeclContext(LexicalDC); - LexicalDC->addDeclInternal(D2); + addDeclToContexts(D, D2); + + if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) { + TemplateSpecializationKind SK = MemberInfo->getTemplateSpecializationKind(); + EnumDecl *FromInst = D->getInstantiatedFromMemberEnum(); + if (Expected ToInstOrErr = import(FromInst)) + D2->setInstantiationOfMemberEnum(*ToInstOrErr, SK); + else + return ToInstOrErr.takeError(); + if (ExpectedSLoc POIOrErr = import(MemberInfo->getPointOfInstantiation())) + D2->getMemberSpecializationInfo()->setPointOfInstantiation(*POIOrErr); + else + return POIOrErr.takeError(); + } // Import the definition if (D->isCompleteDefinition()) @@ -3631,6 +3661,10 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { auto ToInitializer = importChecked(Err, D->getInClassInitializer()); if (Err) return std::move(Err); + const Type *ToCapturedVLAType = nullptr; + if (Error Err = Importer.importInto( + ToCapturedVLAType, cast_or_null(D->getCapturedVLAType()))) + return std::move(Err); FieldDecl *ToField; if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC, @@ -3644,6 +3678,8 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { if (ToInitializer) ToField->setInClassInitializer(ToInitializer); ToField->setImplicit(D->isImplicit()); + if (ToCapturedVLAType) + ToField->setCapturedVLAType(cast(ToCapturedVLAType)); LexicalDC->addDeclInternal(ToField); return ToField; } @@ -4018,6 +4054,7 @@ ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) { D->getStorageClass())) return ToVar; + ToVar->setTSCSpec(D->getTSCSpec()); ToVar->setQualifierInfo(ToQualifierLoc); ToVar->setAccess(D->getAccess()); ToVar->setLexicalDeclContext(LexicalDC); @@ -5064,6 +5101,11 @@ ExpectedDecl ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { auto FoundDecls = Importer.findDeclsInToCtx(DC, Name); for (auto *FoundDecl : FoundDecls) { if (auto *FoundProp = dyn_cast(FoundDecl)) { + // Instance and class properties can share the same name but are different + // declarations. + if (FoundProp->isInstanceProperty() != D->isInstanceProperty()) + continue; + // Check property types. if (!Importer.IsStructurallyEquivalent(D->getType(), FoundProp->getType())) { @@ -6482,6 +6524,21 @@ ExpectedStmt ASTNodeImporter::VisitExpr(Expr *E) { return make_error(ImportError::UnsupportedConstruct); } +ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) { + Error Err = Error::success(); + auto BLoc = importChecked(Err, E->getBeginLoc()); + auto RParenLoc = importChecked(Err, E->getEndLoc()); + if (Err) + return std::move(Err); + auto ParentContextOrErr = Importer.ImportContext(E->getParentContext()); + if (!ParentContextOrErr) + return ParentContextOrErr.takeError(); + + return new (Importer.getToContext()) + SourceLocExpr(Importer.getToContext(), E->getIdentKind(), BLoc, RParenLoc, + *ParentContextOrErr); +} + ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) { Error Err = Error::success(); @@ -8151,28 +8208,37 @@ ASTImporter::Import(ExprWithCleanups::CleanupObject From) { return make_error(ImportError::UnsupportedConstruct); } -Expected ASTImporter::Import(QualType FromT) { - if (FromT.isNull()) - return QualType{}; - - const Type *FromTy = FromT.getTypePtr(); +Expected ASTImporter::Import(const Type *FromT) { + if (!FromT) + return FromT; // Check whether we've already imported this type. - llvm::DenseMap::iterator Pos - = ImportedTypes.find(FromTy); + llvm::DenseMap::iterator Pos = + ImportedTypes.find(FromT); if (Pos != ImportedTypes.end()) - return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers()); + return Pos->second; // Import the type ASTNodeImporter Importer(*this); - ExpectedType ToTOrErr = Importer.Visit(FromTy); + ExpectedType ToTOrErr = Importer.Visit(FromT); if (!ToTOrErr) return ToTOrErr.takeError(); // Record the imported type. - ImportedTypes[FromTy] = (*ToTOrErr).getTypePtr(); + ImportedTypes[FromT] = ToTOrErr->getTypePtr(); + + return ToTOrErr->getTypePtr(); +} + +Expected ASTImporter::Import(QualType FromT) { + if (FromT.isNull()) + return QualType{}; + + Expected ToTyOrErr = Import(FromT.getTypePtr()); + if (!ToTyOrErr) + return ToTyOrErr.takeError(); - return ToContext.getQualifiedType(*ToTOrErr, FromT.getLocalQualifiers()); + return ToContext.getQualifiedType(*ToTyOrErr, FromT.getLocalQualifiers()); } Expected ASTImporter::Import(TypeSourceInfo *FromTSI) { diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp index c87bcf31d120..9027fa7a7515 100644 --- a/clang/lib/AST/CXXInheritance.cpp +++ b/clang/lib/AST/CXXInheritance.cpp @@ -386,9 +386,9 @@ static bool isOrdinaryMember(const NamedDecl *ND) { static bool findOrdinaryMember(const CXXRecordDecl *RD, CXXBasePath &Path, DeclarationName Name) { - Path.Decls = RD->lookup(Name); - for (NamedDecl *ND : Path.Decls) - if (isOrdinaryMember(ND)) + Path.Decls = RD->lookup(Name).begin(); + for (DeclContext::lookup_iterator I = Path.Decls, E = I.end(); I != E; ++I) + if (isOrdinaryMember(*I)) return true; return false; @@ -453,9 +453,10 @@ std::vector CXXRecordDecl::lookupDependentName( }, Paths, /*LookupInDependent=*/true)) return Results; - for (const NamedDecl *ND : Paths.front().Decls) { - if (isOrdinaryMember(ND) && Filter(ND)) - Results.push_back(ND); + for (DeclContext::lookup_iterator I = Paths.front().Decls, E = I.end(); + I != E; ++I) { + if (isOrdinaryMember(*I) && Filter(*I)) + Results.push_back(*I); } return Results; } diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 8c986df3e175..fcda07dab604 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1487,10 +1487,13 @@ LinkageInfo LinkageComputer::getLVForDecl(const NamedDecl *D, } LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) { - return getLVForDecl(D, - LVComputationKind(usesTypeVisibility(D) - ? NamedDecl::VisibilityForType - : NamedDecl::VisibilityForValue)); + NamedDecl::ExplicitVisibilityKind EK = usesTypeVisibility(D) + ? NamedDecl::VisibilityForType + : NamedDecl::VisibilityForValue; + LVComputationKind CK(EK); + return getLVForDecl(D, D->getASTContext().getLangOpts().IgnoreXCOFFVisibility + ? CK.forLinkageOnly() + : CK); } Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const { @@ -1609,8 +1612,7 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS, // Suppress inline namespace if it doesn't make the result ambiguous. if (P.SuppressInlineNamespace && Ctx->isInlineNamespace() && NameInScope && - Ctx->lookup(NameInScope).size() == - Ctx->getParent()->lookup(NameInScope).size()) + cast(Ctx)->isRedundantInlineQualifierFor(NameInScope)) continue; // Skip non-named contexts such as linkage specifications and ExportDecls. diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index c26d6d1a42ea..6d438cf05590 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1394,39 +1394,7 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, DC->reconcileExternalVisibleStorage(); StoredDeclsList &List = (*Map)[Name]; - - // Clear out any old external visible declarations, to avoid quadratic - // performance in the redeclaration checks below. - List.removeExternalDecls(); - - if (!List.isNull()) { - // We have both existing declarations and new declarations for this name. - // Some of the declarations may simply replace existing ones. Handle those - // first. - llvm::SmallVector Skip; - for (unsigned I = 0, N = Decls.size(); I != N; ++I) - if (List.HandleRedeclaration(Decls[I], /*IsKnownNewer*/false)) - Skip.push_back(I); - Skip.push_back(Decls.size()); - - // Add in any new declarations. - unsigned SkipPos = 0; - for (unsigned I = 0, N = Decls.size(); I != N; ++I) { - if (I == Skip[SkipPos]) - ++SkipPos; - else - List.AddSubsequentDecl(Decls[I]); - } - } else { - // Convert the array to a StoredDeclsList. - for (auto *D : Decls) { - if (List.isNull()) - List.setOnlyValue(D); - else - List.AddSubsequentDecl(D); - } - } - + List.replaceExternalDecls(Decls); return List.getLookupResult(); } @@ -1538,10 +1506,7 @@ void DeclContext::removeDecl(Decl *D) { if (Map) { StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); assert(Pos != Map->end() && "no lookup entry for decl"); - // Remove the decl only if it is contained. - StoredDeclsList::DeclsTy *Vec = Pos->second.getAsVector(); - if ((Vec && is_contained(*Vec, ND)) || Pos->second.getAsDecl() == ND) - Pos->second.remove(ND); + Pos->second.remove(ND); } } while (DC->isTransparentContext() && (DC = DC->getParent())); } @@ -1658,8 +1623,6 @@ void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) { } } -NamedDecl *const DeclContextLookupResult::SingleElementDummyList = nullptr; - DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) const { assert(getDeclKind() != Decl::LinkageSpec && @@ -1935,23 +1898,11 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { // In this case, we never try to replace an existing declaration; we'll // handle that when we finalize the list of declarations for this name. DeclNameEntries.setHasExternalDecls(); - DeclNameEntries.AddSubsequentDecl(D); - return; - } - - if (DeclNameEntries.isNull()) { - DeclNameEntries.setOnlyValue(D); - return; - } - - if (DeclNameEntries.HandleRedeclaration(D, /*IsKnownNewer*/!Internal)) { - // This declaration has replaced an existing one for which - // declarationReplaces returns true. + DeclNameEntries.prependDeclNoReplace(D); return; } - // Put this declaration into the appropriate slot. - DeclNameEntries.AddSubsequentDecl(D); + DeclNameEntries.addOrReplaceDecl(D); } UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index ae7131eae01d..624b1bfde4e6 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6712,9 +6712,12 @@ bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E) { if (Pointer.Designator.Invalid) return false; - // Deleting a null pointer has no effect. - if (Pointer.isNullPointer()) + // Deleting a null pointer would have no effect, but it's not permitted by + // std::allocator::deallocate's contract. + if (Pointer.isNullPointer()) { + Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_deallocate_null); return true; + } if (!CheckDeleteKind(Info, E, Pointer, DynAlloc::StdAllocator)) return false; @@ -12469,25 +12472,6 @@ void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) { } namespace { -/// Used when we determine that we should fail, but can keep evaluating prior to -/// noting that we had a failure. -class DelayedNoteFailureRAII { - EvalInfo &Info; - bool NoteFailure; - -public: - DelayedNoteFailureRAII(EvalInfo &Info, bool NoteFailure = true) - : Info(Info), NoteFailure(NoteFailure) {} - ~DelayedNoteFailureRAII() { - if (NoteFailure) { - bool ContinueAfterFailure = Info.noteFailure(); - (void)ContinueAfterFailure; - assert(ContinueAfterFailure && - "Shouldn't have kept evaluating on failure."); - } - } -}; - enum class CmpResult { Unequal, Less, @@ -12855,12 +12839,14 @@ bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) { } bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { - // We don't call noteFailure immediately because the assignment happens after - // we evaluate LHS and RHS. - if (!Info.keepEvaluatingAfterFailure() && E->isAssignmentOp()) - return Error(E); + // We don't support assignment in C. C++ assignments don't get here because + // assignment is an lvalue in C++. + if (E->isAssignmentOp()) { + Error(E); + if (!Info.noteFailure()) + return false; + } - DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->isAssignmentOp()); if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E)) return DataRecursiveIntBinOpEvaluator(*this, Result).Traverse(E); diff --git a/clang/lib/AST/ExternalASTMerger.cpp b/clang/lib/AST/ExternalASTMerger.cpp index 88bbe90a4e90..c7789b707b21 100644 --- a/clang/lib/AST/ExternalASTMerger.cpp +++ b/clang/lib/AST/ExternalASTMerger.cpp @@ -64,24 +64,24 @@ LookupSameContext(Source SourceTU, const DeclContext *DC, Source SourceName = *SourceNameOrErr; DeclContext::lookup_result SearchResult = SourceParentDC.get()->lookup(SourceName.get()); - size_t SearchResultSize = SearchResult.size(); - if (SearchResultSize == 0 || SearchResultSize > 1) { - // There are two cases here. First, we might not find the name. - // We might also find multiple copies, in which case we have no - // guarantee that the one we wanted is the one we pick. (E.g., - // if we have two specializations of the same template it is - // very hard to determine which is the one you want.) - // - // The Origins map fixes this problem by allowing the origin to be - // explicitly recorded, so we trigger that recording by returning - // nothing (rather than a possibly-inaccurate guess) here. - return nullptr; - } else { - NamedDecl *SearchResultDecl = SearchResult[0]; + + // There are two cases here. First, we might not find the name. + // We might also find multiple copies, in which case we have no + // guarantee that the one we wanted is the one we pick. (E.g., + // if we have two specializations of the same template it is + // very hard to determine which is the one you want.) + // + // The Origins map fixes this problem by allowing the origin to be + // explicitly recorded, so we trigger that recording by returning + // nothing (rather than a possibly-inaccurate guess) here. + if (SearchResult.isSingleResult()) { + NamedDecl *SearchResultDecl = SearchResult.front(); if (isa(SearchResultDecl) && SearchResultDecl->getKind() == DC->getDeclKind()) return cast(SearchResultDecl)->getPrimaryContext(); return nullptr; // This type of lookup is unsupported + } else { + return nullptr; } } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 885d9e28ee69..3e6e29207f08 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -628,21 +628,24 @@ static bool isInternalLinkageDecl(const NamedDecl *ND) { return false; } -// Check if this Decl needs a unique internal linkage name. +// Check if this Function Decl needs a unique internal linkage name. bool ItaniumMangleContextImpl::isUniqueInternalLinkageDecl( const NamedDecl *ND) { if (!NeedsUniqueInternalLinkageNames || !ND) return false; + const auto *FD = dyn_cast(ND); + if (!FD) + return false; + // For C functions without prototypes, return false as their // names should not be mangled. - if (auto *FD = dyn_cast(ND)) { - if (!FD->getType()->getAs()) - return false; - } + if (!FD->hasPrototype()) + return false; if (isInternalLinkageDecl(ND)) return true; + return false; } diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index e2da71b211a4..254b42606408 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1513,6 +1513,27 @@ OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C, return new (Mem) OMPAffinityClause(N); } +OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar, + ArrayRef PrefExprs, bool IsTarget, + bool IsTargetSync, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, + SourceLocation EndLoc) { + + void *Mem = C.Allocate(totalSizeToAlloc(PrefExprs.size() + 1)); + auto *Clause = + new (Mem) OMPInitClause(IsTarget, IsTargetSync, StartLoc, LParenLoc, + VarLoc, EndLoc, PrefExprs.size() + 1); + Clause->setInteropVar(InteropVar); + llvm::copy(PrefExprs, Clause->getTrailingObjects() + 1); + return Clause; +} + +OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) { + void *Mem = C.Allocate(totalSizeToAlloc(N)); + return new (Mem) OMPInitClause(N); +} + //===----------------------------------------------------------------------===// // OpenMP clauses printing methods //===----------------------------------------------------------------------===// @@ -1755,8 +1776,44 @@ void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) { OS << ")"; } -void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *) { +void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) { + OS << "init("; + bool First = true; + for (const Expr *E : Node->prefs()) { + if (First) + OS << "prefer_type("; + else + OS << ","; + E->printPretty(OS, nullptr, Policy); + First = false; + } + if (!First) + OS << "), "; + if (Node->getIsTarget()) + OS << "target"; + if (Node->getIsTargetSync()) { + if (Node->getIsTarget()) + OS << ", "; + OS << "targetsync"; + } + OS << " : "; + Node->getInteropVar()->printPretty(OS, nullptr, Policy); + OS << ")"; +} + +void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) { + OS << "use("; + Node->getInteropVar()->printPretty(OS, nullptr, Policy); + OS << ")"; +} + +void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) { OS << "destroy"; + if (Expr *E = Node->getInteropVar()) { + OS << "("; + E->printPretty(OS, nullptr, Policy); + OS << ")"; + } } template diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 95d69fa5b11a..eb9bfc20342f 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -1627,12 +1627,17 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // Some such targets do honor it on zero-width bitfields. if (FieldSize == 0 && Context.getTargetInfo().useZeroLengthBitfieldAlignment()) { - // The alignment to round up to is the max of the field's natural - // alignment and a target-specific fixed value (sometimes zero). - unsigned ZeroLengthBitfieldBoundary = - Context.getTargetInfo().getZeroLengthBitfieldBoundary(); - FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary); - + // Some targets don't honor leading zero-width bitfield. + if (!IsUnion && FieldOffset == 0 && + !Context.getTargetInfo().useLeadingZeroLengthBitfield()) + FieldAlign = 1; + else { + // The alignment to round up to is the max of the field's natural + // alignment and a target-specific fixed value (sometimes zero). + unsigned ZeroLengthBitfieldBoundary = + Context.getTargetInfo().getZeroLengthBitfieldBoundary(); + FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary); + } // If that doesn't apply, just ignore the field alignment. } else { FieldAlign = 1; diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index 5a6b31bae624..7dc43ea92450 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -1944,3 +1944,36 @@ OMPTargetTeamsDistributeSimdDirective::CreateEmpty(const ASTContext &C, numLoopChildren(CollapsedNum, OMPD_target_teams_distribute_simd), CollapsedNum); } + +OMPInteropDirective * +OMPInteropDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses) { + return createDirective( + C, Clauses, /*AssociatedStmt=*/nullptr, /*NumChildren=*/0, StartLoc, + EndLoc); +} + +OMPInteropDirective *OMPInteropDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + EmptyShell) { + return createEmptyDirective(C, NumClauses); +} + +OMPDispatchDirective *OMPDispatchDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef Clauses, Stmt *AssociatedStmt, + SourceLocation TargetCallLoc) { + auto *Dir = createDirective( + C, Clauses, AssociatedStmt, /*NumChildren=*/0, StartLoc, EndLoc); + Dir->setTargetCallLoc(TargetCallLoc); + return Dir; +} + +OMPDispatchDirective *OMPDispatchDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + EmptyShell) { + return createEmptyDirective(C, NumClauses, + /*HasAssociatedStmt=*/true, + /*NumChildren=*/0); +} diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 82071f5d7aaa..5993268971f8 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -962,6 +962,16 @@ void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective( PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) { + Indent() << "#pragma omp interop"; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) { + Indent() << "#pragma omp dispatch"; + PrintOMPExecutableDirective(Node); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// @@ -1165,6 +1175,10 @@ void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { case BuiltinType::ULong: OS << "UL"; break; case BuiltinType::LongLong: OS << "LL"; break; case BuiltinType::ULongLong: OS << "ULL"; break; + case BuiltinType::Int128: + break; // no suffix. + case BuiltinType::UInt128: + break; // no suffix. } } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 761d027b3378..fa3ab3ce977a 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -543,7 +543,19 @@ void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {} void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {} -void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *) {} +void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause *C) { + VisitOMPClauseList(C); +} + +void OMPClauseProfiler::VisitOMPUseClause(const OMPUseClause *C) { + if (C->getInteropVar()) + Profiler->VisitStmt(C->getInteropVar()); +} + +void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *C) { + if (C->getInteropVar()) + Profiler->VisitStmt(C->getInteropVar()); +} template void OMPClauseProfiler::VisitOMPClauseList(T *Node) { @@ -1128,6 +1140,14 @@ void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective( VisitOMPLoopDirective(S); } +void StmtProfiler::VisitOMPInteropDirective(const OMPInteropDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPDispatchDirective(const OMPDispatchDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitExpr(const Expr *S) { VisitStmt(S); } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index e158fe0e28e4..611c30d9c767 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2086,8 +2086,9 @@ bool Type::isUnsignedIntegerOrEnumerationType() const { bool Type::hasUnsignedIntegerRepresentation() const { if (const auto *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isUnsignedIntegerOrEnumerationType(); - else - return isUnsignedIntegerOrEnumerationType(); + if (const auto *VT = dyn_cast(CanonicalType)) + return VT->getElementType()->isUnsignedIntegerOrEnumerationType(); + return isUnsignedIntegerOrEnumerationType(); } bool Type::isFloatingType() const { @@ -2228,10 +2229,11 @@ bool Type::isIncompleteType(NamedDecl **Def) const { return !Rec->isCompleteDefinition(); } case ConstantArray: + case VariableArray: // An array is incomplete if its element type is incomplete // (C++ [dcl.array]p1). - // We don't handle variable arrays (they're not allowed in C++) or - // dependent-sized arrays (dependent types are never treated as incomplete). + // We don't handle dependent-sized arrays (dependent types are never treated + // as incomplete). return cast(CanonicalType)->getElementType() ->isIncompleteType(Def); case IncompleteArray: diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 3e8e94300cae..17e9b3f6a023 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1235,8 +1235,7 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS, // Only suppress an inline namespace if the name has the same lookup // results in the enclosing namespace. if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope && - DC->getParent()->lookup(NameInScope).size() == - DC->lookup(NameInScope).size()) + NS->isRedundantInlineQualifierFor(NameInScope)) return AppendScope(DC->getParent(), OS, NameInScope); AppendScope(DC->getParent(), OS, NS->getDeclName()); diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index b20a60425661..c2001070de55 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -883,6 +883,7 @@ const internal::VariadicDynCastAllOfMatcher whileStmt; const internal::VariadicDynCastAllOfMatcher doStmt; const internal::VariadicDynCastAllOfMatcher breakStmt; const internal::VariadicDynCastAllOfMatcher continueStmt; +const internal::VariadicDynCastAllOfMatcher coreturnStmt; const internal::VariadicDynCastAllOfMatcher returnStmt; const internal::VariadicDynCastAllOfMatcher gotoStmt; const internal::VariadicDynCastAllOfMatcher labelStmt; @@ -915,6 +916,12 @@ const internal::VariadicDynCastAllOfMatcher const internal::VariadicDynCastAllOfMatcher cxxNullPtrLiteralExpr; const internal::VariadicDynCastAllOfMatcher chooseExpr; +const internal::VariadicDynCastAllOfMatcher + coawaitExpr; +const internal::VariadicDynCastAllOfMatcher + dependentCoawaitExpr; +const internal::VariadicDynCastAllOfMatcher + coyieldExpr; const internal::VariadicDynCastAllOfMatcher gnuNullExpr; const internal::VariadicDynCastAllOfMatcher genericSelectionExpr; diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 3ffa0d6af217..783fb203c408 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -492,9 +492,11 @@ template Args, Diagnostics *Error) { - ArgT **InnerArgs = new ArgT *[Args.size()](); + SmallVector InnerArgsPtr; + InnerArgsPtr.resize_for_overwrite(Args.size()); + SmallVector InnerArgs; + InnerArgs.reserve(Args.size()); - bool HasError = false; for (size_t i = 0, e = Args.size(); i != e; ++i) { using ArgTraits = ArgTypeTraits; @@ -503,8 +505,7 @@ variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, if (!ArgTraits::hasCorrectType(Value)) { Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); - HasError = true; - break; + return {}; } if (!ArgTraits::hasCorrectValue(Value)) { if (llvm::Optional BestGuess = @@ -521,24 +522,12 @@ variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); } - HasError = true; - break; + return {}; } - - InnerArgs[i] = new ArgT(ArgTraits::get(Value)); - } - - VariantMatcher Out; - if (!HasError) { - Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs, - Args.size()))); + InnerArgs.set_size(i + 1); + InnerArgsPtr[i] = new (&InnerArgs[i]) ArgT(ArgTraits::get(Value)); } - - for (size_t i = 0, e = Args.size(); i != e; ++i) { - delete InnerArgs[i]; - } - delete[] InnerArgs; - return Out; + return outvalueToVariantMatcher(Func(InnerArgsPtr)); } /// Matcher descriptor for variadic functions. diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 4300eb8d8b98..8e595deac2cd 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -166,11 +166,14 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(complexType); REGISTER_MATCHER(compoundLiteralExpr); REGISTER_MATCHER(compoundStmt); + REGISTER_MATCHER(coawaitExpr); REGISTER_MATCHER(conditionalOperator); REGISTER_MATCHER(constantArrayType); REGISTER_MATCHER(constantExpr); REGISTER_MATCHER(containsDeclaration); REGISTER_MATCHER(continueStmt); + REGISTER_MATCHER(coreturnStmt); + REGISTER_MATCHER(coyieldExpr); REGISTER_MATCHER(cudaKernelCallExpr); REGISTER_MATCHER(cxxBindTemporaryExpr); REGISTER_MATCHER(cxxBoolLiteral); @@ -214,6 +217,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(decltypeType); REGISTER_MATCHER(deducedTemplateSpecializationType); REGISTER_MATCHER(defaultStmt); + REGISTER_MATCHER(dependentCoawaitExpr); REGISTER_MATCHER(dependentSizedArrayType); REGISTER_MATCHER(designatedInitExpr); REGISTER_MATCHER(designatorCountIs); @@ -229,6 +233,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(expr); REGISTER_MATCHER(exprWithCleanups); REGISTER_MATCHER(fieldDecl); + REGISTER_MATCHER(fixedPointLiteral); REGISTER_MATCHER(floatLiteral); REGISTER_MATCHER(forDecomposition); REGISTER_MATCHER(forEach); @@ -254,6 +259,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasAnyArgument); REGISTER_MATCHER(hasAnyBase); REGISTER_MATCHER(hasAnyBinding); + REGISTER_MATCHER(hasAnyBody); REGISTER_MATCHER(hasAnyClause); REGISTER_MATCHER(hasAnyConstructorInitializer); REGISTER_MATCHER(hasAnyDeclaration); @@ -526,6 +532,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(tagType); REGISTER_MATCHER(templateArgument); REGISTER_MATCHER(templateArgumentCountIs); + REGISTER_MATCHER(templateArgumentLoc); REGISTER_MATCHER(templateName); REGISTER_MATCHER(templateSpecializationType); REGISTER_MATCHER(templateTemplateParmDecl); diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp index 92d68d85fbc2..00bb51a1c0d3 100644 --- a/clang/lib/Analysis/CalledOnceCheck.cpp +++ b/clang/lib/Analysis/CalledOnceCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/Analyses/CalledOnceCheck.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" @@ -48,12 +49,29 @@ static constexpr unsigned EXPECTED_NUMBER_OF_BASIC_BLOCKS = 8; template using CFGSizedVector = llvm::SmallVector; constexpr llvm::StringLiteral CONVENTIONAL_NAMES[] = { - "completionHandler", "completion", "withCompletionHandler"}; + "completionHandler", "completion", "withCompletionHandler", + "withCompletion", "completionBlock", "withCompletionBlock", + "replyTo", "reply", "withReplyTo"}; constexpr llvm::StringLiteral CONVENTIONAL_SUFFIXES[] = { - "WithCompletionHandler", "WithCompletion"}; + "WithCompletionHandler", "WithCompletion", "WithCompletionBlock", + "WithReplyTo", "WithReply"}; constexpr llvm::StringLiteral CONVENTIONAL_CONDITIONS[] = { "error", "cancel", "shouldCall", "done", "OK", "success"}; +struct KnownCalledOnceParameter { + llvm::StringLiteral FunctionName; + unsigned ParamIndex; +}; +constexpr KnownCalledOnceParameter KNOWN_CALLED_ONCE_PARAMETERS[] = { + {llvm::StringLiteral{"dispatch_async"}, 1}, + {llvm::StringLiteral{"dispatch_async_and_wait"}, 1}, + {llvm::StringLiteral{"dispatch_after"}, 2}, + {llvm::StringLiteral{"dispatch_sync"}, 1}, + {llvm::StringLiteral{"dispatch_once"}, 1}, + {llvm::StringLiteral{"dispatch_barrier_async"}, 1}, + {llvm::StringLiteral{"dispatch_barrier_async_and_wait"}, 1}, + {llvm::StringLiteral{"dispatch_barrier_sync"}, 1}}; + class ParameterStatus { public: // Status kind is basically the main part of parameter's status. @@ -794,8 +812,12 @@ class CalledOnceChecker : public ConstStmtVisitor { } } - // Early exit if we don't have parameters for extra analysis. - if (NotCalledOnEveryPath.none() && NotUsedOnEveryPath.none()) + // Early exit if we don't have parameters for extra analysis... + if (NotCalledOnEveryPath.none() && NotUsedOnEveryPath.none() && + // ... or if we've seen variables with cleanup functions. + // We can't reason that we've seen every path in this case, + // and thus abandon reporting any warnings that imply that. + !FunctionHasCleanupVars) return; // We are looking for a pair of blocks A, B so that the following is true: @@ -864,16 +886,14 @@ class CalledOnceChecker : public ConstStmtVisitor { // Let's check if any of the call arguments is a point of interest. for (const auto &Argument : llvm::enumerate(Arguments)) { if (auto Index = getIndexOfExpression(Argument.value())) { - ParameterStatus &CurrentParamStatus = CurrentState.getStatusFor(*Index); - if (shouldBeCalledOnce(CallOrMessage, Argument.index())) { // If the corresponding parameter is marked as 'called_once' we should // consider it as a call. processCallFor(*Index, CallOrMessage); - } else if (CurrentParamStatus.getKind() == ParameterStatus::NotCalled) { + } else { // Otherwise, we mark this parameter as escaped, which can be // interpreted both as called or not called depending on the context. - CurrentParamStatus = ParameterStatus::Escaped; + processEscapeFor(*Index); } // Otherwise, let's keep the state as it is. } @@ -907,6 +927,16 @@ class CalledOnceChecker : public ConstStmtVisitor { } } + /// Process escape of the parameter with the given index + void processEscapeFor(unsigned Index) { + ParameterStatus &CurrentParamStatus = CurrentState.getStatusFor(Index); + + // Escape overrides whatever error we think happened. + if (CurrentParamStatus.isErrorStatus()) { + CurrentParamStatus = ParameterStatus::Escaped; + } + } + void findAndReportNotCalledBranches(const CFGBlock *Parent, unsigned Index, bool IsEscape = false) { for (const CFGBlock *Succ : Parent->succs()) { @@ -918,9 +948,9 @@ class CalledOnceChecker : public ConstStmtVisitor { "Block should have at least two successors at this point"); if (auto Clarification = NotCalledClarifier::clarify(Parent, Succ)) { const ParmVarDecl *Parameter = getParameter(Index); - Handler.handleNeverCalled(Parameter, Clarification->Location, - Clarification->Reason, !IsEscape, - !isExplicitlyMarked(Parameter)); + Handler.handleNeverCalled( + Parameter, AC.getDecl(), Clarification->Location, + Clarification->Reason, !IsEscape, !isExplicitlyMarked(Parameter)); } } } @@ -994,13 +1024,15 @@ class CalledOnceChecker : public ConstStmtVisitor { return hasConventionalSuffix(MethodSelector.getNameForSlot(0)); } - return isConventional(MethodSelector.getNameForSlot(PieceIndex)); + llvm::StringRef PieceName = MethodSelector.getNameForSlot(PieceIndex); + return isConventional(PieceName) || hasConventionalSuffix(PieceName); } bool shouldBeCalledOnce(const ParmVarDecl *Parameter) const { return isExplicitlyMarked(Parameter) || (CheckConventionalParameters && - isConventional(Parameter->getName()) && + (isConventional(Parameter->getName()) || + hasConventionalSuffix(Parameter->getName())) && isConventional(Parameter->getType())); } @@ -1078,6 +1110,91 @@ class CalledOnceChecker : public ConstStmtVisitor { return false; } + // Return a call site where the block is called exactly once or null otherwise + const Expr *getBlockGuaraneedCallSite(const BlockExpr *Block) const { + ParentMap &PM = AC.getParentMap(); + + // We don't want to track the block through assignments and so on, instead + // we simply see how the block used and if it's used directly in a call, + // we decide based on call to what it is. + // + // In order to do this, we go up the parents of the block looking for + // a call or a message expressions. These might not be immediate parents + // of the actual block expression due to casts and parens, so we skip them. + for (const Stmt *Prev = Block, *Current = PM.getParent(Block); + Current != nullptr; Prev = Current, Current = PM.getParent(Current)) { + // Skip no-op (for our case) operations. + if (isa(Current) || isa(Current)) + continue; + + // At this point, Prev represents our block as an immediate child of the + // call. + if (const auto *Call = dyn_cast(Current)) { + // It might be the call of the Block itself... + if (Call->getCallee() == Prev) + return Call; + + // ...or it can be an indirect call of the block. + return shouldBlockArgumentBeCalledOnce(Call, Prev) ? Call : nullptr; + } + if (const auto *Message = dyn_cast(Current)) { + return shouldBlockArgumentBeCalledOnce(Message, Prev) ? Message + : nullptr; + } + + break; + } + + return nullptr; + } + + template + bool shouldBlockArgumentBeCalledOnce(const CallLikeExpr *CallOrMessage, + const Stmt *BlockArgument) const { + // CallExpr::arguments does not interact nicely with llvm::enumerate. + llvm::ArrayRef Arguments = llvm::makeArrayRef( + CallOrMessage->getArgs(), CallOrMessage->getNumArgs()); + + for (const auto &Argument : llvm::enumerate(Arguments)) { + if (Argument.value() == BlockArgument) { + return shouldBlockArgumentBeCalledOnce(CallOrMessage, Argument.index()); + } + } + + return false; + } + + bool shouldBlockArgumentBeCalledOnce(const CallExpr *Call, + unsigned ParamIndex) const { + const FunctionDecl *Function = Call->getDirectCallee(); + return shouldBlockArgumentBeCalledOnce(Function, ParamIndex) || + shouldBeCalledOnce(Call, ParamIndex); + } + + bool shouldBlockArgumentBeCalledOnce(const ObjCMessageExpr *Message, + unsigned ParamIndex) const { + // At the moment, we don't have any Obj-C methods we want to specifically + // check in here. + return shouldBeCalledOnce(Message, ParamIndex); + } + + static bool shouldBlockArgumentBeCalledOnce(const FunctionDecl *Function, + unsigned ParamIndex) { + // There is a list of important API functions that while not following + // conventions nor being directly annotated, still guarantee that the + // callback parameter will be called exactly once. + // + // Here we check if this is the case. + return Function && + llvm::any_of(KNOWN_CALLED_ONCE_PARAMETERS, + [Function, ParamIndex]( + const KnownCalledOnceParameter &Reference) { + return Reference.FunctionName == + Function->getName() && + Reference.ParamIndex == ParamIndex; + }); + } + /// Return true if the analyzed function is actually a default implementation /// of the method that has to be overriden. /// @@ -1360,11 +1477,7 @@ class CalledOnceChecker : public ConstStmtVisitor { /// Check given parameter that was discovered to escape. void checkEscapee(const ParmVarDecl &Parameter) { if (auto Index = getIndex(Parameter)) { - ParameterStatus &CurrentParamStatus = CurrentState.getStatusFor(*Index); - - if (CurrentParamStatus.getKind() == ParameterStatus::NotCalled) { - CurrentParamStatus = ParameterStatus::Escaped; - } + processEscapeFor(*Index); } } @@ -1428,17 +1541,44 @@ class CalledOnceChecker : public ConstStmtVisitor { } void VisitBlockExpr(const BlockExpr *Block) { + // Block expressions are tricky. It is a very common practice to capture + // completion handlers by blocks and use them there. + // For this reason, it is important to analyze blocks and report warnings + // for completion handler misuse in blocks. + // + // However, it can be quite difficult to track how the block itself is being + // used. The full precise anlysis of that will be similar to alias analysis + // for completion handlers and can be too heavyweight for a compile-time + // diagnostic. Instead, we judge about the immediate use of the block. + // + // Here, we try to find a call expression where we know due to conventions, + // annotations, or other reasons that the block is called once and only + // once. + const Expr *CalledOnceCallSite = getBlockGuaraneedCallSite(Block); + + // We need to report this information to the handler because in the + // situation when we know that the block is called exactly once, we can be + // stricter in terms of reported diagnostics. + if (CalledOnceCallSite) { + Handler.handleBlockThatIsGuaranteedToBeCalledOnce(Block->getBlockDecl()); + } else { + Handler.handleBlockWithNoGuarantees(Block->getBlockDecl()); + } + for (const auto &Capture : Block->getBlockDecl()->captures()) { - // If a block captures a tracked parameter, it should be - // considered escaped. - // On one hand, blocks that do that should definitely call it on - // every path. However, it is not guaranteed that the block - // itself gets called whenever it gets created. - // - // Because we don't want to track blocks and whether they get called, - // we consider such parameters simply escaped. if (const auto *Param = dyn_cast(Capture.getVariable())) { - checkEscapee(*Param); + if (auto Index = getIndex(*Param)) { + if (CalledOnceCallSite) { + // The call site of a block can be considered a call site of the + // captured parameter we track. + processCallFor(*Index, CalledOnceCallSite); + } else { + // We still should consider this block as an escape for parameter, + // if we don't know about its call site or the number of time it + // can be invoked. + processEscapeFor(*Index); + } + } } } } @@ -1465,6 +1605,10 @@ class CalledOnceChecker : public ConstStmtVisitor { if (Var->getInit()) { checkEscapee(Var->getInit()); } + + if (Var->hasAttr()) { + FunctionHasCleanupVars = true; + } } } } @@ -1533,6 +1677,13 @@ class CalledOnceChecker : public ConstStmtVisitor { // around. bool SuppressOnConventionalErrorPaths = false; + // The user can annotate variable declarations with cleanup functions, which + // essentially imposes a custom destructor logic on that variable. + // It is possible to use it, however, to call tracked parameters on all exits + // from the function. For this reason, we track the fact that the function + // actually has these. + bool FunctionHasCleanupVars = false; + State CurrentState; ParamSizedVector TrackedParams; CFGSizedVector States; diff --git a/clang/lib/Analysis/RetainSummaryManager.cpp b/clang/lib/Analysis/RetainSummaryManager.cpp index 00bc854a8804..ecda47a67c1d 100644 --- a/clang/lib/Analysis/RetainSummaryManager.cpp +++ b/clang/lib/Analysis/RetainSummaryManager.cpp @@ -881,8 +881,8 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy, return None; } -/// \return Whether the chain of typedefs starting from {@code QT} -/// has a typedef with a given name {@code Name}. +/// \return Whether the chain of typedefs starting from @c QT +/// has a typedef with a given name @c Name. static bool hasTypedefNamed(QualType QT, StringRef Name) { while (auto *T = dyn_cast(QT)) { diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 21583e92c72d..84e0e91f597f 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -2051,15 +2051,11 @@ void BuildLockset::VisitCallExpr(const CallExpr *Exp) { if (ME && MD) { if (ME->isArrow()) { - if (MD->isConst()) - checkPtAccess(CE->getImplicitObjectArgument(), AK_Read); - else // FIXME -- should be AK_Written - checkPtAccess(CE->getImplicitObjectArgument(), AK_Read); + // Should perhaps be AK_Written if !MD->isConst(). + checkPtAccess(CE->getImplicitObjectArgument(), AK_Read); } else { - if (MD->isConst()) - checkAccess(CE->getImplicitObjectArgument(), AK_Read); - else // FIXME -- should be AK_Written - checkAccess(CE->getImplicitObjectArgument(), AK_Read); + // Should perhaps be AK_Written if !MD->isConst(). + checkAccess(CE->getImplicitObjectArgument(), AK_Read); } } diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 0cd89df41b67..49afaa9ba6a3 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -75,12 +75,13 @@ bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo, bool OclCUnsupported = !LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES); bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG; + bool CUDAUnsupported = !LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG; bool CPlusPlusUnsupported = !LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG; return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported && !OclC1Unsupported && !OclC2Unsupported && !OpenMPUnsupported && !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported && - !CPlusPlusUnsupported; + !CPlusPlusUnsupported && !CUDAUnsupported; } /// initializeBuiltins - Mark the identifiers for all the builtins with their diff --git a/clang/lib/Basic/CodeGenOptions.cpp b/clang/lib/Basic/CodeGenOptions.cpp index 4fc7a535c9eb..0c609cfa61de 100644 --- a/clang/lib/Basic/CodeGenOptions.cpp +++ b/clang/lib/Basic/CodeGenOptions.cpp @@ -20,12 +20,4 @@ CodeGenOptions::CodeGenOptions() { memcpy(CoverageVersion, "408*", 4); } -bool CodeGenOptions::isNoBuiltinFunc(const char *Name) const { - StringRef FuncName(Name); - for (unsigned i = 0, e = NoBuiltinFuncs.size(); i != e; ++i) - if (FuncName.equals(NoBuiltinFuncs[i])) - return true; - return false; -} - } // end namespace clang diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index 51c6e02e2e2e..cedc94a93550 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -227,6 +227,9 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { if (LangOpts.DeclSpecKeyword) AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this); + if (LangOpts.IEEE128) + AddKeyword("__ieee128", tok::kw___float128, KEYALL, LangOpts, *this); + // Add the 'import' contextual keyword. get("import").setModulesImport(true); } diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 8730a5d5f4e7..8d26149cd39d 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -429,7 +429,7 @@ void Module::buildVisibleModulesCache() const { } } -void Module::print(raw_ostream &OS, unsigned Indent) const { +void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const { OS.indent(Indent); if (IsFramework) OS << "framework "; @@ -535,7 +535,7 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { // the module. Regular inferred submodules are OK, as we need to look at all // those header files anyway. if (!(*MI)->IsInferred || (*MI)->IsFramework) - (*MI)->print(OS, Indent + 2); + (*MI)->print(OS, Indent + 2, Dump); for (unsigned I = 0, N = Exports.size(); I != N; ++I) { OS.indent(Indent + 2); @@ -559,6 +559,13 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS << "\n"; } + if (Dump) { + for (Module *M : Imports) { + OS.indent(Indent + 2); + llvm::errs() << "import " << M->getFullModuleName() << "\n"; + } + } + for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { OS.indent(Indent + 2); OS << "use "; @@ -619,7 +626,7 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { } LLVM_DUMP_METHOD void Module::dump() const { - print(llvm::errs()); + print(llvm::errs(), 0, true); } void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, diff --git a/clang/lib/Basic/OpenCLOptions.cpp b/clang/lib/Basic/OpenCLOptions.cpp index 2ca1ee064729..78b7493855e6 100644 --- a/clang/lib/Basic/OpenCLOptions.cpp +++ b/clang/lib/Basic/OpenCLOptions.cpp @@ -14,9 +14,21 @@ bool OpenCLOptions::isKnown(llvm::StringRef Ext) const { return OptMap.find(Ext) != OptMap.end(); } +bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext, + const LangOptions &LO) const { + if (!isKnown(Ext)) + return false; + + auto &OptInfo = OptMap.find(Ext)->getValue(); + if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO)) + return isSupported(Ext, LO); + + return isEnabled(Ext); +} + bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const { - auto E = OptMap.find(Ext); - return E != OptMap.end() && E->second.Enabled; + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Enabled; } bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const { @@ -26,32 +38,23 @@ bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const { bool OpenCLOptions::isSupported(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isAvailableIn(LO); + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isAvailableIn(LO); } bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isCoreIn(LO); + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isCoreIn(LO); } bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isOptionalCoreIn(LO); + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isOptionalCoreIn(LO); } bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext, @@ -61,12 +64,9 @@ bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext, bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isAvailableIn(LO) && + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isAvailableIn(LO) && !isSupportedCoreOrOptionalCore(Ext, LO); } @@ -105,10 +105,4 @@ void OpenCLOptions::disableAll() { Opt.getValue().Enabled = false; } -void OpenCLOptions::enableSupportedCore(const LangOptions &LO) { - for (auto &Opt : OptMap) - if (isSupportedCoreOrOptionalCore(Opt.getKey(), LO)) - Opt.getValue().Enabled = true; -} - } // end namespace clang diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index e289e953d47f..00abb3062ca6 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -660,6 +660,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_atomic: case OMPD_target_data: case OMPD_distribute_simd: + case OMPD_dispatch: CaptureRegions.push_back(OMPD_unknown); break; case OMPD_tile: diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index bc3c607dd74e..1783da8f9cfd 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -104,8 +104,10 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { UseSignedCharForObjCBool = true; UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = false; + UseLeadingZeroLengthBitfield = true; UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; + MaxAlignedAttribute = 0; HalfFormat = &llvm::APFloat::IEEEhalf(); FloatFormat = &llvm::APFloat::IEEEsingle(); DoubleFormat = &llvm::APFloat::IEEEdouble(); diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 793a471194fe..8df5cb7a3a61 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -595,13 +595,13 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, } case llvm::Triple::spir: { - if (Triple.getOS() != llvm::Triple::UnknownOS || + if (os != llvm::Triple::UnknownOS || Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return nullptr; return new SPIR32TargetInfo(Triple, Opts); } case llvm::Triple::spir64: { - if (Triple.getOS() != llvm::Triple::UnknownOS || + if (os != llvm::Triple::UnknownOS || Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return nullptr; return new SPIR64TargetInfo(Triple, Opts); @@ -611,7 +611,7 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, Triple.getVendor() != llvm::Triple::UnknownVendor || !Triple.isOSBinFormatWasm()) return nullptr; - switch (Triple.getOS()) { + switch (os) { case llvm::Triple::WASI: return new WASITargetInfo(Triple, Opts); case llvm::Triple::Emscripten: @@ -626,7 +626,7 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, Triple.getVendor() != llvm::Triple::UnknownVendor || !Triple.isOSBinFormatWasm()) return nullptr; - switch (Triple.getOS()) { + switch (os) { case llvm::Triple::WASI: return new WASITargetInfo(Triple, Opts); case llvm::Triple::Emscripten: diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 5b7981ea5256..f102f738582b 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -360,6 +360,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasLS64) Builder.defineMacro("__ARM_FEATURE_LS64", "1"); + if (HasRandGen) + Builder.defineMacro("__ARM_FEATURE_RNG", "1"); + switch (ArchKind) { default: break; @@ -425,6 +428,7 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, HasMTE = false; HasTME = false; HasLS64 = false; + HasRandGen = false; HasMatMul = false; HasBFloat16 = false; HasSVE2 = false; @@ -524,6 +528,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, HasLSE = true; if (Feature == "+ls64") HasLS64 = true; + if (Feature == "+rand") + HasRandGen = true; if (Feature == "+flagm") HasFlagM = true; } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 2809fbce9c88..c1f79e2055f9 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -38,6 +38,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasTME; bool HasPAuth; bool HasLS64; + bool HasRandGen; bool HasMatMul; bool HasSVE2; bool HasSVE2AES; diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index a84422e412ff..75115db1250b 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -183,6 +183,7 @@ bool AMDGPUTargetInfo::initFeatureMap( Features["dot2-insts"] = true; Features["dot5-insts"] = true; Features["dot6-insts"] = true; + Features["dot7-insts"] = true; Features["dl-insts"] = true; Features["flat-address-space"] = true; Features["16-bit-insts"] = true; @@ -200,6 +201,7 @@ bool AMDGPUTargetInfo::initFeatureMap( Features["dot2-insts"] = true; Features["dot5-insts"] = true; Features["dot6-insts"] = true; + Features["dot7-insts"] = true; LLVM_FALLTHROUGH; case GK_GFX1010: Features["dl-insts"] = true; @@ -227,6 +229,7 @@ bool AMDGPUTargetInfo::initFeatureMap( Features["dl-insts"] = true; Features["dot1-insts"] = true; Features["dot2-insts"] = true; + Features["dot7-insts"] = true; LLVM_FALLTHROUGH; case GK_GFX90C: case GK_GFX909: diff --git a/clang/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp index ba10459e9690..d1613fb22930 100644 --- a/clang/lib/Basic/Targets/Hexagon.cpp +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -136,7 +136,7 @@ const char *const HexagonTargetInfo::GCCRegNames[] = { "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3", - "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp", + "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp", "cs0", "cs1", "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14", "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28", "r31:30" diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 539466c4f678..6e757adfa8bf 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -261,6 +261,9 @@ class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo { case llvm::Triple::arm: this->MCountName = "__mcount"; break; + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + break; } } }; @@ -491,6 +494,9 @@ class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo { case llvm::Triple::sparcv9: this->MCountName = "_mcount"; break; + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + break; } } }; @@ -788,8 +794,10 @@ class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo { ZOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo(Triple, Opts) { this->WCharType = TargetInfo::UnsignedInt; + this->MaxAlignedAttribute = 128; this->UseBitFieldTypeAlignment = false; this->UseZeroLengthBitfieldAlignment = true; + this->UseLeadingZeroLengthBitfield = false; this->ZeroLengthBitfieldBoundary = 32; this->MinGlobalAlign = 0; this->DefaultAlignForAttributeAligned = 128; diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 73ecc05f2015..0703691f4c5b 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -66,8 +66,10 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector &Features, PairedVectorMemops = true; } else if (Feature == "+mma") { HasMMA = true; - } else if (Feature == "+rop-protection") { - HasROPProtection = true; + } else if (Feature == "+rop-protect") { + HasROPProtect = true; + } else if (Feature == "+privileged") { + HasPrivileged = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -195,10 +197,14 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__POWER9_VECTOR__"); if (HasMMA) Builder.defineMacro("__MMA__"); - if (HasROPProtection) - Builder.defineMacro("__ROP_PROTECTION__"); + if (HasROPProtect) + Builder.defineMacro("__ROP_PROTECT__"); + if (HasPrivileged) + Builder.defineMacro("__PRIVILEGED__"); if (HasP10Vector) Builder.defineMacro("__POWER10_VECTOR__"); + if (HasPCRelativeMemops) + Builder.defineMacro("__PCREL__"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -323,8 +329,10 @@ bool PPCTargetInfo::initFeatureMap( .Case("pwr8", true) .Default(false); - // ROP Protection is off by default. - Features["rop-protection"] = false; + // ROP Protect is off by default. + Features["rop-protect"] = false; + // Privileged instructions are off by default. + Features["privileged"] = false; Features["spe"] = llvm::StringSwitch(CPU) .Case("8548", true) @@ -363,9 +371,15 @@ bool PPCTargetInfo::initFeatureMap( } if (!(ArchDefs & ArchDefinePwr8) && - llvm::find(FeaturesVec, "+rop-protection") != FeaturesVec.end()) { - // We can turn on ROP Protection on Power 8 and above. - Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protection" << CPU; + llvm::find(FeaturesVec, "+rop-protect") != FeaturesVec.end()) { + // We can turn on ROP Protect on Power 8 and above. + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU; + return false; + } + + if (!(ArchDefs & ArchDefinePwr8) && + llvm::find(FeaturesVec, "+privileged") != FeaturesVec.end()) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU; return false; } @@ -407,7 +421,8 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("pcrelative-memops", HasPCRelativeMemops) .Case("spe", HasSPE) .Case("mma", HasMMA) - .Case("rop-protection", HasROPProtection) + .Case("rop-protect", HasROPProtect) + .Case("privileged", HasPrivileged) .Default(false); } @@ -566,6 +581,7 @@ void PPCTargetInfo::adjust(LangOptions &Opts) { LongDoubleFormat = Opts.PPCIEEELongDouble ? &llvm::APFloat::IEEEquad() : &llvm::APFloat::PPCDoubleDouble(); + Opts.IEEE128 = 1; } ArrayRef PPCTargetInfo::getTargetBuiltins() const { diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 0f9713a4c015..1c6c63bdfa90 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -59,7 +59,8 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // Target cpu features. bool HasAltivec = false; bool HasMMA = false; - bool HasROPProtection = false; + bool HasROPProtect = false; + bool HasPrivileged = false; bool HasVSX = false; bool HasP8Vector = false; bool HasP8Crypto = false; diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index aee5aba97fd3..4ca41414a9d6 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -31,7 +31,13 @@ ArrayRef RISCVTargetInfo::getGCCRegNames() const { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"}; + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", + + // Vector registers + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"}; return llvm::makeArrayRef(GCCRegNames); } @@ -81,7 +87,29 @@ bool RISCVTargetInfo::validateAsmConstraint( // An address that is held in a general-purpose register. Info.setAllowsMemory(); return true; + case 'v': + // A vector register. + if (Name[1] == 'r' || Name[1] == 'm') { + Info.setAllowsRegister(); + Name += 1; + return true; + } + return false; + } +} + +std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const { + std::string R; + switch (*Constraint) { + case 'v': + R = std::string("v"); + Constraint += 1; + break; + default: + R = TargetInfo::convertConstraint(Constraint); + break; } + return R; } void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index abae51e75a19..4fc8cd1e22df 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -59,6 +59,7 @@ class RISCVTargetInfo : public TargetInfo { WCharType = SignedInt; WIntType = UnsignedInt; HasRISCVVTypes = true; + MCountName = "_mcount"; } bool setCPU(const std::string &Name) override { @@ -96,6 +97,8 @@ class RISCVTargetInfo : public TargetInfo { bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override; + std::string convertConstraint(const char *&Constraint) const override; + bool hasFeature(StringRef Feature) const override; bool handleTargetFeatures(std::vector &Features, diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index 89babe85794d..2a5055c3d534 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -46,7 +46,6 @@ bool WebAssemblyTargetInfo::setABI(const std::string &Name) { bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) .Case("simd128", SIMDLevel >= SIMD128) - .Case("unimplemented-simd128", SIMDLevel >= UnimplementedSIMD128) .Case("nontrapping-fptoint", HasNontrappingFPToInt) .Case("sign-ext", HasSignExt) .Case("exception-handling", HasExceptionHandling) @@ -73,8 +72,6 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts, defineCPUMacros(Builder, "wasm", /*Tuning=*/false); if (SIMDLevel >= SIMD128) Builder.defineMacro("__wasm_simd128__"); - if (SIMDLevel >= UnimplementedSIMD128) - Builder.defineMacro("__wasm_unimplemented_simd128__"); if (HasNontrappingFPToInt) Builder.defineMacro("__wasm_nontrapping_fptoint__"); if (HasSignExt) @@ -99,9 +96,6 @@ void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap &Features, SIMDEnum Level, bool Enabled) { if (Enabled) { switch (Level) { - case UnimplementedSIMD128: - Features["unimplemented-simd128"] = true; - LLVM_FALLTHROUGH; case SIMD128: Features["simd128"] = true; LLVM_FALLTHROUGH; @@ -115,9 +109,6 @@ void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap &Features, case NoSIMD: case SIMD128: Features["simd128"] = false; - LLVM_FALLTHROUGH; - case UnimplementedSIMD128: - Features["unimplemented-simd128"] = false; break; } } @@ -127,8 +118,6 @@ void WebAssemblyTargetInfo::setFeatureEnabled(llvm::StringMap &Features, bool Enabled) const { if (Name == "simd128") setSIMDLevel(Features, SIMD128, Enabled); - else if (Name == "unimplemented-simd128") - setSIMDLevel(Features, UnimplementedSIMD128, Enabled); else Features[Name] = Enabled; } @@ -160,14 +149,6 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1)); continue; } - if (Feature == "+unimplemented-simd128") { - SIMDLevel = std::max(SIMDLevel, SIMDEnum(UnimplementedSIMD128)); - continue; - } - if (Feature == "-unimplemented-simd128") { - SIMDLevel = std::min(SIMDLevel, SIMDEnum(UnimplementedSIMD128 - 1)); - continue; - } if (Feature == "+nontrapping-fptoint") { HasNontrappingFPToInt = true; continue; diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 9150d849f601..be5b66a9580b 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -27,7 +27,6 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { enum SIMDEnum { NoSIMD, SIMD128, - UnimplementedSIMD128, } SIMDLevel = NoSIMD; bool HasNontrappingFPToInt = false; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 36b6588e773f..41eafd13d97c 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -81,6 +81,7 @@ #include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/CanonicalizeAliases.h" +#include "llvm/Transforms/Utils/Debugify.h" #include "llvm/Transforms/Utils/EntryExitInstrumenter.h" #include "llvm/Transforms/Utils/NameAnonGlobals.h" #include "llvm/Transforms/Utils/SymbolRewriter.h" @@ -549,7 +550,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions; Options.FunctionSections = CodeGenOpts.FunctionSections; Options.DataSections = CodeGenOpts.DataSections; - Options.IgnoreXCOFFVisibility = CodeGenOpts.IgnoreXCOFFVisibility; + Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility; Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames; Options.UniqueBasicBlockSectionNames = CodeGenOpts.UniqueBasicBlockSectionNames; @@ -945,7 +946,16 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, if (TM) TheModule->setDataLayout(TM->createDataLayout()); - legacy::PassManager PerModulePasses; + DebugifyCustomPassManager PerModulePasses; + DebugInfoPerPassMap DIPreservationMap; + if (CodeGenOpts.EnableDIPreservationVerify) { + PerModulePasses.setDebugifyMode(DebugifyMode::OriginalDebugInfo); + PerModulePasses.setDIPreservationMap(DIPreservationMap); + + if (!CodeGenOpts.DIBugsReportFilePath.empty()) + PerModulePasses.setOrigDIVerifyBugsReportFilePath( + CodeGenOpts.DIBugsReportFilePath); + } PerModulePasses.add( createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); @@ -1493,10 +1503,7 @@ static void runThinLTOBackend( // we should only invoke this using the individual indexes written out // via a WriteIndexesThinBackend. FunctionImporter::ImportMapTy ImportList; - std::vector> OwnedImports; - MapVector ModuleMap; - if (!lto::loadReferencedModules(*M, *CombinedIndex, ImportList, ModuleMap, - OwnedImports)) + if (!lto::initImportList(*M, *CombinedIndex, ImportList)) return; auto AddStream = [&](size_t Task) { @@ -1573,7 +1580,7 @@ static void runThinLTOBackend( if (Error E = thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList, ModuleToDefinedGVSummaries[M->getModuleIdentifier()], - ModuleMap, CGOpts.CmdArgs)) { + /* ModuleMap */ nullptr, CGOpts.CmdArgs)) { handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { errs() << "Error running ThinLTO backend: " << EIB.message() << '\n'; }); diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index c7256e240a31..8ac36e4a6b64 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -427,6 +427,8 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E, else switch ((llvm::AtomicOrderingCABI)FOS) { case llvm::AtomicOrderingCABI::relaxed: + // 31.7.2.18: "The failure argument shall not be memory_order_release + // nor memory_order_acq_rel". Fallback to monotonic. case llvm::AtomicOrderingCABI::release: case llvm::AtomicOrderingCABI::acq_rel: FailureOrder = llvm::AtomicOrdering::Monotonic; @@ -439,12 +441,10 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E, FailureOrder = llvm::AtomicOrdering::SequentiallyConsistent; break; } - if (isStrongerThan(FailureOrder, SuccessOrder)) { - // Don't assert on undefined behavior "failure argument shall be no - // stronger than the success argument". - FailureOrder = - llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder); - } + // Prior to c++17, "the failure argument shall be no stronger than the + // success argument". This condition has been lifted and the only + // precondition is 31.7.2.18. Effectively treat this as a DR and skip + // language version checks. emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder, FailureOrder, Scope); return; @@ -454,8 +454,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E, llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr, *SeqCstBB = nullptr; MonotonicBB = CGF.createBasicBlock("monotonic_fail", CGF.CurFn); - if (SuccessOrder != llvm::AtomicOrdering::Monotonic && - SuccessOrder != llvm::AtomicOrdering::Release) + if (SuccessOrder != llvm::AtomicOrdering::Monotonic) AcquireBB = CGF.createBasicBlock("acquire_fail", CGF.CurFn); if (SuccessOrder == llvm::AtomicOrdering::SequentiallyConsistent) SeqCstBB = CGF.createBasicBlock("seqcst_fail", CGF.CurFn); @@ -479,8 +478,9 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E, emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder, llvm::AtomicOrdering::Acquire, Scope); CGF.Builder.CreateBr(ContBB); - SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::consume), - AcquireBB); + if (SuccessOrder != llvm::AtomicOrdering::Release) + SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::consume), + AcquireBB); SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::acquire), AcquireBB); } diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 91c726f4cf64..7e5d96fb8633 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1190,8 +1190,10 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E, // First argument of a block call is a generic block literal casted to // generic void pointer, i.e. i8 addrspace(4)* + llvm::Type *GenericVoidPtrTy = + CGM.getOpenCLRuntime().getGenericVoidPointerType(); llvm::Value *BlockDescriptor = Builder.CreatePointerCast( - BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType()); + BlockPtr, GenericVoidPtrTy); QualType VoidPtrQualTy = Ctx.getPointerType( Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic)); Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy); @@ -1203,7 +1205,8 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E, Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee()); else { llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2); - Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); + Func = Builder.CreateAlignedLoad(GenericVoidPtrTy, FuncPtr, + getPointerAlign()); } } else { // Bitcast the block literal to a generic block literal. @@ -1219,7 +1222,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E, EmitCallArgs(Args, FnType->getAs(), E->arguments()); // Load the function. - Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); + Func = Builder.CreateAlignedLoad(VoidPtrTy, FuncPtr, getPointerAlign()); } const FunctionType *FuncTy = FnType->castAs(); diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h index 4cdf9fce7a3e..e79d72885e54 100644 --- a/clang/lib/CodeGen/CGBuilder.h +++ b/clang/lib/CodeGen/CGBuilder.h @@ -66,35 +66,28 @@ class CGBuilderTy : public CGBuilderBaseTy { // Note that we intentionally hide the CreateLoad APIs that don't // take an alignment. llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { - return CreateAlignedLoad(Addr.getPointer(), + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { // This overload is required to prevent string literals from // ending up in the IsVolatile overload. - return CreateAlignedLoad(Addr.getPointer(), + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, const llvm::Twine &Name = "") { - return CreateAlignedLoad( - Addr.getPointer(), Addr.getAlignment().getAsAlign(), IsVolatile, Name); + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), + Addr.getAlignment().getAsAlign(), IsVolatile, + Name); } using CGBuilderBaseTy::CreateAlignedLoad; - llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, - const llvm::Twine &Name = "") { - return CreateAlignedLoad(Addr, Align.getAsAlign(), Name); - } - llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, - const char *Name) { - return CreateAlignedLoad(Addr, Align.getAsAlign(), Name); - } llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name = "") { assert(Addr->getType()->getPointerElementType() == Ty); - return CreateAlignedLoad(Addr, Align.getAsAlign(), Name); + return CreateAlignedLoad(Ty, Addr, Align.getAsAlign(), Name); } // Note that we intentionally hide the CreateStore APIs that don't @@ -220,7 +213,7 @@ class CGBuilderTy : public CGBuilderBaseTy { CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType())); return Address( - CreateInBoundsGEP(Addr.getPointer(), + CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), {getSize(CharUnits::Zero()), getSize(Index)}, Name), Addr.getAlignment().alignmentAtOffset(Index * EltSize)); } @@ -261,7 +254,8 @@ class CGBuilderTy : public CGBuilderBaseTy { Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name = "") { assert(Addr.getElementType() == TypeCache.Int8Ty); - return Address(CreateInBoundsGEP(Addr.getPointer(), getSize(Offset), Name), + return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), + getSize(Offset), Name), Addr.getAlignment().alignmentAtOffset(Offset)); } Address CreateConstByteGEP(Address Addr, CharUnits Offset, diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 351ceb2dd8a8..87e61429a4af 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "CGCUDARuntime.h" #include "CGCXXABI.h" #include "CGObjCRuntime.h" #include "CGOpenCLRuntime.h" @@ -415,7 +416,7 @@ static Value *EmitISOVolatileLoad(CodeGenFunction &CGF, const CallExpr *E) { llvm::Type *ITy = llvm::IntegerType::get(CGF.getLLVMContext(), LoadSize.getQuantity() * 8); Ptr = CGF.Builder.CreateBitCast(Ptr, ITy->getPointerTo()); - llvm::LoadInst *Load = CGF.Builder.CreateAlignedLoad(Ptr, LoadSize); + llvm::LoadInst *Load = CGF.Builder.CreateAlignedLoad(ITy, Ptr, LoadSize); Load->setVolatile(true); return Load; } @@ -3079,15 +3080,38 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // isfinite(x) --> fabs(x) != infinity // x != NaN via the ordered compare in either case. CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); - // FIXME: for strictfp/IEEE-754 we need to not trap on SNaN here. Value *V = EmitScalarExpr(E->getArg(0)); - Value *Fabs = EmitFAbs(*this, V); - Constant *Infinity = ConstantFP::getInfinity(V->getType()); - CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf) - ? CmpInst::FCMP_OEQ - : CmpInst::FCMP_ONE; - Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf"); - return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType()))); + llvm::Type *Ty = V->getType(); + if (!Builder.getIsFPConstrained() || + Builder.getDefaultConstrainedExcept() == fp::ebIgnore || + !Ty->isIEEE()) { + Value *Fabs = EmitFAbs(*this, V); + Constant *Infinity = ConstantFP::getInfinity(V->getType()); + CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf) + ? CmpInst::FCMP_OEQ + : CmpInst::FCMP_ONE; + Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf"); + return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType()))); + } + + if (Value *Result = getTargetHooks().testFPKind(V, BuiltinID, Builder, CGM)) + return RValue::get(Result); + + // Inf values have all exp bits set and a zero significand. Therefore: + // isinf(V) == ((V << 1) == ((exp mask) << 1)) + // isfinite(V) == ((V << 1) < ((exp mask) << 1)) using unsigned comparison + unsigned bitsize = Ty->getScalarSizeInBits(); + llvm::IntegerType *IntTy = Builder.getIntNTy(bitsize); + Value *IntV = Builder.CreateBitCast(V, IntTy); + Value *Shl1 = Builder.CreateShl(IntV, 1); + const llvm::fltSemantics &Semantics = Ty->getFltSemantics(); + APInt ExpMask = APFloat::getInf(Semantics).bitcastToAPInt(); + Value *ExpMaskShl1 = llvm::ConstantInt::get(IntTy, ExpMask.shl(1)); + if (BuiltinID == Builtin::BI__builtin_isinf) + V = Builder.CreateICmpEQ(Shl1, ExpMaskShl1); + else + V = Builder.CreateICmpULT(Shl1, ExpMaskShl1); + return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); } case Builtin::BI__builtin_isinf_sign: { @@ -3252,7 +3276,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.CreateMemCpy(Dest, Src, SizeVal, false); if (BuiltinID == Builtin::BImempcpy || BuiltinID == Builtin::BI__builtin_mempcpy) - return RValue::get(Builder.CreateInBoundsGEP(Dest.getPointer(), SizeVal)); + return RValue::get(Builder.CreateInBoundsGEP(Dest.getElementType(), + Dest.getPointer(), SizeVal)); else return RValue::get(Dest.getPointer()); } @@ -3357,6 +3382,52 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); return RValue::get(Dest.getPointer()); } + case Builtin::BI__builtin_wmemchr: { + // The MSVC runtime library does not provide a definition of wmemchr, so we + // need an inline implementation. + if (!getTarget().getTriple().isOSMSVCRT()) + break; + + llvm::Type *WCharTy = ConvertType(getContext().WCharTy); + Value *Str = EmitScalarExpr(E->getArg(0)); + Value *Chr = EmitScalarExpr(E->getArg(1)); + Value *Size = EmitScalarExpr(E->getArg(2)); + + BasicBlock *Entry = Builder.GetInsertBlock(); + BasicBlock *CmpEq = createBasicBlock("wmemchr.eq"); + BasicBlock *Next = createBasicBlock("wmemchr.next"); + BasicBlock *Exit = createBasicBlock("wmemchr.exit"); + Value *SizeEq0 = Builder.CreateICmpEQ(Size, ConstantInt::get(SizeTy, 0)); + Builder.CreateCondBr(SizeEq0, Exit, CmpEq); + + EmitBlock(CmpEq); + PHINode *StrPhi = Builder.CreatePHI(Str->getType(), 2); + StrPhi->addIncoming(Str, Entry); + PHINode *SizePhi = Builder.CreatePHI(SizeTy, 2); + SizePhi->addIncoming(Size, Entry); + CharUnits WCharAlign = + getContext().getTypeAlignInChars(getContext().WCharTy); + Value *StrCh = Builder.CreateAlignedLoad(WCharTy, StrPhi, WCharAlign); + Value *FoundChr = Builder.CreateConstInBoundsGEP1_32(WCharTy, StrPhi, 0); + Value *StrEqChr = Builder.CreateICmpEQ(StrCh, Chr); + Builder.CreateCondBr(StrEqChr, Exit, Next); + + EmitBlock(Next); + Value *NextStr = Builder.CreateConstInBoundsGEP1_32(WCharTy, StrPhi, 1); + Value *NextSize = Builder.CreateSub(SizePhi, ConstantInt::get(SizeTy, 1)); + Value *NextSizeEq0 = + Builder.CreateICmpEQ(NextSize, ConstantInt::get(SizeTy, 0)); + Builder.CreateCondBr(NextSizeEq0, Exit, CmpEq); + StrPhi->addIncoming(NextStr, Next); + SizePhi->addIncoming(NextSize, Next); + + EmitBlock(Exit); + PHINode *Ret = Builder.CreatePHI(Str->getType(), 3); + Ret->addIncoming(llvm::Constant::getNullValue(Str->getType()), Entry); + Ret->addIncoming(llvm::Constant::getNullValue(Str->getType()), Next); + Ret->addIncoming(FoundChr, CmpEq); + return RValue::get(Ret); + } case Builtin::BI__builtin_wmemcmp: { // The MSVC runtime library does not provide a definition of wmemcmp, so we // need an inline implementation. @@ -4683,7 +4754,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, auto *Zero = llvm::ConstantInt::get(IntTy, 0); for (unsigned I = First; I < NumArgs; ++I) { auto *Index = llvm::ConstantInt::get(IntTy, I - First); - auto *GEP = Builder.CreateGEP(TmpPtr, {Zero, Index}); + auto *GEP = Builder.CreateGEP(Tmp.getElementType(), TmpPtr, + {Zero, Index}); if (I == First) ElemPtr = GEP; auto *V = @@ -4988,6 +5060,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); return RValue::get(Builder.CreateStore(ArgPtr, DestAddr)); } + + case Builtin::BI__builtin_get_device_side_mangled_name: { + auto Name = CGM.getCUDARuntime().getDeviceSideName( + cast(E->getArg(0)->IgnoreImpCasts())->getDecl()); + auto Str = CGM.GetAddrOfConstantCString(Name, ""); + llvm::Constant *Zeros[] = {llvm::ConstantInt::get(SizeTy, 0), + llvm::ConstantInt::get(SizeTy, 0)}; + auto *Ptr = llvm::ConstantExpr::getGetElementPtr(Str.getElementType(), + Str.getPointer(), Zeros); + return RValue::get(Ptr); + } } // If this is an alias for a lib function (e.g. __builtin_sin), emit @@ -8985,7 +9068,7 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, for (unsigned I = 0; I < NumOpnds; ++I) Builder.CreateDefaultAlignedStore( IsBoolTy ? Builder.CreateZExt(Ops[I], EltTy) : Ops[I], - Builder.CreateGEP(Alloca.getPointer(), + Builder.CreateGEP(Alloca.getElementType(), Alloca.getPointer(), {Builder.getInt64(0), Builder.getInt64(I)})); SVETypeFlags TypeFlags(Builtin->TypeModifier); @@ -8994,7 +9077,8 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, llvm::Type *OverloadedTy = getSVEVectorForElementType(EltTy); Function *F = CGM.getIntrinsic(Intrinsic::aarch64_sve_ld1rq, OverloadedTy); Value *Alloca0 = Builder.CreateGEP( - Alloca.getPointer(), {Builder.getInt64(0), Builder.getInt64(0)}); + Alloca.getElementType(), Alloca.getPointer(), + {Builder.getInt64(0), Builder.getInt64(0)}); Value *LD1RQ = Builder.CreateCall(F, {Pred, Alloca0}); if (!IsBoolTy) @@ -9150,6 +9234,38 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, "cls"); } + if (BuiltinID == AArch64::BI__builtin_arm_frint32zf || + BuiltinID == AArch64::BI__builtin_arm_frint32z) { + llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); + llvm::Type *Ty = Arg->getType(); + return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint32z, Ty), + Arg, "frint32z"); + } + + if (BuiltinID == AArch64::BI__builtin_arm_frint64zf || + BuiltinID == AArch64::BI__builtin_arm_frint64z) { + llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); + llvm::Type *Ty = Arg->getType(); + return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint64z, Ty), + Arg, "frint64z"); + } + + if (BuiltinID == AArch64::BI__builtin_arm_frint32xf || + BuiltinID == AArch64::BI__builtin_arm_frint32x) { + llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); + llvm::Type *Ty = Arg->getType(); + return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint32x, Ty), + Arg, "frint32x"); + } + + if (BuiltinID == AArch64::BI__builtin_arm_frint64xf || + BuiltinID == AArch64::BI__builtin_arm_frint64x) { + llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); + llvm::Type *Ty = Arg->getType(); + return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint64x, Ty), + Arg, "frint64x"); + } + if (BuiltinID == AArch64::BI__builtin_arm_jcvt) { assert((getContext().getTypeSize(E->getType()) == 32) && "__jcvt of unusual size!"); @@ -9198,6 +9314,23 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } } + if (BuiltinID == AArch64::BI__builtin_arm_rndr || + BuiltinID == AArch64::BI__builtin_arm_rndrrs) { + + auto Intr = (BuiltinID == AArch64::BI__builtin_arm_rndr + ? Intrinsic::aarch64_rndr + : Intrinsic::aarch64_rndrrs); + Function *F = CGM.getIntrinsic(Intr); + llvm::Value *Val = Builder.CreateCall(F); + Value *RandomValue = Builder.CreateExtractValue(Val, 0); + Value *Status = Builder.CreateExtractValue(Val, 1); + + Address MemAddress = EmitPointerWithAlignment(E->getArg(0)); + Builder.CreateStore(RandomValue, MemAddress); + Status = Builder.CreateZExt(Status, Int32Ty); + return Status; + } + if (BuiltinID == AArch64::BI__clear_cache) { assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); const FunctionDecl *FD = E->getDirectCallee(); @@ -10500,17 +10633,23 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } case NEON::BI__builtin_neon_vrndnh_f16: { Ops.push_back(EmitScalarExpr(E->getArg(0))); - Int = Intrinsic::aarch64_neon_frintn; + Int = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_roundeven + : Intrinsic::roundeven; return EmitNeonCall(CGM.getIntrinsic(Int, HalfTy), Ops, "vrndn"); } case NEON::BI__builtin_neon_vrndn_v: case NEON::BI__builtin_neon_vrndnq_v: { - Int = Intrinsic::aarch64_neon_frintn; + Int = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_roundeven + : Intrinsic::roundeven; return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); } case NEON::BI__builtin_neon_vrndns_f32: { Ops.push_back(EmitScalarExpr(E->getArg(0))); - Int = Intrinsic::aarch64_neon_frintn; + Int = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_roundeven + : Intrinsic::roundeven; return EmitNeonCall(CGM.getIntrinsic(Int, FloatTy), Ops, "vrndn"); } case NEON::BI__builtin_neon_vrndph_f16: { @@ -12129,7 +12268,8 @@ Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, Index)}; llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); - CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); + CpuValue = Builder.CreateAlignedLoad(Int32Ty, CpuValue, + CharUnits::fromQuantity(4)); // Check the value of the field against the requested value. return Builder.CreateICmpEQ(CpuValue, @@ -12186,8 +12326,8 @@ llvm::Value *CodeGenFunction::EmitX86CpuSupports(uint64_t FeaturesMask) { Value *Idxs[] = {Builder.getInt32(0), Builder.getInt32(3), Builder.getInt32(0)}; Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs); - Value *Features = - Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4)); + Value *Features = Builder.CreateAlignedLoad(Int32Ty, CpuFeatures, + CharUnits::fromQuantity(4)); // Check the value of the bit corresponding to the feature requested. Value *Mask = Builder.getInt32(Features1); @@ -12201,8 +12341,8 @@ llvm::Value *CodeGenFunction::EmitX86CpuSupports(uint64_t FeaturesMask) { "__cpu_features2"); cast(CpuFeatures2)->setDSOLocal(true); - Value *Features = - Builder.CreateAlignedLoad(CpuFeatures2, CharUnits::fromQuantity(4)); + Value *Features = Builder.CreateAlignedLoad(Int32Ty, CpuFeatures2, + CharUnits::fromQuantity(4)); // Check the value of the bit corresponding to the feature requested. Value *Mask = Builder.getInt32(Features2); @@ -14631,11 +14771,12 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, break; } + llvm::Type *Ty = FixedVectorType::get(Builder.getInt64Ty(), 2); Value *InOps[9]; InOps[0] = Ops[2]; for (int i = 0; i != 8; ++i) { Value *Ptr = Builder.CreateConstGEP1_32(Ops[1], i); - InOps[i + 1] = Builder.CreateAlignedLoad(Ptr, Align(16)); + InOps[i + 1] = Builder.CreateAlignedLoad(Ty, Ptr, Align(16)); } Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), InOps); @@ -14900,6 +15041,18 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); return Builder.CreateCall(F, X); } + case PPC::BI__builtin_altivec_vadduqm: + case PPC::BI__builtin_altivec_vsubuqm: { + llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); + Ops[0] = + Builder.CreateBitCast(Ops[0], llvm::FixedVectorType::get(Int128Ty, 1)); + Ops[1] = + Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(Int128Ty, 1)); + if (BuiltinID == PPC::BI__builtin_altivec_vadduqm) + return Builder.CreateAdd(Ops[0], Ops[1], "vadduqm"); + else + return Builder.CreateSub(Ops[0], Ops[1], "vsubuqm"); + } // Copy sign case PPC::BI__builtin_vsx_xvcpsgnsp: case PPC::BI__builtin_vsx_xvcpsgndp: { @@ -15204,7 +15357,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, for (unsigned i=0; i Values = {Dst}; for (unsigned i = 0; i < II.NumResults; ++i) { Value *V = Builder.CreateAlignedLoad( - Builder.CreateGEP(Src.getPointer(), llvm::ConstantInt::get(IntTy, i)), + Src.getElementType(), + Builder.CreateGEP(Src.getElementType(), Src.getPointer(), + llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, ParamType)); } @@ -16697,7 +16852,8 @@ CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { // Load A for (unsigned i = 0; i < MI.NumEltsA; ++i) { Value *V = Builder.CreateAlignedLoad( - Builder.CreateGEP(SrcA.getPointer(), + SrcA.getElementType(), + Builder.CreateGEP(SrcA.getElementType(), SrcA.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, AType)); @@ -16706,7 +16862,8 @@ CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { llvm::Type *BType = Intrinsic->getFunctionType()->getParamType(MI.NumEltsA); for (unsigned i = 0; i < MI.NumEltsB; ++i) { Value *V = Builder.CreateAlignedLoad( - Builder.CreateGEP(SrcB.getPointer(), + SrcB.getElementType(), + Builder.CreateGEP(SrcB.getElementType(), SrcB.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, BType)); @@ -16716,7 +16873,8 @@ CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { Intrinsic->getFunctionType()->getParamType(MI.NumEltsA + MI.NumEltsB); for (unsigned i = 0; i < MI.NumEltsC; ++i) { Value *V = Builder.CreateAlignedLoad( - Builder.CreateGEP(SrcC.getPointer(), + SrcC.getElementType(), + Builder.CreateGEP(SrcC.getElementType(), SrcC.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, CType)); @@ -17061,31 +17219,31 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, llvm_unreachable("unexpected builtin ID"); } } - case WebAssembly::BI__builtin_wasm_add_saturate_s_i8x16: - case WebAssembly::BI__builtin_wasm_add_saturate_u_i8x16: - case WebAssembly::BI__builtin_wasm_add_saturate_s_i16x8: - case WebAssembly::BI__builtin_wasm_add_saturate_u_i16x8: - case WebAssembly::BI__builtin_wasm_sub_saturate_s_i8x16: - case WebAssembly::BI__builtin_wasm_sub_saturate_u_i8x16: - case WebAssembly::BI__builtin_wasm_sub_saturate_s_i16x8: - case WebAssembly::BI__builtin_wasm_sub_saturate_u_i16x8: { + case WebAssembly::BI__builtin_wasm_add_sat_s_i8x16: + case WebAssembly::BI__builtin_wasm_add_sat_u_i8x16: + case WebAssembly::BI__builtin_wasm_add_sat_s_i16x8: + case WebAssembly::BI__builtin_wasm_add_sat_u_i16x8: + case WebAssembly::BI__builtin_wasm_sub_sat_s_i8x16: + case WebAssembly::BI__builtin_wasm_sub_sat_u_i8x16: + case WebAssembly::BI__builtin_wasm_sub_sat_s_i16x8: + case WebAssembly::BI__builtin_wasm_sub_sat_u_i16x8: { unsigned IntNo; switch (BuiltinID) { - case WebAssembly::BI__builtin_wasm_add_saturate_s_i8x16: - case WebAssembly::BI__builtin_wasm_add_saturate_s_i16x8: + case WebAssembly::BI__builtin_wasm_add_sat_s_i8x16: + case WebAssembly::BI__builtin_wasm_add_sat_s_i16x8: IntNo = Intrinsic::sadd_sat; break; - case WebAssembly::BI__builtin_wasm_add_saturate_u_i8x16: - case WebAssembly::BI__builtin_wasm_add_saturate_u_i16x8: + case WebAssembly::BI__builtin_wasm_add_sat_u_i8x16: + case WebAssembly::BI__builtin_wasm_add_sat_u_i16x8: IntNo = Intrinsic::uadd_sat; break; - case WebAssembly::BI__builtin_wasm_sub_saturate_s_i8x16: - case WebAssembly::BI__builtin_wasm_sub_saturate_s_i16x8: - IntNo = Intrinsic::wasm_sub_saturate_signed; + case WebAssembly::BI__builtin_wasm_sub_sat_s_i8x16: + case WebAssembly::BI__builtin_wasm_sub_sat_s_i16x8: + IntNo = Intrinsic::wasm_sub_sat_signed; break; - case WebAssembly::BI__builtin_wasm_sub_saturate_u_i8x16: - case WebAssembly::BI__builtin_wasm_sub_saturate_u_i16x8: - IntNo = Intrinsic::wasm_sub_saturate_unsigned; + case WebAssembly::BI__builtin_wasm_sub_sat_u_i8x16: + case WebAssembly::BI__builtin_wasm_sub_sat_u_i16x8: + IntNo = Intrinsic::wasm_sub_sat_unsigned; break; default: llvm_unreachable("unexpected builtin ID"); @@ -17153,11 +17311,10 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, ConvertType(E->getType())); return Builder.CreateCall(Callee, {LHS, RHS}); } - case WebAssembly::BI__builtin_wasm_q15mulr_saturate_s_i16x8: { + case WebAssembly::BI__builtin_wasm_q15mulr_sat_s_i16x8: { Value *LHS = EmitScalarExpr(E->getArg(0)); Value *RHS = EmitScalarExpr(E->getArg(1)); - Function *Callee = - CGM.getIntrinsic(Intrinsic::wasm_q15mulr_saturate_signed); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_q15mulr_sat_signed); return Builder.CreateCall(Callee, {LHS, RHS}); } case WebAssembly::BI__builtin_wasm_extmul_low_i8x16_s_i16x8: @@ -17233,17 +17390,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, CGM.getIntrinsic(Intrinsic::wasm_bitselect, ConvertType(E->getType())); return Builder.CreateCall(Callee, {V1, V2, C}); } - case WebAssembly::BI__builtin_wasm_signselect_i8x16: - case WebAssembly::BI__builtin_wasm_signselect_i16x8: - case WebAssembly::BI__builtin_wasm_signselect_i32x4: - case WebAssembly::BI__builtin_wasm_signselect_i64x2: { - Value *V1 = EmitScalarExpr(E->getArg(0)); - Value *V2 = EmitScalarExpr(E->getArg(1)); - Value *C = EmitScalarExpr(E->getArg(2)); - Function *Callee = - CGM.getIntrinsic(Intrinsic::wasm_signselect, ConvertType(E->getType())); - return Builder.CreateCall(Callee, {V1, V2, C}); - } case WebAssembly::BI__builtin_wasm_dot_s_i32x4_i16x8: { Value *LHS = EmitScalarExpr(E->getArg(0)); Value *RHS = EmitScalarExpr(E->getArg(1)); @@ -17255,12 +17401,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_popcnt); return Builder.CreateCall(Callee, {Vec}); } - case WebAssembly::BI__builtin_wasm_eq_i64x2: { - Value *LHS = EmitScalarExpr(E->getArg(0)); - Value *RHS = EmitScalarExpr(E->getArg(1)); - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_eq); - return Builder.CreateCall(Callee, {LHS, RHS}); - } case WebAssembly::BI__builtin_wasm_any_true_i8x16: case WebAssembly::BI__builtin_wasm_any_true_i16x8: case WebAssembly::BI__builtin_wasm_any_true_i32x4: @@ -17311,29 +17451,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::sqrt, Vec->getType()); return Builder.CreateCall(Callee, {Vec}); } - case WebAssembly::BI__builtin_wasm_qfma_f32x4: - case WebAssembly::BI__builtin_wasm_qfms_f32x4: - case WebAssembly::BI__builtin_wasm_qfma_f64x2: - case WebAssembly::BI__builtin_wasm_qfms_f64x2: { - Value *A = EmitScalarExpr(E->getArg(0)); - Value *B = EmitScalarExpr(E->getArg(1)); - Value *C = EmitScalarExpr(E->getArg(2)); - unsigned IntNo; - switch (BuiltinID) { - case WebAssembly::BI__builtin_wasm_qfma_f32x4: - case WebAssembly::BI__builtin_wasm_qfma_f64x2: - IntNo = Intrinsic::wasm_qfma; - break; - case WebAssembly::BI__builtin_wasm_qfms_f32x4: - case WebAssembly::BI__builtin_wasm_qfms_f64x2: - IntNo = Intrinsic::wasm_qfms; - break; - default: - llvm_unreachable("unexpected builtin ID"); - } - Function *Callee = CGM.getIntrinsic(IntNo, A->getType()); - return Builder.CreateCall(Callee, {A, B, C}); - } case WebAssembly::BI__builtin_wasm_narrow_s_i8x16_i16x8: case WebAssembly::BI__builtin_wasm_narrow_u_i8x16_i16x8: case WebAssembly::BI__builtin_wasm_narrow_s_i16x8_i32x4: @@ -17357,24 +17474,24 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, CGM.getIntrinsic(IntNo, {ConvertType(E->getType()), Low->getType()}); return Builder.CreateCall(Callee, {Low, High}); } - case WebAssembly::BI__builtin_wasm_widen_low_s_i32x4_i64x2: - case WebAssembly::BI__builtin_wasm_widen_high_s_i32x4_i64x2: - case WebAssembly::BI__builtin_wasm_widen_low_u_i32x4_i64x2: - case WebAssembly::BI__builtin_wasm_widen_high_u_i32x4_i64x2: { + case WebAssembly::BI__builtin_wasm_extend_low_s_i32x4_i64x2: + case WebAssembly::BI__builtin_wasm_extend_high_s_i32x4_i64x2: + case WebAssembly::BI__builtin_wasm_extend_low_u_i32x4_i64x2: + case WebAssembly::BI__builtin_wasm_extend_high_u_i32x4_i64x2: { Value *Vec = EmitScalarExpr(E->getArg(0)); unsigned IntNo; switch (BuiltinID) { - case WebAssembly::BI__builtin_wasm_widen_low_s_i32x4_i64x2: - IntNo = Intrinsic::wasm_widen_low_signed; + case WebAssembly::BI__builtin_wasm_extend_low_s_i32x4_i64x2: + IntNo = Intrinsic::wasm_extend_low_signed; break; - case WebAssembly::BI__builtin_wasm_widen_high_s_i32x4_i64x2: - IntNo = Intrinsic::wasm_widen_high_signed; + case WebAssembly::BI__builtin_wasm_extend_high_s_i32x4_i64x2: + IntNo = Intrinsic::wasm_extend_high_signed; break; - case WebAssembly::BI__builtin_wasm_widen_low_u_i32x4_i64x2: - IntNo = Intrinsic::wasm_widen_low_unsigned; + case WebAssembly::BI__builtin_wasm_extend_low_u_i32x4_i64x2: + IntNo = Intrinsic::wasm_extend_low_unsigned; break; - case WebAssembly::BI__builtin_wasm_widen_high_u_i32x4_i64x2: - IntNo = Intrinsic::wasm_widen_high_unsigned; + case WebAssembly::BI__builtin_wasm_extend_high_u_i32x4_i64x2: + IntNo = Intrinsic::wasm_extend_high_unsigned; break; default: llvm_unreachable("unexpected builtin ID"); @@ -17382,26 +17499,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(IntNo); return Builder.CreateCall(Callee, Vec); } - case WebAssembly::BI__builtin_wasm_widen_s_i8x16_i32x4: - case WebAssembly::BI__builtin_wasm_widen_u_i8x16_i32x4: { - Value *Vec = EmitScalarExpr(E->getArg(0)); - llvm::APSInt SubVecConst = - *E->getArg(1)->getIntegerConstantExpr(getContext()); - Value *SubVec = llvm::ConstantInt::get(getLLVMContext(), SubVecConst); - unsigned IntNo; - switch (BuiltinID) { - case WebAssembly::BI__builtin_wasm_widen_s_i8x16_i32x4: - IntNo = Intrinsic::wasm_widen_signed; - break; - case WebAssembly::BI__builtin_wasm_widen_u_i8x16_i32x4: - IntNo = Intrinsic::wasm_widen_unsigned; - break; - default: - llvm_unreachable("unexpected builtin ID"); - } - Function *Callee = CGM.getIntrinsic(IntNo); - return Builder.CreateCall(Callee, {Vec, SubVec}); - } case WebAssembly::BI__builtin_wasm_convert_low_s_i32x4_f64x2: case WebAssembly::BI__builtin_wasm_convert_low_u_i32x4_f64x2: { Value *Vec = EmitScalarExpr(E->getArg(0)); @@ -17419,16 +17516,16 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(IntNo); return Builder.CreateCall(Callee, Vec); } - case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4: - case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4: { + case WebAssembly::BI__builtin_wasm_trunc_sat_zero_s_f64x2_i32x4: + case WebAssembly::BI__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4: { Value *Vec = EmitScalarExpr(E->getArg(0)); unsigned IntNo; switch (BuiltinID) { - case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4: - IntNo = Intrinsic::wasm_trunc_saturate_zero_signed; + case WebAssembly::BI__builtin_wasm_trunc_sat_zero_s_f64x2_i32x4: + IntNo = Intrinsic::wasm_trunc_sat_zero_signed; break; - case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4: - IntNo = Intrinsic::wasm_trunc_saturate_zero_unsigned; + case WebAssembly::BI__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4: + IntNo = Intrinsic::wasm_trunc_sat_zero_unsigned; break; default: llvm_unreachable("unexpected builtin ID"); @@ -17516,16 +17613,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_shuffle); return Builder.CreateCall(Callee, Ops); } - case WebAssembly::BI__builtin_wasm_prefetch_t: { - Value *Ptr = EmitScalarExpr(E->getArg(0)); - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_prefetch_t); - return Builder.CreateCall(Callee, Ptr); - } - case WebAssembly::BI__builtin_wasm_prefetch_nt: { - Value *Ptr = EmitScalarExpr(E->getArg(0)); - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_prefetch_nt); - return Builder.CreateCall(Callee, Ptr); - } default: return nullptr; } @@ -17789,196 +17876,7 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, // Required for overloaded intrinsics. llvm::SmallVector IntrinsicTypes; switch (BuiltinID) { - // We could generate all the possible combinations and handling code in - // a file and include it here, instead of listing all the builtins plainly. - // Something like - // #include clang/Basic/RISCVVBuiltinCodeGen.inc - case RISCV::BI__builtin_rvv_vadd_vv_i8m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8mf8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8mf8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m1_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m8_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8mf8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m1_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m8_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32mf2_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16mf4_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8mf8_vl: - // The order of operands is (op1, op2, vl). - ID = Intrinsic::riscv_vadd; - IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()}; - break; - case RISCV::BI__builtin_rvv_vadd_vv_i8m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i64m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i32mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i16mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_i8mf8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i64m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i32mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i16mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_i8mf8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u64m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u32mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u16mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vv_u8mf8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m1_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u64m8_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u32mf2_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u16mf4_m_vl: - case RISCV::BI__builtin_rvv_vadd_vx_u8mf8_m_vl: - ID = Intrinsic::riscv_vadd_mask; - // The order of operands is (mask, maskedoff, op1, op2, vl). - IntrinsicTypes = {ResultType, Ops[3]->getType(), Ops[4]->getType()}; - // The order of intrinsic operands is (maskedoff, op1, op2, mask, vl). - std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1); - break; +#include "clang/Basic/riscv_vector_builtin_cg.inc" } assert(ID != Intrinsic::not_intrinsic); diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 3a311ab395e4..d53a623b258c 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "CGCUDARuntime.h" +#include "CGCXXABI.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "clang/AST/Decl.h" @@ -260,10 +261,15 @@ std::string CGNVCUDARuntime::getDeviceSideName(const NamedDecl *ND) { else GD = GlobalDecl(ND); std::string DeviceSideName; - if (DeviceMC->shouldMangleDeclName(ND)) { + MangleContext *MC; + if (CGM.getLangOpts().CUDAIsDevice) + MC = &CGM.getCXXABI().getMangleContext(); + else + MC = DeviceMC.get(); + if (MC->shouldMangleDeclName(ND)) { SmallString<256> Buffer; llvm::raw_svector_ostream Out(Buffer); - DeviceMC->mangleName(GD, Out); + MC->mangleName(GD, Out); DeviceSideName = std::string(Out.str()); } else DeviceSideName = std::string(ND->getIdentifier()->getName()); diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index a4bd2c6d5da0..641740c37a68 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -252,8 +252,8 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, "No kext in Microsoft ABI"); CodeGenModule &CGM = CGF.CGM; llvm::Value *VTable = CGM.getCXXABI().getAddrOfVTable(RD, CharUnits()); - Ty = Ty->getPointerTo()->getPointerTo(); - VTable = CGF.Builder.CreateBitCast(VTable, Ty); + Ty = Ty->getPointerTo(); + VTable = CGF.Builder.CreateBitCast(VTable, Ty->getPointerTo()); assert(VTable && "BuildVirtualCall = kext vtbl pointer is null"); uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); const VTableLayout &VTLayout = CGM.getItaniumVTableContext().getVTableLayout(RD); @@ -264,7 +264,7 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); llvm::Value *VFunc = CGF.Builder.CreateAlignedLoad( - VFuncPtr, llvm::Align(CGF.PointerAlignInBytes)); + Ty, VFuncPtr, llvm::Align(CGF.PointerAlignInBytes)); CGCallee Callee(GD, VFunc); return Callee; } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index da993bed7ba0..1d71148d67e6 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1765,8 +1765,7 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, if (AttrOnCallSite) { // Attributes that should go on the call site only. - if (!CodeGenOpts.SimplifyLibCalls || - CodeGenOpts.isNoBuiltinFunc(Name.data())) + if (!CodeGenOpts.SimplifyLibCalls || LangOpts.isNoBuiltinFunc(Name)) FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin); if (!CodeGenOpts.TrapFuncName.empty()) FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName); @@ -2291,7 +2290,7 @@ void CodeGenModule::ConstructAttributeList( // Attach attributes to inalloca argument. if (IRFunctionArgs.hasInallocaArg()) { llvm::AttrBuilder Attrs; - Attrs.addAttribute(llvm::Attribute::InAlloca); + Attrs.addInAllocaAttr(FI.getArgStruct()); ArgAttrs[IRFunctionArgs.getInallocaArgNo()] = llvm::AttributeSet::get(getLLVMContext(), Attrs); } @@ -3401,7 +3400,9 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, llvm::Value *ArgStruct = &*EI; llvm::Value *SRet = Builder.CreateStructGEP( nullptr, ArgStruct, RetAI.getInAllocaFieldIndex()); - RV = Builder.CreateAlignedLoad(SRet, getPointerAlign(), "sret"); + llvm::Type *Ty = + cast(SRet)->getResultElementType(); + RV = Builder.CreateAlignedLoad(Ty, SRet, getPointerAlign(), "sret"); } break; diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index e687a0d25430..7fcc84bc7a09 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -272,7 +272,7 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, llvm::Value *ptr = addr.getPointer(); unsigned AddrSpace = ptr->getType()->getPointerAddressSpace(); ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8Ty->getPointerTo(AddrSpace)); - ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr"); + ptr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ptr, baseOffset, "add.ptr"); // If we have a virtual component, the alignment of the result will // be relative only to the known alignment of that vbase. @@ -434,8 +434,8 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr, // Apply the offset. llvm::Value *Value = Builder.CreateBitCast(BaseAddr.getPointer(), Int8PtrTy); - Value = Builder.CreateInBoundsGEP(Value, Builder.CreateNeg(NonVirtualOffset), - "sub.ptr"); + Value = Builder.CreateInBoundsGEP( + Int8Ty, Value, Builder.CreateNeg(NonVirtualOffset), "sub.ptr"); // Just cast. Value = Builder.CreateBitCast(Value, DerivedPtrTy); @@ -1963,9 +1963,10 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, } // Find the end of the array. + llvm::Type *elementType = arrayBase.getElementType(); llvm::Value *arrayBegin = arrayBase.getPointer(); - llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements, - "arrayctor.end"); + llvm::Value *arrayEnd = Builder.CreateInBoundsGEP( + elementType, arrayBegin, numElements, "arrayctor.end"); // Enter the loop, setting up a phi for the current location to initialize. llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); @@ -2023,9 +2024,8 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, } // Go to the next element. - llvm::Value *next = - Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(SizeTy, 1), - "arrayctor.next"); + llvm::Value *next = Builder.CreateInBoundsGEP( + elementType, cur, llvm::ConstantInt::get(SizeTy, 1), "arrayctor.next"); cur->addIncoming(next, Builder.GetInsertBlock()); // Check whether that's the end of the loop. diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index 5c57ad0685d5..038238c84046 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -556,6 +556,8 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) { {Builder.getInt32(NewAlign), NullPtr, NullPtr, NullPtr}); createCoroData(*this, CurCoro, CoroId); CurCoro.Data->SuspendBB = RetBB; + assert(ShouldEmitLifetimeMarkers && + "Must emit lifetime intrinsics for coroutines"); // Backend is allowed to elide memory allocations, to help it, emit // auto mem = coro.alloc() ? 0 : ... allocation code ...; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 28846a4fde37..27f3e5df8800 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2385,7 +2385,8 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind, if (DebugKind == codegenoptions::DebugLineTablesOnly) return true; - if (DebugKind > codegenoptions::LimitedDebugInfo) + if (DebugKind > codegenoptions::LimitedDebugInfo || + RD->hasAttr()) return false; if (!LangOpts.CPlusPlus) @@ -2739,16 +2740,26 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, EltTys.push_back(PropertyNode); }; { - llvm::SmallPtrSet PropertySet; + // Use 'char' for the isClassProperty bit as DenseSet requires space for + // empty/tombstone keys in the data type (and bool is too small for that). + typedef std::pair IsClassAndIdent; + /// List of already emitted properties. Two distinct class and instance + /// properties can share the same identifier (but not two instance + /// properties or two class properties). + llvm::DenseSet PropertySet; + /// Returns the IsClassAndIdent key for the given property. + auto GetIsClassAndIdent = [](const ObjCPropertyDecl *PD) { + return std::make_pair(PD->isClassProperty(), PD->getIdentifier()); + }; for (const ObjCCategoryDecl *ClassExt : ID->known_extensions()) for (auto *PD : ClassExt->properties()) { - PropertySet.insert(PD->getIdentifier()); + PropertySet.insert(GetIsClassAndIdent(PD)); AddProperty(PD); } for (const auto *PD : ID->properties()) { // Don't emit duplicate metadata for properties that were already in a // class extension. - if (!PropertySet.insert(PD->getIdentifier()).second) + if (!PropertySet.insert(GetIsClassAndIdent(PD)).second) continue; AddProperty(PD); } @@ -3538,7 +3549,7 @@ void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit, llvm::DIScope *&FDContext, llvm::DINodeArray &TParamsArray, llvm::DINode::DIFlags &Flags) { - const auto *FD = cast(GD.getDecl()); + const auto *FD = cast(GD.getCanonicalDecl().getDecl()); Name = getFunctionName(FD); // Use mangled name as linkage name for C/C++ functions. if (FD->hasPrototype()) { diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 5a691ee303e4..243d93a8c165 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1767,8 +1767,8 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type, llvm::Value *BaseSizeInChars = llvm::ConstantInt::get(IntPtrTy, EltSize.getQuantity()); Address Begin = Builder.CreateElementBitCast(Loc, Int8Ty, "vla.begin"); - llvm::Value *End = - Builder.CreateInBoundsGEP(Begin.getPointer(), SizeVal, "vla.end"); + llvm::Value *End = Builder.CreateInBoundsGEP( + Begin.getElementType(), Begin.getPointer(), SizeVal, "vla.end"); llvm::BasicBlock *OriginBB = Builder.GetInsertBlock(); EmitBlock(LoopBB); llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur"); @@ -2196,7 +2196,8 @@ void CodeGenFunction::emitDestroy(Address addr, QualType type, } llvm::Value *begin = addr.getPointer(); - llvm::Value *end = Builder.CreateInBoundsGEP(begin, length); + llvm::Value *end = + Builder.CreateInBoundsGEP(addr.getElementType(), begin, length); emitArrayDestroy(begin, end, type, elementAlign, destroyer, checkZeroLength, useEHCleanupForArray); } diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 97e2a3a4b69a..078c60c6c4cf 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -1343,7 +1343,8 @@ namespace { CGF.EmitBlock(RethrowBB); if (SavedExnVar) { CGF.EmitRuntimeCallOrInvoke(RethrowFn, - CGF.Builder.CreateAlignedLoad(SavedExnVar, CGF.getPointerAlign())); + CGF.Builder.CreateAlignedLoad(CGF.Int8PtrTy, SavedExnVar, + CGF.getPointerAlign())); } else { CGF.EmitRuntimeCallOrInvoke(RethrowFn); } @@ -1879,8 +1880,24 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, setAddrOfLocalVar(VD, Recovered); if (isa(VD)) { - CXXThisValue = Builder.CreateLoad(Recovered, "this"); - CXXABIThisValue = CXXThisValue; + CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment; + CXXThisAlignment = ParentCGF.CXXThisAlignment; + CXXABIThisValue = Builder.CreateLoad(Recovered, "this"); + if (ParentCGF.LambdaThisCaptureField) { + LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField; + // We are in a lambda function where "this" is captured so the + // CXXThisValue need to be loaded from the lambda capture + LValue ThisFieldLValue = + EmitLValueForLambdaField(LambdaThisCaptureField); + if (!LambdaThisCaptureField->getType()->isPointerType()) { + CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); + } else { + CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation()) + .getScalarVal(); + } + } else { + CXXThisValue = CXXABIThisValue; + } } } @@ -1949,6 +1966,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF, StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args, OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc()); CurSEHParent = ParentCGF.CurSEHParent; + CurCodeDecl = ParentCGF.CurCodeDecl; CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo); EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter); @@ -2021,8 +2039,8 @@ void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy); llvm::Value *Ptrs = Builder.CreateBitCast(SEHInfo, PtrsTy->getPointerTo()); llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0); - Rec = Builder.CreateAlignedLoad(Rec, getPointerAlign()); - llvm::Value *Code = Builder.CreateAlignedLoad(Rec, getIntAlign()); + Rec = Builder.CreateAlignedLoad(RecordTy, Rec, getPointerAlign()); + llvm::Value *Code = Builder.CreateAlignedLoad(Int32Ty, Rec, getIntAlign()); assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except"); Builder.CreateStore(Code, SEHCodeSlotStack.back()); } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index e51a623eaaa6..3e234660c7a2 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -851,9 +851,9 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::ConstantInt::get(IntPtrTy, CacheSize-1)); llvm::Value *Indices[] = { Builder.getInt32(0), Slot }; - llvm::Value *CacheVal = - Builder.CreateAlignedLoad(Builder.CreateInBoundsGEP(Cache, Indices), - getPointerAlign()); + llvm::Value *CacheVal = Builder.CreateAlignedLoad( + IntPtrTy, Builder.CreateInBoundsGEP(HashTable, Cache, Indices), + getPointerAlign()); // If the hash isn't in the cache, call a runtime handler to perform the // hard work of checking whether the vptr is for an object of the right @@ -3613,6 +3613,7 @@ static const Expr *isSimpleArrayDecayOperand(const Expr *E) { } static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF, + llvm::Type *elemType, llvm::Value *ptr, ArrayRef indices, bool inbounds, @@ -3624,7 +3625,7 @@ static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF, CodeGenFunction::NotSubtraction, loc, name); } else { - return CGF.Builder.CreateGEP(ptr, indices, name); + return CGF.Builder.CreateGEP(elemType, ptr, indices, name); } } @@ -3718,8 +3719,8 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, if (!LastIndex || (!CGF.IsInPreservedAIRegion && !IsPreserveAIArrayBase(CGF, Base))) { eltPtr = emitArraySubscriptGEP( - CGF, addr.getPointer(), indices, inbounds, signedIndices, - loc, name); + CGF, addr.getElementType(), addr.getPointer(), indices, inbounds, + signedIndices, loc, name); } else { // Remember the original array subscript for bpf target unsigned idx = LastIndex->getZExtValue(); @@ -3844,8 +3845,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, CharUnits EltAlign = getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize); llvm::Value *EltPtr = - emitArraySubscriptGEP(*this, Addr.getPointer(), ScaledIdx, false, - SignedIndices, E->getExprLoc()); + emitArraySubscriptGEP(*this, Addr.getElementType(), Addr.getPointer(), + ScaledIdx, false, SignedIndices, E->getExprLoc()); Addr = Address(EltPtr, EltAlign); // Cast back. @@ -5173,9 +5174,9 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee getContext().getFunctionTypeWithExceptionSpec(PointeeType, EST_None); llvm::Constant *FTRTTIConst = CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true); - llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty}; + llvm::Type *PrefixSigType = PrefixSig->getType(); llvm::StructType *PrefixStructTy = llvm::StructType::get( - CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true); + CGM.getLLVMContext(), {PrefixSigType, Int32Ty}, /*isPacked=*/true); llvm::Value *CalleePtr = Callee.getFunctionPointer(); @@ -5184,7 +5185,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee llvm::Value *CalleeSigPtr = Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 0); llvm::Value *CalleeSig = - Builder.CreateAlignedLoad(CalleeSigPtr, getIntAlign()); + Builder.CreateAlignedLoad(PrefixSigType, CalleeSigPtr, getIntAlign()); llvm::Value *CalleeSigMatch = Builder.CreateICmpEQ(CalleeSig, PrefixSig); llvm::BasicBlock *Cont = createBasicBlock("cont"); @@ -5195,7 +5196,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee llvm::Value *CalleeRTTIPtr = Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 1); llvm::Value *CalleeRTTIEncoded = - Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign()); + Builder.CreateAlignedLoad(Int32Ty, CalleeRTTIPtr, getPointerAlign()); llvm::Value *CalleeRTTI = DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded); llvm::Value *CalleeRTTIMatch = diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 60ea1b2af037..f3ab91559d30 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -2056,7 +2056,7 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, Record->hasTrivialCopyAssignment() || Record->hasTrivialMoveConstructor() || Record->hasTrivialMoveAssignment() || - Record->isUnion()) && + Record->hasAttr() || Record->isUnion()) && "Trying to aggregate-copy a type without a trivial copy/move " "constructor or assignment operator"); // Ignore empty classes in C++. diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index e1907a6f0680..b8608911edb2 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1048,7 +1048,8 @@ void CodeGenFunction::EmitNewArrayInitializer( cast(ILE->getType()->getAsArrayTypeUnsafe()) ->getSize().getZExtValue(); CurPtr = - Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(), + Address(Builder.CreateInBoundsGEP(CurPtr.getElementType(), + CurPtr.getPointer(), Builder.getSize(InitListElements), "string.init.end"), CurPtr.getAlignment().alignmentAtOffset(InitListElements * @@ -1107,7 +1108,8 @@ void CodeGenFunction::EmitNewArrayInitializer( StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), ILE->getInit(i)->getType(), CurPtr, AggValueSlot::DoesNotOverlap); - CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(), + CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getElementType(), + CurPtr.getPointer(), Builder.getSize(1), "array.exp.next"), StartAlign.alignmentAtOffset((i + 1) * ElementSize)); @@ -1226,7 +1228,8 @@ void CodeGenFunction::EmitNewArrayInitializer( // Find the end of the array, hoisted out of the loop. llvm::Value *EndPtr = - Builder.CreateInBoundsGEP(BeginPtr.getPointer(), NumElements, "array.end"); + Builder.CreateInBoundsGEP(BeginPtr.getElementType(), BeginPtr.getPointer(), + NumElements, "array.end"); // If the number of elements isn't constant, we have to now check if there is // anything left to initialize. @@ -2034,8 +2037,8 @@ static void EmitArrayDelete(CodeGenFunction &CGF, deletedPtr.getAlignment().alignmentOfArrayElement(elementSize); llvm::Value *arrayBegin = deletedPtr.getPointer(); - llvm::Value *arrayEnd = - CGF.Builder.CreateInBoundsGEP(arrayBegin, numElements, "delete.end"); + llvm::Value *arrayEnd = CGF.Builder.CreateInBoundsGEP( + deletedPtr.getElementType(), arrayBegin, numElements, "delete.end"); // Note that it is legal to allocate a zero-length array, and we // can never fold the check away because the length should always @@ -2098,7 +2101,8 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { GEP.push_back(Zero); } - Ptr = Address(Builder.CreateInBoundsGEP(Ptr.getPointer(), GEP, "del.first"), + Ptr = Address(Builder.CreateInBoundsGEP(Ptr.getElementType(), + Ptr.getPointer(), GEP, "del.first"), Ptr.getAlignment()); } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index a1af760a1a98..48fcaed55ef5 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -3124,7 +3124,7 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( llvm::Value *IntMin = Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth())); - llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL); + llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty); llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin); llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne); @@ -3156,6 +3156,21 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { } } + if (Ops.Ty->isConstantMatrixType()) { + llvm::MatrixBuilder MB(Builder); + // We need to check the types of the operands of the operator to get the + // correct matrix dimensions. + auto *BO = cast(Ops.E); + (void)BO; + assert( + isa(BO->getLHS()->getType().getCanonicalType()) && + "first operand must be a matrix"); + assert(BO->getRHS()->getType().getCanonicalType()->isArithmeticType() && + "second operand must be an arithmetic type"); + return MB.CreateScalarDiv(Ops.LHS, Ops.RHS, + Ops.Ty->hasUnsignedIntegerRepresentation()); + } + if (Ops.LHS->getType()->isFPOrFPVectorTy()) { llvm::Value *Val; CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures); diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index bf164d242c7d..41915df7cb21 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -368,7 +368,7 @@ template struct GenFuncBase { CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts); Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy); llvm::Value *DstArrayEnd = - CGF.Builder.CreateInBoundsGEP(BC.getPointer(), SizeInBytes); + CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, BC.getPointer(), SizeInBytes); DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy, "dstarray.end"); llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock(); diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 663666b6bf8b..2005eb9856ae 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1819,9 +1819,10 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); + llvm::Type *UnsignedLongTy = ConvertType(getContext().UnsignedLongTy); llvm::Value *initialMutations = - Builder.CreateAlignedLoad(StateMutationsPtr, getPointerAlign(), - "forcoll.initial-mutations"); + Builder.CreateAlignedLoad(UnsignedLongTy, StateMutationsPtr, + getPointerAlign(), "forcoll.initial-mutations"); // Start looping. This is the point we return to whenever we have a // fresh, non-empty batch of objects. @@ -1843,8 +1844,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ // refreshes. StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); llvm::Value *currentMutations - = Builder.CreateAlignedLoad(StateMutationsPtr, getPointerAlign(), - "statemutations"); + = Builder.CreateAlignedLoad(UnsignedLongTy, StateMutationsPtr, + getPointerAlign(), "statemutations"); llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated"); llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated"); @@ -1854,9 +1855,9 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ // If so, call the enumeration-mutation function. EmitBlock(WasMutatedBB); + llvm::Type *ObjCIdType = ConvertType(getContext().getObjCIdType()); llvm::Value *V = - Builder.CreateBitCast(Collection, - ConvertType(getContext().getObjCIdType())); + Builder.CreateBitCast(Collection, ObjCIdType); CallArgList Args2; Args2.add(RValue::get(V), getContext().getObjCIdType()); // FIXME: We shouldn't need to get the function info here, the runtime already @@ -1905,7 +1906,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ llvm::Value *CurrentItemPtr = Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr"); llvm::Value *CurrentItem = - Builder.CreateAlignedLoad(CurrentItemPtr, getPointerAlign()); + Builder.CreateAlignedLoad(ObjCIdType, CurrentItemPtr, getPointerAlign()); if (SanOpts.has(SanitizerKind::ObjCCast)) { // Before using an item from the collection, check that the implicit cast diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 9825d7bca18c..6e6b73f550e3 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -780,7 +780,8 @@ class CGObjCGNUstep : public CGObjCGNU { // Load the imp from the slot llvm::Value *imp = Builder.CreateAlignedLoad( - Builder.CreateStructGEP(nullptr, slot, 4), CGF.getPointerAlign()); + IMPTy, Builder.CreateStructGEP(nullptr, slot, 4), + CGF.getPointerAlign()); // The lookup function may have changed the receiver, so make sure we use // the new one. @@ -798,8 +799,9 @@ class CGObjCGNUstep : public CGObjCGNU { CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs); slot->setOnlyReadsMemory(); - return Builder.CreateAlignedLoad(Builder.CreateStructGEP(nullptr, slot, 4), - CGF.getPointerAlign()); + return Builder.CreateAlignedLoad( + IMPTy, Builder.CreateStructGEP(nullptr, slot, 4), + CGF.getPointerAlign()); } public: @@ -1328,7 +1330,8 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { Ref = GV; } EmittedProtocolRef = true; - return CGF.Builder.CreateAlignedLoad(Ref, CGM.getPointerAlign()); + return CGF.Builder.CreateAlignedLoad(ProtocolPtrTy, Ref, + CGM.getPointerAlign()); } llvm::Constant *GenerateProtocolList(ArrayRef Protocols) { @@ -1689,7 +1692,8 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { IvarOffsetPointer = new llvm::GlobalVariable(TheModule, IntTy, false, llvm::GlobalValue::ExternalLinkage, nullptr, Name); CharUnits Align = CGM.getIntAlign(); - llvm::Value *Offset = CGF.Builder.CreateAlignedLoad(IvarOffsetPointer, Align); + llvm::Value *Offset = + CGF.Builder.CreateAlignedLoad(IntTy, IvarOffsetPointer, Align); if (Offset->getType() != PtrDiffTy) Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy); return Offset; @@ -2543,7 +2547,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, ReceiverClass = Builder.CreateBitCast(ReceiverClass, llvm::PointerType::getUnqual(IdTy)); ReceiverClass = - Builder.CreateAlignedLoad(ReceiverClass, CGF.getPointerAlign()); + Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.getPointerAlign()); } ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy); } else { @@ -2588,7 +2592,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1); // Load the superclass pointer ReceiverClass = - Builder.CreateAlignedLoad(ReceiverClass, CGF.getPointerAlign()); + Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.getPointerAlign()); } // Construct the structure used to look up the IMP llvm::StructType *ObjCSuperTy = @@ -4086,6 +4090,7 @@ llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF, return CGF.Builder.CreateZExtOrBitCast( CGF.Builder.CreateAlignedLoad( Int32Ty, CGF.Builder.CreateAlignedLoad( + llvm::Type::getInt32PtrTy(VMContext), ObjCIvarOffsetVariable(Interface, Ivar), CGF.getPointerAlign(), "ivar"), CharUnits::fromQuantity(4)), @@ -4101,7 +4106,7 @@ llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF, GV->setAlignment(Align.getAsAlign()); Offset = GV; } - Offset = CGF.Builder.CreateAlignedLoad(Offset, Align); + Offset = CGF.Builder.CreateAlignedLoad(IntTy, Offset, Align); if (Offset->getType() != PtrDiffTy) Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy); return Offset; diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 4c4a316308ce..76ea28c93313 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2096,6 +2096,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, CGF.Builder.CreateStructGEP(ObjCSuper, 0)); // If this is a class message the metaclass is passed as the target. + llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(ObjCTypes.ClassTy); llvm::Value *Target; if (IsClassMessage) { if (isCategoryImpl) { @@ -2107,13 +2108,14 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, // isa" is the first ivar in a class (which it must be). Target = EmitClassRef(CGF, Class->getSuperClass()); Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0); - Target = CGF.Builder.CreateAlignedLoad(Target, CGF.getPointerAlign()); + Target = CGF.Builder.CreateAlignedLoad(ClassTyPtr, Target, + CGF.getPointerAlign()); } else { llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class); llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1); - llvm::Value *Super = - CGF.Builder.CreateAlignedLoad(SuperPtr, CGF.getPointerAlign()); + llvm::Value *Super = CGF.Builder.CreateAlignedLoad(ClassTyPtr, SuperPtr, + CGF.getPointerAlign()); Target = Super; } } else if (isCategoryImpl) @@ -2121,7 +2123,8 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, else { llvm::Value *ClassPtr = EmitSuperClassRef(Class); ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1); - Target = CGF.Builder.CreateAlignedLoad(ClassPtr, CGF.getPointerAlign()); + Target = CGF.Builder.CreateAlignedLoad(ClassTyPtr, ClassPtr, + CGF.getPointerAlign()); } // FIXME: We shouldn't need to do this cast, rectify the ASTContext and // ObjCTypes types. @@ -5285,7 +5288,8 @@ llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, CGM.getPointerAlign(), true); } - return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign()); + return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, + CGF.getPointerAlign()); } llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, @@ -6682,7 +6686,7 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF, llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); if (PTGV) - return CGF.Builder.CreateAlignedLoad(PTGV, Align); + return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align); PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, llvm::GlobalValue::WeakAnyLinkage, Init, ProtocolName); @@ -6693,7 +6697,7 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF, if (!CGM.getTriple().isOSBinFormatMachO()) PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName)); CGM.addUsedGlobal(PTGV); - return CGF.Builder.CreateAlignedLoad(PTGV, Align); + return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align); } /// GenerateCategory - Build metadata for a category implementation. @@ -7246,7 +7250,8 @@ CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, } else { llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar); IvarOffsetValue = - CGF.Builder.CreateAlignedLoad(GV, CGF.getSizeAlign(), "ivar"); + CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV, + CGF.getSizeAlign(), "ivar"); if (IsIvarOffsetKnownIdempotent(CGF, Ivar)) cast(IvarOffsetValue) ->setMetadata(CGM.getModule().getMDKindID("invariant.load"), @@ -7486,7 +7491,7 @@ CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF, } CharUnits Align = CGF.getPointerAlign(); - return CGF.Builder.CreateAlignedLoad(Entry, Align); + return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align); } llvm::Value * @@ -7578,7 +7583,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF, CGM.addCompilerUsedGlobal(Entry); } - return CGF.Builder.CreateAlignedLoad(Entry, Align); + return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align); } /// GetClass - Return a reference to the class for the given interface diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index 9bf4d83f9bc4..108f6fc7ba60 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -64,7 +64,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, Ivar->getUsageType(ObjectPtrTy).withCVRQualifiers(CVRQualifiers); llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy); llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, CGF.Int8PtrTy); - V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr"); + V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, V, Offset, "add.ptr"); if (!Ivar->isBitField()) { V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy)); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index f9c79e6c95f5..4ec216a42188 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -409,6 +409,7 @@ class InlinedOpenMPRegionRAII { llvm::DenseMap LambdaCaptureFields; FieldDecl *LambdaThisCaptureField = nullptr; const CodeGen::CGBlockInfo *BlockInfo = nullptr; + bool NoInheritance = false; public: /// Constructs region for combined constructs. @@ -416,16 +417,19 @@ class InlinedOpenMPRegionRAII { /// a list of functions used for code generation of implicitly inlined /// regions. InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen, - OpenMPDirectiveKind Kind, bool HasCancel) - : CGF(CGF) { + OpenMPDirectiveKind Kind, bool HasCancel, + bool NoInheritance = true) + : CGF(CGF), NoInheritance(NoInheritance) { // Start emission for the construct. CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo( CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel); - std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields); - LambdaThisCaptureField = CGF.LambdaThisCaptureField; - CGF.LambdaThisCaptureField = nullptr; - BlockInfo = CGF.BlockInfo; - CGF.BlockInfo = nullptr; + if (NoInheritance) { + std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields); + LambdaThisCaptureField = CGF.LambdaThisCaptureField; + CGF.LambdaThisCaptureField = nullptr; + BlockInfo = CGF.BlockInfo; + CGF.BlockInfo = nullptr; + } } ~InlinedOpenMPRegionRAII() { @@ -434,9 +438,11 @@ class InlinedOpenMPRegionRAII { cast(CGF.CapturedStmtInfo)->getOldCSI(); delete CGF.CapturedStmtInfo; CGF.CapturedStmtInfo = OldCSI; - std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields); - CGF.LambdaThisCaptureField = LambdaThisCaptureField; - CGF.BlockInfo = BlockInfo; + if (NoInheritance) { + std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields); + CGF.LambdaThisCaptureField = LambdaThisCaptureField; + CGF.BlockInfo = BlockInfo; + } } }; @@ -649,9 +655,13 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF, InitRVal = RValue::getComplex(CGF.EmitLoadOfComplex(LV, DRD->getLocation())); break; - case TEK_Aggregate: - InitRVal = RValue::getAggregate(LV.getAddress(CGF)); - break; + case TEK_Aggregate: { + OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_LValue); + CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, LV); + CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(), + /*IsInitializer=*/false); + return; + } } OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_RValue); CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal); @@ -1028,7 +1038,7 @@ LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) { getThreadIDVariable()->getType()->castAs()); } -void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) { +void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt *S) { if (!CGF.HaveInsertPoint()) return; // 1.2.2 OpenMP Language Terminology @@ -1037,6 +1047,8 @@ void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) { // The point of exit cannot be a branch out of the structured block. // longjmp() and throw() must not violate the entry/exit criteria. CGF.EHStack.pushTerminate(); + if (S) + CGF.incrementProfileCounter(S); CodeGen(CGF); CGF.EHStack.popTerminate(); } @@ -3857,7 +3869,7 @@ static void emitPrivatesInit(CodeGenFunction &CGF, // Processing for implicitly captured variables. InlinedOpenMPRegionRAII Region( CGF, [](CodeGenFunction &, PrePostActionTy &) {}, OMPD_unknown, - /*HasCancel=*/false); + /*HasCancel=*/false, /*NoInheritance=*/true); SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef); } if (Type->isArrayType()) { @@ -6218,7 +6230,9 @@ void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF, bool HasCancel) { if (!CGF.HaveInsertPoint()) return; - InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel); + InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel, + InnerKind != OMPD_critical && + InnerKind != OMPD_master); CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr); } @@ -7429,6 +7443,7 @@ class MappableExprsHandler { // S1 s; // double *p; // struct S2 *ps; + // int &ref; // } // S2 s; // S2 *ps; @@ -7472,6 +7487,14 @@ class MappableExprsHandler { // optimizes this entry out, same in the examples below) // (***) map the pointee (map: to) // + // map(to: s.ref) + // &s, &(s.ref), sizeof(int*), TARGET_PARAM (*) + // &s, &(s.ref), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | TO (***) + // (*) alloc space for struct members, only this is a target parameter + // (**) map the pointer (nothing to be mapped in this example) (the compiler + // optimizes this entry out, same in the examples below) + // (***) map the pointee (map: to) + // // map(s.ps) // &s, &(s.ps), sizeof(S2*), TARGET_PARAM | TO | FROM // @@ -7669,6 +7692,7 @@ class MappableExprsHandler { uint64_t DimSize = 1; bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous; + bool IsPrevMemberReference = false; for (; I != CE; ++I) { // If the current component is member of a struct (parent struct) mark it. @@ -7726,12 +7750,16 @@ class MappableExprsHandler { .getCanonicalType() ->isAnyPointerType()) || I->getAssociatedExpression()->getType()->isAnyPointerType(); + bool IsMemberReference = isa(I->getAssociatedExpression()) && + MapDecl && + MapDecl->getType()->isLValueReferenceType(); bool IsNonDerefPointer = IsPointer && !UO && !BO && !IsNonContiguous; if (OASE) ++DimSize; - if (Next == CE || IsNonDerefPointer || IsFinalArraySection) { + if (Next == CE || IsMemberReference || IsNonDerefPointer || + IsFinalArraySection) { // If this is not the last component, we expect the pointer to be // associated with an array expression or member expression. assert((Next == CE || @@ -7744,22 +7772,53 @@ class MappableExprsHandler { "Unexpected expression"); Address LB = Address::invalid(); + Address LowestElem = Address::invalid(); + auto &&EmitMemberExprBase = [](CodeGenFunction &CGF, + const MemberExpr *E) { + const Expr *BaseExpr = E->getBase(); + // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a + // scalar. + LValue BaseLV; + if (E->isArrow()) { + LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; + Address Addr = + CGF.EmitPointerWithAlignment(BaseExpr, &BaseInfo, &TBAAInfo); + QualType PtrTy = BaseExpr->getType()->getPointeeType(); + BaseLV = CGF.MakeAddrLValue(Addr, PtrTy, BaseInfo, TBAAInfo); + } else { + BaseLV = CGF.EmitOMPSharedLValue(BaseExpr); + } + return BaseLV; + }; if (OAShE) { - LB = Address(CGF.EmitScalarExpr(OAShE->getBase()), - CGF.getContext().getTypeAlignInChars( - OAShE->getBase()->getType())); - } else { - LB = CGF.EmitOMPSharedLValue(I->getAssociatedExpression()) + LowestElem = LB = Address(CGF.EmitScalarExpr(OAShE->getBase()), + CGF.getContext().getTypeAlignInChars( + OAShE->getBase()->getType())); + } else if (IsMemberReference) { + const auto *ME = cast(I->getAssociatedExpression()); + LValue BaseLVal = EmitMemberExprBase(CGF, ME); + LowestElem = CGF.EmitLValueForFieldInitialization( + BaseLVal, cast(MapDecl)) + .getAddress(CGF); + LB = CGF.EmitLoadOfReferenceLValue(LowestElem, MapDecl->getType()) .getAddress(CGF); + } else { + LowestElem = LB = + CGF.EmitOMPSharedLValue(I->getAssociatedExpression()) + .getAddress(CGF); } // If this component is a pointer inside the base struct then we don't // need to create any entry for it - it will be combined with the object // it is pointing to into a single PTR_AND_OBJ entry. bool IsMemberPointerOrAddr = - (IsPointer || ForDeviceAddr) && EncounteredME && - (dyn_cast(I->getAssociatedExpression()) == - EncounteredME); + EncounteredME && + (((IsPointer || ForDeviceAddr) && + I->getAssociatedExpression() == EncounteredME) || + (IsPrevMemberReference && !IsPointer) || + (IsMemberReference && Next != CE && + !Next->getAssociatedExpression()->getType()->isPointerType())); if (!OverlappedElements.empty() && Next == CE) { // Handle base element with the info for overlapped elements. assert(!PartialStruct.Base.isValid() && "The base element is set."); @@ -7767,11 +7826,11 @@ class MappableExprsHandler { "Unexpected base element with the pointer type."); // Mark the whole struct as the struct that requires allocation on the // device. - PartialStruct.LowestElem = {0, LB}; + PartialStruct.LowestElem = {0, LowestElem}; CharUnits TypeSize = CGF.getContext().getTypeSizeInChars( I->getAssociatedExpression()->getType()); Address HB = CGF.Builder.CreateConstGEP( - CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(LB, + CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(LowestElem, CGF.VoidPtrTy), TypeSize.getQuantity() - 1); PartialStruct.HighestElem = { @@ -7797,10 +7856,20 @@ class MappableExprsHandler { Address ComponentLB = Address::invalid(); for (const OMPClauseMappableExprCommon::MappableComponent &MC : Component) { - if (MC.getAssociatedDeclaration()) { - ComponentLB = - CGF.EmitOMPSharedLValue(MC.getAssociatedExpression()) - .getAddress(CGF); + if (const ValueDecl *VD = MC.getAssociatedDeclaration()) { + const auto *FD = dyn_cast(VD); + if (FD && FD->getType()->isLValueReferenceType()) { + const auto *ME = + cast(MC.getAssociatedExpression()); + LValue BaseLVal = EmitMemberExprBase(CGF, ME); + ComponentLB = + CGF.EmitLValueForFieldInitialization(BaseLVal, FD) + .getAddress(CGF); + } else { + ComponentLB = + CGF.EmitOMPSharedLValue(MC.getAssociatedExpression()) + .getAddress(CGF); + } Size = CGF.Builder.CreatePtrDiff( CGF.EmitCastToVoidPtr(ComponentLB.getPointer()), CGF.EmitCastToVoidPtr(LB.getPointer())); @@ -7823,8 +7892,7 @@ class MappableExprsHandler { CombinedInfo.BasePointers.push_back(BP.getPointer()); CombinedInfo.Pointers.push_back(LB.getPointer()); Size = CGF.Builder.CreatePtrDiff( - CGF.EmitCastToVoidPtr( - CGF.Builder.CreateConstGEP(HB, 1).getPointer()), + CGF.Builder.CreateConstGEP(HB, 1).getPointer(), CGF.EmitCastToVoidPtr(LB.getPointer())); CombinedInfo.Sizes.push_back( CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true)); @@ -7856,13 +7924,13 @@ class MappableExprsHandler { OpenMPOffloadMappingFlags Flags = getMapTypeBits( MapType, MapModifiers, MotionModifiers, IsImplicit, !IsExpressionFirstInfo || RequiresReference || - FirstPointerInComplexData, + FirstPointerInComplexData || IsMemberReference, IsCaptureFirstInfo && !RequiresReference, IsNonContiguous); - if (!IsExpressionFirstInfo) { + if (!IsExpressionFirstInfo || IsMemberReference) { // If we have a PTR_AND_OBJ pair where the OBJ is a pointer as well, // then we reset the TO/FROM/ALWAYS/DELETE/CLOSE flags. - if (IsPointer) + if (IsPointer || (IsMemberReference && Next != CE)) Flags &= ~(OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_ALWAYS | OMP_MAP_DELETE | OMP_MAP_CLOSE); @@ -7888,21 +7956,21 @@ class MappableExprsHandler { // Update info about the lowest and highest elements for this struct if (!PartialStruct.Base.isValid()) { - PartialStruct.LowestElem = {FieldIndex, LB}; + PartialStruct.LowestElem = {FieldIndex, LowestElem}; if (IsFinalArraySection) { Address HB = CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false) .getAddress(CGF); PartialStruct.HighestElem = {FieldIndex, HB}; } else { - PartialStruct.HighestElem = {FieldIndex, LB}; + PartialStruct.HighestElem = {FieldIndex, LowestElem}; } PartialStruct.Base = BP; PartialStruct.LB = BP; } else if (FieldIndex < PartialStruct.LowestElem.first) { - PartialStruct.LowestElem = {FieldIndex, LB}; + PartialStruct.LowestElem = {FieldIndex, LowestElem}; } else if (FieldIndex > PartialStruct.HighestElem.first) { - PartialStruct.HighestElem = {FieldIndex, LB}; + PartialStruct.HighestElem = {FieldIndex, LowestElem}; } } @@ -7916,11 +7984,12 @@ class MappableExprsHandler { // The pointer becomes the base for the next element. if (Next != CE) - BP = LB; + BP = IsMemberReference ? LowestElem : LB; IsExpressionFirstInfo = false; IsCaptureFirstInfo = false; FirstPointerInComplexData = false; + IsPrevMemberReference = IsMemberReference; } else if (FirstPointerInComplexData) { QualType Ty = Components.rbegin() ->getAssociatedDeclaration() @@ -8904,7 +8973,6 @@ class MappableExprsHandler { std::prev(It) ->getAssociatedExpression() ->getType() - .getNonReferenceType() ->isPointerType()) continue; const MapData &BaseData = CI == CE ? L : L1; @@ -9948,7 +10016,7 @@ void CGOpenMPRuntime::emitTargetNumIterationsCall( llvm::Value *Args[] = {RTLoc, DeviceID, NumIterations}; CGF.EmitRuntimeCall( OMPBuilder.getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_push_target_tripcount), + CGM.getModule(), OMPRTL___kmpc_push_target_tripcount_mapper), Args); } }; diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 8e22f49aa119..51b8670c18b8 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -1912,8 +1912,9 @@ void CGOpenMPRuntimeGPU::emitGenericVarsProlog(CodeGenFunction &CGF, if (Rec.second.IsOnePerTeam) { VarTy = Rec.second.FD->getType(); } else { + Address Addr = VarAddr.getAddress(CGF); llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP( - VarAddr.getAddress(CGF).getPointer(), + Addr.getElementType(), Addr.getPointer(), {Bld.getInt32(0), getNVPTXLaneID(CGF)}); VarTy = Rec.second.FD->getType()->castAsArrayTypeUnsafe()->getElementType(); @@ -2092,14 +2093,6 @@ void CGOpenMPRuntimeGPU::emitNonSPMDParallelCall( // Force inline this outlined function at its call site. Fn->setLinkage(llvm::GlobalValue::InternalLinkage); - // Ensure we do not inline the function. This is trivially true for the ones - // passed to __kmpc_fork_call but the ones calles in serialized regions - // could be inlined. This is not a perfect but it is closer to the invariant - // we want, namely, every data environment starts with a new function. - // TODO: We should pass the if condition to the runtime function and do the - // handling there. Much cleaner code. - cast(OutlinedFn)->addFnAttr(llvm::Attribute::NoInline); - Address ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, /*Name=*/".zero.addr"); CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C*/ 0)); @@ -2943,7 +2936,8 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM, // Get pointer to location in transfer medium. // MediumPtr = &medium[warp_id] llvm::Value *MediumPtrVal = Bld.CreateInBoundsGEP( - TransferMedium, {llvm::Constant::getNullValue(CGM.Int64Ty), WarpID}); + TransferMedium->getValueType(), TransferMedium, + {llvm::Constant::getNullValue(CGM.Int64Ty), WarpID}); Address MediumPtr(MediumPtrVal, Align); // Casting to actual data type. // MediumPtr = (CopyType*)MediumPtrAddr; @@ -2991,7 +2985,7 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM, // SrcMediumPtr = &medium[tid] llvm::Value *SrcMediumPtrVal = Bld.CreateInBoundsGEP( - TransferMedium, + TransferMedium->getValueType(), TransferMedium, {llvm::Constant::getNullValue(CGM.Int64Ty), ThreadID}); Address SrcMediumPtr(SrcMediumPtrVal, Align); // SrcMediumVal = *SrcMediumPtr; @@ -3327,9 +3321,10 @@ static llvm::Value *emitListToGlobalCopyFunction( const FieldDecl *FD = VarFieldMap.lookup(VD); LValue GlobLVal = CGF.EmitLValueForField( CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD); - llvm::Value *BufferPtr = - Bld.CreateInBoundsGEP(GlobLVal.getPointer(CGF), Idxs); - GlobLVal.setAddress(Address(BufferPtr, GlobLVal.getAlignment())); + Address GlobAddr = GlobLVal.getAddress(CGF); + llvm::Value *BufferPtr = Bld.CreateInBoundsGEP( + GlobAddr.getElementType(), GlobAddr.getPointer(), Idxs); + GlobLVal.setAddress(Address(BufferPtr, GlobAddr.getAlignment())); switch (CGF.getEvaluationKind(Private->getType())) { case TEK_Scalar: { llvm::Value *V = CGF.EmitLoadOfScalar( @@ -3426,8 +3421,9 @@ static llvm::Value *emitListToGlobalReduceFunction( const FieldDecl *FD = VarFieldMap.lookup(VD); LValue GlobLVal = CGF.EmitLValueForField( CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD); - llvm::Value *BufferPtr = - Bld.CreateInBoundsGEP(GlobLVal.getPointer(CGF), Idxs); + Address GlobAddr = GlobLVal.getAddress(CGF); + llvm::Value *BufferPtr = Bld.CreateInBoundsGEP( + GlobAddr.getElementType(), GlobAddr.getPointer(), Idxs); llvm::Value *Ptr = CGF.EmitCastToVoidPtr(BufferPtr); CGF.EmitStoreOfScalar(Ptr, Elem, /*Volatile=*/false, C.VoidPtrTy); if ((*IPriv)->getType()->isVariablyModifiedType()) { @@ -3531,9 +3527,10 @@ static llvm::Value *emitGlobalToListCopyFunction( const FieldDecl *FD = VarFieldMap.lookup(VD); LValue GlobLVal = CGF.EmitLValueForField( CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD); - llvm::Value *BufferPtr = - Bld.CreateInBoundsGEP(GlobLVal.getPointer(CGF), Idxs); - GlobLVal.setAddress(Address(BufferPtr, GlobLVal.getAlignment())); + Address GlobAddr = GlobLVal.getAddress(CGF); + llvm::Value *BufferPtr = Bld.CreateInBoundsGEP( + GlobAddr.getElementType(), GlobAddr.getPointer(), Idxs); + GlobLVal.setAddress(Address(BufferPtr, GlobAddr.getAlignment())); switch (CGF.getEvaluationKind(Private->getType())) { case TEK_Scalar: { llvm::Value *V = CGF.EmitLoadOfScalar(GlobLVal, Loc); @@ -3630,8 +3627,9 @@ static llvm::Value *emitGlobalToListReduceFunction( const FieldDecl *FD = VarFieldMap.lookup(VD); LValue GlobLVal = CGF.EmitLValueForField( CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD); - llvm::Value *BufferPtr = - Bld.CreateInBoundsGEP(GlobLVal.getPointer(CGF), Idxs); + Address GlobAddr = GlobLVal.getAddress(CGF); + llvm::Value *BufferPtr = Bld.CreateInBoundsGEP( + GlobAddr.getElementType(), GlobAddr.getPointer(), Idxs); llvm::Value *Ptr = CGF.EmitCastToVoidPtr(BufferPtr); CGF.EmitStoreOfScalar(Ptr, Elem, /*Volatile=*/false, C.VoidPtrTy); if ((*IPriv)->getType()->isVariablyModifiedType()) { @@ -4210,6 +4208,15 @@ llvm::Function *CGOpenMPRuntimeGPU::createParallelDataSharingWrapper( auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, Twine(OutlinedParallelFn->getName(), "_wrapper"), &CGM.getModule()); + + // Ensure we do not inline the function. This is trivially true for the ones + // passed to __kmpc_fork_call but the ones calles in serialized regions + // could be inlined. This is not a perfect but it is closer to the invariant + // we want, namely, every data environment starts with a new function. + // TODO: We should pass the if condition to the runtime function and do the + // handling there. Much cleaner code. + Fn->addFnAttr(llvm::Attribute::NoInline); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); Fn->setLinkage(llvm::GlobalValue::InternalLinkage); Fn->setDoesNotRecurse(); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 021eda31ee71..b4ddfa586d1a 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -375,6 +375,12 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { EmitOMPTargetTeamsDistributeSimdDirective( cast(*S)); break; + case Stmt::OMPInteropDirectiveClass: + llvm_unreachable("Interop directive not supported yet."); + break; + case Stmt::OMPDispatchDirectiveClass: + llvm_unreachable("Dispatch directive not supported yet."); + break; } } @@ -818,8 +824,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); if (ConditionScope.requiresCleanups()) ExitBlock = createBasicBlock("while.exit"); - llvm::MDNode *Weights = createProfileOrBranchWeightsForLoop( - S.getCond(), getProfileCount(S.getBody()), S.getBody()); + llvm::MDNode *Weights = + createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())); + if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) + BoolCondVal = emitCondLikelihoodViaExpectIntrinsic( + BoolCondVal, Stmt::getLikelihood(S.getBody())); Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights); if (ExitBlock != LoopExit.getBlock()) { @@ -945,8 +954,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, // Start the loop with a block that tests the condition. // If there's an increment, the continue scope will be overwritten // later. - JumpDest Continue = getJumpDestInCurrentScope("for.cond"); - llvm::BasicBlock *CondBlock = Continue.getBlock(); + JumpDest CondDest = getJumpDestInCurrentScope("for.cond"); + llvm::BasicBlock *CondBlock = CondDest.getBlock(); EmitBlock(CondBlock); bool LoopMustProgress = false; @@ -964,24 +973,33 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, SourceLocToDebugLoc(R.getBegin()), SourceLocToDebugLoc(R.getEnd()), LoopMustProgress); - // If the for loop doesn't have an increment we can just use the - // condition as the continue block. Otherwise we'll need to create - // a block for it (in the current scope, i.e. in the scope of the - // condition), and that we will become our continue block. - if (S.getInc()) - Continue = getJumpDestInCurrentScope("for.inc"); - - // Store the blocks to use for break and continue. - BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); - // Create a cleanup scope for the condition variable cleanups. LexicalScope ConditionScope(*this, S.getSourceRange()); + // If the for loop doesn't have an increment we can just use the condition as + // the continue block. Otherwise, if there is no condition variable, we can + // form the continue block now. If there is a condition variable, we can't + // form the continue block until after we've emitted the condition, because + // the condition is in scope in the increment, but Sema's jump diagnostics + // ensure that there are no continues from the condition variable that jump + // to the loop increment. + JumpDest Continue; + if (!S.getInc()) + Continue = CondDest; + else if (!S.getConditionVariable()) + Continue = getJumpDestInCurrentScope("for.inc"); + BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); + if (S.getCond()) { // If the for statement has a condition scope, emit the local variable // declaration. if (S.getConditionVariable()) { EmitDecl(*S.getConditionVariable()); + + // We have entered the condition variable's scope, so we're now able to + // jump to the continue block. + Continue = S.getInc() ? getJumpDestInCurrentScope("for.inc") : CondDest; + BreakContinueStack.back().ContinueBlock = Continue; } llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); @@ -996,8 +1014,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, // C99 6.8.5p2/p4: The first substatement is executed if the expression // compares unequal to 0. The condition must be a scalar type. llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); - llvm::MDNode *Weights = createProfileOrBranchWeightsForLoop( - S.getCond(), getProfileCount(S.getBody()), S.getBody()); + llvm::MDNode *Weights = + createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())); + if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) + BoolCondVal = emitCondLikelihoodViaExpectIntrinsic( + BoolCondVal, Stmt::getLikelihood(S.getBody())); if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) if (C->isOne()) @@ -1082,8 +1103,11 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, // The body is executed if the expression, contextually converted // to bool, is true. llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); - llvm::MDNode *Weights = createProfileOrBranchWeightsForLoop( - S.getCond(), getProfileCount(S.getBody()), S.getBody()); + llvm::MDNode *Weights = + createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())); + if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) + BoolCondVal = emitCondLikelihoodViaExpectIntrinsic( + BoolCondVal, Stmt::getLikelihood(S.getBody())); Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights); if (ExitBlock != LoopExit.getBlock()) { @@ -1357,7 +1381,7 @@ void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S, // this case. (*SwitchWeights)[0] += ThisCount; } else if (SwitchLikelihood) - Weights = createBranchWeights(LH); + Cond = emitCondLikelihoodViaExpectIntrinsic(Cond, LH); Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 2eaa481cd911..02d4f6b3c315 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -634,6 +634,7 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes, WrapperCGF.CXXThisValue, WrapperFO); llvm::SmallVector CallArgs; + auto *PI = F->arg_begin(); for (const auto *Arg : Args) { llvm::Value *CallArg; auto I = LocalAddrs.find(Arg); @@ -642,6 +643,11 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, I->second.second, I->second.first ? I->second.first->getType() : Arg->getType(), AlignmentSource::Decl); + if (LV.getType()->isAnyComplexType()) + LV.setAddress(WrapperCGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + LV.getAddress(WrapperCGF), + PI->getType()->getPointerTo( + LV.getAddress(WrapperCGF).getAddressSpace()))); CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc()); } else { auto EI = VLASizes.find(Arg); @@ -655,6 +661,7 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, } } CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType())); + ++PI; } CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, Loc, F, CallArgs); WrapperCGF.FinishFunction(); @@ -4132,8 +4139,6 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( llvm::SmallVector, 16> FirstprivatePtrs; if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() || !Data.LastprivateVars.empty() || !Data.PrivateLocals.empty()) { - llvm::FunctionType *CopyFnTy = llvm::FunctionType::get( - CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true); enum { PrivatesParam = 2, CopyFnParam = 3 }; llvm::Value *CopyFn = CGF.Builder.CreateLoad( CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam))); @@ -4142,13 +4147,16 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( // Map privates. llvm::SmallVector, 16> PrivatePtrs; llvm::SmallVector CallArgs; + llvm::SmallVector ParamTypes; CallArgs.push_back(PrivatesPtr); + ParamTypes.push_back(PrivatesPtr->getType()); for (const Expr *E : Data.PrivateVars) { const auto *VD = cast(cast(E)->getDecl()); Address PrivatePtr = CGF.CreateMemTemp( CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); CallArgs.push_back(PrivatePtr.getPointer()); + ParamTypes.push_back(PrivatePtr.getType()); } for (const Expr *E : Data.FirstprivateVars) { const auto *VD = cast(cast(E)->getDecl()); @@ -4158,6 +4166,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( PrivatePtrs.emplace_back(VD, PrivatePtr); FirstprivatePtrs.emplace_back(VD, PrivatePtr); CallArgs.push_back(PrivatePtr.getPointer()); + ParamTypes.push_back(PrivatePtr.getType()); } for (const Expr *E : Data.LastprivateVars) { const auto *VD = cast(cast(E)->getDecl()); @@ -4166,6 +4175,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( ".lastpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); CallArgs.push_back(PrivatePtr.getPointer()); + ParamTypes.push_back(PrivatePtr.getType()); } for (const VarDecl *VD : Data.PrivateLocals) { QualType Ty = VD->getType().getNonReferenceType(); @@ -4177,7 +4187,12 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( CGF.getContext().getPointerType(Ty), ".local.ptr.addr"); UntiedLocalVars.try_emplace(VD, PrivatePtr, Address::invalid()); CallArgs.push_back(PrivatePtr.getPointer()); + ParamTypes.push_back(PrivatePtr.getType()); } + auto *CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(), + ParamTypes, /*isVarArg=*/false); + CopyFn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + CopyFn, CopyFnTy->getPointerTo()); CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall( CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs); for (const auto &Pair : LastprivateDstsOrigs) { @@ -4425,8 +4440,6 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( // Set proper addresses for generated private copies. OMPPrivateScope Scope(CGF); if (!Data.FirstprivateVars.empty()) { - llvm::FunctionType *CopyFnTy = llvm::FunctionType::get( - CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true); enum { PrivatesParam = 2, CopyFnParam = 3 }; llvm::Value *CopyFn = CGF.Builder.CreateLoad( CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam))); @@ -4435,7 +4448,9 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( // Map privates. llvm::SmallVector, 16> PrivatePtrs; llvm::SmallVector CallArgs; + llvm::SmallVector ParamTypes; CallArgs.push_back(PrivatesPtr); + ParamTypes.push_back(PrivatesPtr->getType()); for (const Expr *E : Data.FirstprivateVars) { const auto *VD = cast(cast(E)->getDecl()); Address PrivatePtr = @@ -4443,7 +4458,12 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( ".firstpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); CallArgs.push_back(PrivatePtr.getPointer()); + ParamTypes.push_back(PrivatePtr.getType()); } + auto *CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(), + ParamTypes, /*isVarArg=*/false); + CopyFn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + CopyFn, CopyFnTy->getPointerTo()); CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall( CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs); for (const auto &Pair : PrivatePtrs) { @@ -5587,7 +5607,11 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: - default: + case OMPC_init: + case OMPC_inbranch: + case OMPC_notinbranch: + case OMPC_link: + case OMPC_use: llvm_unreachable("Clause is not allowed in 'omp atomic'."); } } @@ -5619,7 +5643,7 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { C->getClauseKind() != OMPC_acq_rel && C->getClauseKind() != OMPC_acquire && C->getClauseKind() != OMPC_release && - C->getClauseKind() != OMPC_relaxed) { + C->getClauseKind() != OMPC_relaxed && C->getClauseKind() != OMPC_hint) { Kind = C->getClauseKind(); break; } @@ -5742,6 +5766,7 @@ static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S, CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); CGF.EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt()); + CGF.EnsureInsertPoint(); } void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM, diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 592f2642999d..d1e807ca48c6 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -496,6 +496,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { if (LargestVectorWidth) CurFn->addFnAttr("min-legal-vector-width", llvm::utostr(LargestVectorWidth)); + // Add vscale attribute if appropriate. + if (getLangOpts().ArmSveVectorBits) { + unsigned VScale = getLangOpts().ArmSveVectorBits / 128; + CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(getLLVMContext(), + VScale, VScale)); + } + // If we generated an unreachable return block, delete it now. if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty()) { Builder.ClearInsertionPoint(); @@ -1062,8 +1069,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function::arg_iterator EI = CurFn->arg_end(); --EI; llvm::Value *Addr = Builder.CreateStructGEP(nullptr, &*EI, Idx); + llvm::Type *Ty = + cast(Addr)->getResultElementType(); ReturnValuePointer = Address(Addr, getPointerAlign()); - Addr = Builder.CreateAlignedLoad(Addr, getPointerAlign(), "agg.result"); + Addr = Builder.CreateAlignedLoad(Ty, Addr, getPointerAlign(), "agg.result"); ReturnValue = Address(Addr, CGM.getNaturalTypeAlignment(RetTy)); } else { ReturnValue = CreateIRTemp(RetTy, "retval"); @@ -1309,10 +1318,16 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, Stmt *Body = FD->getBody(); - // Initialize helper which will detect jumps which can cause invalid lifetime - // markers. - if (Body && ShouldEmitLifetimeMarkers) - Bypasses.Init(Body); + if (Body) { + // Coroutines always emit lifetime markers. + if (isa(Body)) + ShouldEmitLifetimeMarkers = true; + + // Initialize helper which will detect jumps which can cause invalid + // lifetime markers. + if (ShouldEmitLifetimeMarkers) + Bypasses.Init(Body); + } // Emit the standard function prologue. StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin()); @@ -1762,10 +1777,19 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, return; } + // Emit the code with the fully general case. + llvm::Value *CondV; + { + ApplyDebugLocation DL(*this, Cond); + CondV = EvaluateExprAsBool(Cond); + } + + llvm::MDNode *Weights = nullptr; + llvm::MDNode *Unpredictable = nullptr; + // If the branch has a condition wrapped by __builtin_unpredictable, // create metadata that specifies that the branch is unpredictable. // Don't bother if not optimizing because that metadata would not be used. - llvm::MDNode *Unpredictable = nullptr; auto *Call = dyn_cast(Cond->IgnoreImpCasts()); if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) { auto *FD = dyn_cast_or_null(Call->getCalleeDecl()); @@ -1775,18 +1799,17 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, } } - llvm::MDNode *Weights = createBranchWeights(LH); - if (!Weights) { + // If there is a Likelihood knowledge for the cond, lower it. + // Note that if not optimizing this won't emit anything. + llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH); + if (CondV != NewCondV) + CondV = NewCondV; + else { + // Otherwise, lower profile counts. Note that we do this even at -O0. uint64_t CurrentCount = std::max(getCurrentProfileCount(), TrueCount); Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount); } - // Emit the code with the fully general case. - llvm::Value *CondV; - { - ApplyDebugLocation DL(*this, Cond); - CondV = EvaluateExprAsBool(Cond); - } Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable); } @@ -1814,8 +1837,8 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, Address begin = Builder.CreateElementBitCast(dest, CGF.Int8Ty, "vla.begin"); - llvm::Value *end = - Builder.CreateInBoundsGEP(begin.getPointer(), sizeInChars, "vla.end"); + llvm::Value *end = Builder.CreateInBoundsGEP( + begin.getElementType(), begin.getPointer(), sizeInChars, "vla.end"); llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock(); llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop"); @@ -2022,9 +2045,9 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, addr = Builder.CreateElementBitCast(addr, baseType, "array.begin"); } else { // Create the actual GEP. - addr = Address(Builder.CreateInBoundsGEP(addr.getPointer(), - gepIndices, "array.begin"), - addr.getAlignment()); + addr = Address(Builder.CreateInBoundsGEP( + addr.getElementType(), addr.getPointer(), gepIndices, "array.begin"), + addr.getAlignment()); } baseType = eltType; @@ -2630,39 +2653,30 @@ llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) { return llvm::DebugLoc(); } -static Optional> -getLikelihoodWeights(Stmt::Likelihood LH) { +llvm::Value * +CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond, + Stmt::Likelihood LH) { switch (LH) { - case Stmt::LH_Unlikely: - return std::pair(llvm::UnlikelyBranchWeight, - llvm::LikelyBranchWeight); case Stmt::LH_None: - return None; + return Cond; case Stmt::LH_Likely: - return std::pair(llvm::LikelyBranchWeight, - llvm::UnlikelyBranchWeight); + case Stmt::LH_Unlikely: + // Don't generate llvm.expect on -O0 as the backend won't use it for + // anything. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + return Cond; + llvm::Type *CondTy = Cond->getType(); + assert(CondTy->isIntegerTy(1) && "expecting condition to be a boolean"); + llvm::Function *FnExpect = + CGM.getIntrinsic(llvm::Intrinsic::expect, CondTy); + llvm::Value *ExpectedValueOfCond = + llvm::ConstantInt::getBool(CondTy, LH == Stmt::LH_Likely); + return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond}, + Cond->getName() + ".expval"); } llvm_unreachable("Unknown Likelihood"); } -llvm::MDNode *CodeGenFunction::createBranchWeights(Stmt::Likelihood LH) const { - Optional> LHW = getLikelihoodWeights(LH); - if (!LHW) - return nullptr; - - llvm::MDBuilder MDHelper(CGM.getLLVMContext()); - return MDHelper.createBranchWeights(LHW->first, LHW->second); -} - -llvm::MDNode *CodeGenFunction::createProfileOrBranchWeightsForLoop( - const Stmt *Cond, uint64_t LoopCount, const Stmt *Body) const { - llvm::MDNode *Weights = createProfileWeightsForLoop(Cond, LoopCount); - if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) - Weights = createBranchWeights(Stmt::getLikelihood(Body)); - - return Weights; -} - llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name) { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8dc3a8ef3aa1..b15fe7c44229 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1445,8 +1445,9 @@ class CodeGenFunction : public CodeGenTypeCache { }; OpenMPCancelExitStack OMPCancelStack; - /// Calculate branch weights for the likelihood attribute - llvm::MDNode *createBranchWeights(Stmt::Likelihood LH) const; + /// Lower the Likelihood knowledge about the \p Cond via llvm.expect intrin. + llvm::Value *emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond, + Stmt::Likelihood LH); CodeGenPGO PGO; @@ -1457,13 +1458,6 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::MDNode *createProfileWeightsForLoop(const Stmt *Cond, uint64_t LoopCount) const; - /// Calculate the branch weight for PGO data or the likelihood attribute. - /// The function tries to get the weight of \ref createProfileWeightsForLoop. - /// If that fails it gets the weight of \ref createBranchWeights. - llvm::MDNode *createProfileOrBranchWeightsForLoop(const Stmt *Cond, - uint64_t LoopCount, - const Stmt *Body) const; - public: /// Increment the profiler's counter for the given statement by \p StepV. /// If \p StepV is null, the default increment is 1. @@ -1892,8 +1886,9 @@ class CodeGenFunction : public CodeGenTypeCache { /// function attribute. unsigned LargestVectorWidth = 0; - /// True if we need emit the life-time markers. - const bool ShouldEmitLifetimeMarkers; + /// True if we need emit the life-time markers. This is initially set in + /// the constructor, but could be overwritten to true if this is a coroutine. + bool ShouldEmitLifetimeMarkers; /// Add OpenCL kernel arg metadata and the kernel attribute metadata to /// the function metadata. @@ -4678,7 +4673,6 @@ class CodeGenFunction : public CodeGenTypeCache { struct MultiVersionResolverOption { llvm::Function *Function; - FunctionDecl *FD; struct Conds { StringRef Architecture; llvm::SmallVector Features; @@ -4812,7 +4806,8 @@ inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, // Otherwise, it should be an alloca instruction, as set up in save(). auto alloca = cast(value.getPointer()); - return CGF.Builder.CreateAlignedLoad(alloca, alloca->getAlign()); + return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca, + alloca->getAlign()); } } // end namespace CodeGen diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4bf339786d42..f719f009ea99 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -978,20 +978,14 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM, if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO())) return true; - const auto &CGOpts = CGM.getCodeGenOpts(); - llvm::Reloc::Model RM = CGOpts.RelocationModel; - const auto &LOpts = CGM.getLangOpts(); - - if (TT.isOSBinFormatMachO()) { - if (RM == llvm::Reloc::Static) - return true; - return GV->isStrongDefinitionForLinker(); - } - // Only handle COFF and ELF for now. if (!TT.isOSBinFormatELF()) return false; + // If this is not an executable, don't assume anything is local. + const auto &CGOpts = CGM.getCodeGenOpts(); + llvm::Reloc::Model RM = CGOpts.RelocationModel; + const auto &LOpts = CGM.getLangOpts(); if (RM != llvm::Reloc::Static && !LOpts.PIE) { // On ELF, if -fno-semantic-interposition is specified and the target // supports local aliases, there will be neither CC1 @@ -1175,18 +1169,13 @@ static void AppendTargetMangling(const CodeGenModule &CGM, } } -// Returns true if GD is a function/var decl with internal linkage and +// Returns true if GD is a function decl with internal linkage and // needs a unique suffix after the mangled name. static bool isUniqueInternalLinkageDecl(GlobalDecl GD, CodeGenModule &CGM) { const Decl *D = GD.getDecl(); - if (!CGM.getModuleNameHash().empty() && - ((isa(D) && - CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage) || - (isa(D) && CGM.getContext().GetGVALinkageForVariable( - cast(D)) == GVA_Internal))) - return true; - return false; + return !CGM.getModuleNameHash().empty() && isa(D) && + (CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage); } static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, @@ -4267,9 +4256,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, D->getType()->isCUDADeviceBuiltinTextureType()); if (getLangOpts().CUDA && (IsCUDASharedVar || IsCUDAShadowVar || IsCUDADeviceShadowVar)) - Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy)); + Init = llvm::UndefValue::get(getTypes().ConvertTypeForMem(ASTTy)); else if (D->hasAttr()) - Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy)); + Init = llvm::UndefValue::get(getTypes().ConvertTypeForMem(ASTTy)); else if (!InitExpr) { // This is a tentative definition; tentative definitions are // implicitly initialized with { 0 }. @@ -6263,15 +6252,16 @@ llvm::SanitizerStatReport &CodeGenModule::getSanStats() { return *SanStats; } + llvm::Value * CodeGenModule::createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF) { llvm::Constant *C = ConstantEmitter(CGF).emitAbstract(E, E->getType()); - auto SamplerT = getOpenCLRuntime().getSamplerType(E->getType().getTypePtr()); - auto FTy = llvm::FunctionType::get(SamplerT, {C->getType()}, false); - return CGF.Builder.CreateCall(CreateRuntimeFunction(FTy, - "__translate_sampler_initializer"), - {C}); + auto *SamplerT = getOpenCLRuntime().getSamplerType(E->getType().getTypePtr()); + auto *FTy = llvm::FunctionType::get(SamplerT, {C->getType()}, false); + auto *Call = CGF.EmitRuntimeCall( + CreateRuntimeFunction(FTy, "__translate_sampler_initializer"), {C}); + return Call; } CharUnits CodeGenModule::getNaturalPointeeTypeAlignment( diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 6ece8566ac08..e0cbcb238d1c 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -651,7 +651,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( // for consistency. llvm::Value *This = ThisAddr.getPointer(); llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy()); - Ptr = Builder.CreateInBoundsGEP(Ptr, Adj); + Ptr = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), Ptr, Adj); This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted"); ThisPtrForCall = This; @@ -755,7 +755,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( VFPAddr = CGF.Builder.CreateBitCast( VFPAddr, FTy->getPointerTo()->getPointerTo()); VirtualFn = CGF.Builder.CreateAlignedLoad( - VFPAddr, CGF.getPointerAlign(), "memptr.virtualfn"); + FTy->getPointerTo(), VFPAddr, CGF.getPointerAlign(), + "memptr.virtualfn"); } } assert(VirtualFn && "Virtual fuction pointer not created!"); @@ -858,8 +859,8 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress( Base = Builder.CreateElementBitCast(Base, CGF.Int8Ty); // Apply the offset, which we assume is non-null. - llvm::Value *Addr = - Builder.CreateInBoundsGEP(Base.getPointer(), MemPtr, "memptr.offset"); + llvm::Value *Addr = Builder.CreateInBoundsGEP( + Base.getElementType(), Base.getPointer(), MemPtr, "memptr.offset"); // Cast the address to the appropriate pointer type, adopting the // address space of the base pointer. @@ -1254,13 +1255,13 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, // Track back to entry -2 and pull out the offset there. llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64( VTable, -2, "complete-offset.ptr"); - llvm::Value *Offset = - CGF.Builder.CreateAlignedLoad(OffsetPtr, CGF.getPointerAlign()); + llvm::Value *Offset = CGF.Builder.CreateAlignedLoad(CGF.IntPtrTy, OffsetPtr, CGF.getPointerAlign()); // Apply the offset. llvm::Value *CompletePtr = CGF.Builder.CreateBitCast(Ptr.getPointer(), CGF.Int8PtrTy); - CompletePtr = CGF.Builder.CreateInBoundsGEP(CompletePtr, Offset); + CompletePtr = + CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, CompletePtr, Offset); // If we're supposed to call the global delete, make sure we do so // even if the destructor throws. @@ -1467,7 +1468,8 @@ llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF, // Load the type info. Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL); } - return CGF.Builder.CreateAlignedLoad(Value, CGF.getPointerAlign()); + return CGF.Builder.CreateAlignedLoad(StdTypeInfoPtrTy, Value, + CGF.getPointerAlign()); } bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, @@ -1535,7 +1537,7 @@ llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, OffsetToTop = CGF.Builder.CreateConstInBoundsGEP1_32(/*Type=*/nullptr, VTable, -2U); OffsetToTop = CGF.Builder.CreateAlignedLoad( - OffsetToTop, CharUnits::fromQuantity(4), "offset.to.top"); + CGM.Int32Ty, OffsetToTop, CharUnits::fromQuantity(4), "offset.to.top"); } else { llvm::Type *PtrDiffLTy = CGF.ConvertType(CGF.getContext().getPointerDiffType()); @@ -1547,12 +1549,12 @@ llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, // Get the offset-to-top from the vtable. OffsetToTop = CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL); OffsetToTop = CGF.Builder.CreateAlignedLoad( - OffsetToTop, CGF.getPointerAlign(), "offset.to.top"); + PtrDiffLTy, OffsetToTop, CGF.getPointerAlign(), "offset.to.top"); } // Finally, add the offset to the pointer. llvm::Value *Value = ThisAddr.getPointer(); Value = CGF.EmitCastToVoidPtr(Value); - Value = CGF.Builder.CreateInBoundsGEP(Value, OffsetToTop); + Value = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, Value, OffsetToTop); return CGF.Builder.CreateBitCast(Value, DestLTy); } @@ -1582,12 +1584,13 @@ ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr, CGF.Int32Ty->getPointerTo()); VBaseOffset = CGF.Builder.CreateAlignedLoad( - VBaseOffsetPtr, CharUnits::fromQuantity(4), "vbase.offset"); + CGF.Int32Ty, VBaseOffsetPtr, CharUnits::fromQuantity(4), + "vbase.offset"); } else { VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr, CGM.PtrDiffTy->getPointerTo()); VBaseOffset = CGF.Builder.CreateAlignedLoad( - VBaseOffsetPtr, CGF.getPointerAlign(), "vbase.offset"); + CGM.PtrDiffTy, VBaseOffsetPtr, CGF.getPointerAlign(), "vbase.offset"); } return VBaseOffset; } @@ -1848,7 +1851,8 @@ llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); // And load the address point from the VTT. - return CGF.Builder.CreateAlignedLoad(VTT, CGF.getPointerAlign()); + return CGF.Builder.CreateAlignedLoad(CGF.VoidPtrTy, VTT, + CGF.getPointerAlign()); } llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( @@ -1923,7 +1927,8 @@ CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *VTableSlotPtr = CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn"); VFuncLoad = - CGF.Builder.CreateAlignedLoad(VTableSlotPtr, CGF.getPointerAlign()); + CGF.Builder.CreateAlignedLoad(Ty->getPointerTo(), VTableSlotPtr, + CGF.getPointerAlign()); } // Add !invariant.load md to virtual function load to indicate that @@ -2068,7 +2073,8 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, CGF.Int32Ty->getPointerTo()); Offset = - CGF.Builder.CreateAlignedLoad(OffsetPtr, CharUnits::fromQuantity(4)); + CGF.Builder.CreateAlignedLoad(CGF.Int32Ty, OffsetPtr, + CharUnits::fromQuantity(4)); } else { llvm::Type *PtrDiffTy = CGF.ConvertType(CGF.getContext().getPointerDiffType()); @@ -2077,10 +2083,12 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); // Load the adjustment offset from the vtable. - Offset = CGF.Builder.CreateAlignedLoad(OffsetPtr, CGF.getPointerAlign()); + Offset = CGF.Builder.CreateAlignedLoad(PtrDiffTy, OffsetPtr, + CGF.getPointerAlign()); } // Adjust our pointer. - ResultPtr = CGF.Builder.CreateInBoundsGEP(V.getPointer(), Offset); + ResultPtr = CGF.Builder.CreateInBoundsGEP( + V.getElementType(), V.getPointer(), Offset); } else { ResultPtr = V.getPointer(); } @@ -2940,7 +2948,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs( llvm::Value *Val = Var; if (VD->getType()->isReferenceType()) { CharUnits Align = CGM.getContext().getDeclAlign(VD); - Val = Builder.CreateAlignedLoad(Val, Align); + Val = Builder.CreateAlignedLoad(Var->getValueType(), Var, Align); } if (Val->getType() != Wrapper->getReturnType()) Val = Builder.CreatePointerBitCastOrAddrSpaceCast( diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index cb0dc1d5d717..f2a350cf9087 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -937,7 +937,8 @@ MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value, llvm::Value *Offset = GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase); - llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(Value.getPointer(), Offset); + llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP( + Value.getElementType(), Value.getPointer(), Offset); CharUnits VBaseAlign = CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase); return std::make_tuple(Address(Ptr, VBaseAlign), Offset, PolymorphicBase); @@ -1219,7 +1220,8 @@ void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers( if (!Int8This) Int8This = Builder.CreateBitCast(getThisValue(CGF), CGF.Int8Ty->getPointerTo(AS)); - llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset); + llvm::Value *VtorDispPtr = + Builder.CreateInBoundsGEP(CGF.Int8Ty, Int8This, VBaseOffset); // vtorDisp is always the 32-bits before the vbase in the class layout. VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4); VtorDispPtr = Builder.CreateBitCast( @@ -1457,8 +1459,8 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( const CXXRecordDecl *VBase = ML.VBase; llvm::Value *VBaseOffset = GetVirtualBaseClassOffset(CGF, Result, Derived, VBase); - llvm::Value *VBasePtr = - CGF.Builder.CreateInBoundsGEP(Result.getPointer(), VBaseOffset); + llvm::Value *VBasePtr = CGF.Builder.CreateInBoundsGEP( + Result.getElementType(), Result.getPointer(), VBaseOffset); CharUnits VBaseAlign = CGF.CGM.getVBaseAlignment(Result.getAlignment(), Derived, VBase); Result = Address(VBasePtr, VBaseAlign); @@ -1911,12 +1913,13 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, SourceLocation Loc) { CGBuilderTy &Builder = CGF.Builder; - Ty = Ty->getPointerTo()->getPointerTo(); + Ty = Ty->getPointerTo(); Address VPtr = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true); auto *MethodDecl = cast(GD.getDecl()); - llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty, MethodDecl->getParent()); + llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty->getPointerTo(), + MethodDecl->getParent()); MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext(); MethodVFTableLocation ML = VFTContext.getMethodVFTableLocation(GD); @@ -1944,7 +1947,7 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *VFuncPtr = Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn"); - VFunc = Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); + VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.getPointerAlign()); } CGCallee Callee(GD, VFunc); @@ -2078,7 +2081,8 @@ MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn"); llvm::Value *Callee = - CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); + CGF.Builder.CreateAlignedLoad(ThunkTy->getPointerTo(), VFuncPtr, + CGF.getPointerAlign()); CGF.EmitMustTailThunk(MD, getThisValue(CGF), {ThunkTy, Callee}); @@ -2211,7 +2215,7 @@ llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF, GetVBaseOffsetFromVBPtr(CGF, Address(V, CGF.getPointerAlign()), -TA.Virtual.Microsoft.VBPtrOffset, TA.Virtual.Microsoft.VBOffsetOffset, &VBPtr); - V = CGF.Builder.CreateInBoundsGEP(VBPtr, VBaseOffset); + V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, VBPtr, VBaseOffset); } } @@ -2243,7 +2247,7 @@ MicrosoftCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret, llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(CGF, Ret, RA.Virtual.Microsoft.VBPtrOffset, IntSize * RA.Virtual.Microsoft.VBIndex, &VBPtr); - V = CGF.Builder.CreateInBoundsGEP(VBPtr, VBaseOffset); + V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, VBPtr, VBaseOffset); } if (RA.NonVirtual) @@ -3008,8 +3012,8 @@ MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, CGBuilderTy &Builder = CGF.Builder; // Load the vbtable pointer from the vbptr in the instance. This = Builder.CreateElementBitCast(This, CGM.Int8Ty); - llvm::Value *VBPtr = - Builder.CreateInBoundsGEP(This.getPointer(), VBPtrOffset, "vbptr"); + llvm::Value *VBPtr = Builder.CreateInBoundsGEP( + This.getElementType(), This.getPointer(), VBPtrOffset, "vbptr"); if (VBPtrOut) *VBPtrOut = VBPtr; VBPtr = Builder.CreateBitCast(VBPtr, CGM.Int32Ty->getPointerTo(0)->getPointerTo(This.getAddressSpace())); @@ -3022,7 +3026,8 @@ MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, VBPtrAlign = CGF.getPointerAlign(); } - llvm::Value *VBTable = Builder.CreateAlignedLoad(VBPtr, VBPtrAlign, "vbtable"); + llvm::Value *VBTable = Builder.CreateAlignedLoad( + CGM.Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign, "vbtable"); // Translate from byte offset to table index. It improves analyzability. llvm::Value *VBTableIndex = Builder.CreateAShr( @@ -3030,10 +3035,11 @@ MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, "vbtindex", /*isExact=*/true); // Load an i32 offset from the vb-table. - llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex); + llvm::Value *VBaseOffs = + Builder.CreateInBoundsGEP(CGM.Int32Ty, VBTable, VBTableIndex); VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0)); - return Builder.CreateAlignedLoad(VBaseOffs, CharUnits::fromQuantity(4), - "vbase_offs"); + return Builder.CreateAlignedLoad(CGM.Int32Ty, VBaseOffs, + CharUnits::fromQuantity(4), "vbase_offs"); } // Returns an adjusted base cast to i8*, since we do more address arithmetic on @@ -3080,7 +3086,8 @@ llvm::Value *MicrosoftCXXABI::AdjustVirtualBase( llvm::Value *VBPtr = nullptr; llvm::Value *VBaseOffs = GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr); - llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs); + llvm::Value *AdjustedBase = + Builder.CreateInBoundsGEP(CGM.Int8Ty, VBPtr, VBaseOffs); // Merge control flow with the case where we didn't have to adjust. if (VBaseAdjustBB) { @@ -3132,7 +3139,8 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress( Addr = Builder.CreateBitCast(Addr, CGF.Int8Ty->getPointerTo(AS)); // Apply the offset, which we assume is non-null. - Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset, "memptr.offset"); + Addr = Builder.CreateInBoundsGEP(CGF.Int8Ty, Addr, FieldOffset, + "memptr.offset"); // Cast the address to the appropriate pointer type, adopting the address // space of the base pointer. @@ -3294,9 +3302,10 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( Mapping->getAggregateElement(cast(VBIndex)); } else { llvm::Value *Idxs[] = {getZeroInt(), VBIndex}; - VirtualBaseAdjustmentOffset = - Builder.CreateAlignedLoad(Builder.CreateInBoundsGEP(VDispMap, Idxs), - CharUnits::fromQuantity(4)); + VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad( + CGM.IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(), + VDispMap, Idxs), + CharUnits::fromQuantity(4)); } DstVBIndexEqZero = @@ -3426,7 +3435,7 @@ CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer( if (NonVirtualBaseAdjustment) { // Apply the adjustment and cast back to the original struct type. llvm::Value *Ptr = Builder.CreateBitCast(ThisPtrForCall, CGF.Int8PtrTy); - Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment); + Ptr = Builder.CreateInBoundsGEP(CGF.Int8Ty, Ptr, NonVirtualBaseAdjustment); ThisPtrForCall = Builder.CreateBitCast(Ptr, ThisPtrForCall->getType(), "this.adjusted"); } diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index f4427967da9f..c3df36fc1ea2 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5946,7 +5946,7 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, Address reg_top_p = CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index, "reg_top_p"); reg_top = CGF.Builder.CreateLoad(reg_top_p, "reg_top"); - Address BaseAddr(CGF.Builder.CreateInBoundsGEP(reg_top, reg_offs), + Address BaseAddr(CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, reg_top, reg_offs), CharUnits::fromQuantity(IsFPR ? 16 : 8)); Address RegAddr = Address::invalid(); llvm::Type *MemTy = CGF.ConvertTypeForMem(Ty); @@ -6044,8 +6044,8 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, StackSize = TySize.alignTo(StackSlotSize); llvm::Value *StackSizeC = CGF.Builder.getSize(StackSize); - llvm::Value *NewStack = - CGF.Builder.CreateInBoundsGEP(OnStackPtr, StackSizeC, "new_stack"); + llvm::Value *NewStack = CGF.Builder.CreateInBoundsGEP( + CGF.Int8Ty, OnStackPtr, StackSizeC, "new_stack"); // Write the new value of __stack for the next call to va_arg CGF.Builder.CreateStore(NewStack, stack_p); @@ -7218,6 +7218,18 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { case Builtin::BI__builtin_isnan: TDCBits = 0xf; break; + case Builtin::BIfinite: + case Builtin::BI__finite: + case Builtin::BIfinitef: + case Builtin::BI__finitef: + case Builtin::BIfinitel: + case Builtin::BI__finitel: + case Builtin::BI__builtin_isfinite: + TDCBits = 0xfc0; + break; + case Builtin::BI__builtin_isinf: + TDCBits = 0x30; + break; default: break; } diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp index d33055739080..f28c23a59940 100644 --- a/clang/lib/Driver/Compilation.cpp +++ b/clang/lib/Driver/Compilation.cpp @@ -170,10 +170,11 @@ int Compilation::ExecuteCommand(const Command &C, // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the // output stream. - if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) { + if (getDriver().CCPrintOptions && + !getDriver().CCPrintOptionsFilename.empty()) { std::error_code EC; OwnedStream.reset(new llvm::raw_fd_ostream( - getDriver().CCPrintOptionsFilename, EC, + getDriver().CCPrintOptionsFilename.c_str(), EC, llvm::sys::fs::OF_Append | llvm::sys::fs::OF_Text)); if (EC) { getDriver().Diag(diag::err_drv_cc_print_options_failure) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index ebc917171656..cb7e99a8e45e 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -135,14 +135,13 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, : Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None), ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT), - DriverTitle(Title), CCPrintStatReportFilename(nullptr), - CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr), - CCLogDiagnosticsFilename(nullptr), CCCPrintBindings(false), - CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false), - CCGenDiagnostics(false), CCPrintProcessStats(false), - TargetTriple(TargetTriple), CCCGenericGCCName(""), Saver(Alloc), - CheckInputsExist(true), GenReproducer(false), - SuppressMissingInputWarning(false) { + DriverTitle(Title), CCPrintStatReportFilename(), CCPrintOptionsFilename(), + CCPrintHeadersFilename(), CCLogDiagnosticsFilename(), + CCCPrintBindings(false), CCPrintOptions(false), CCPrintHeaders(false), + CCLogDiagnostics(false), CCGenDiagnostics(false), + CCPrintProcessStats(false), TargetTriple(TargetTriple), + CCCGenericGCCName(""), Saver(Alloc), CheckInputsExist(true), + GenReproducer(false), SuppressMissingInputWarning(false) { // Provide a sane fallback if no VFS is specified. if (!this->VFS) this->VFS = llvm::vfs::getRealFileSystem(); @@ -1840,6 +1839,15 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { return false; } + if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) { + if (auto RuntimePath = TC.getRuntimePath()) { + llvm::outs() << *RuntimePath << '\n'; + return false; + } + llvm::outs() << TC.getCompilerRTPath() << '\n'; + return false; + } + // FIXME: The following handlers should use a callback mechanism, we don't // know what the client would like to do. if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) { @@ -3102,8 +3110,16 @@ class OffloadingActionBuilder final { } // By default, we produce an action for each device arch. - for (Action *&A : OpenMPDeviceActions) + for (unsigned I = 0; I < ToolChains.size(); ++I) { + Action *&A = OpenMPDeviceActions[I]; + // AMDGPU does not support linking of object files, so we skip + // assemble and backend actions to produce LLVM IR. + if (ToolChains[I]->getTriple().isAMDGCN() && + (CurPhase == phases::Assemble || CurPhase == phases::Backend)) + continue; + A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A); + } return ABRT_Success; } @@ -4056,7 +4072,7 @@ void Driver::BuildJobs(Compilation &C) const { else LinkingOutput = getDefaultImageName(); - if (!CCPrintStatReportFilename) { + if (CCPrintStatReportFilename.empty()) { using namespace llvm; // Human readable output. outs() << sys::path::filename(Cmd.getExecutable()) << ": " @@ -4079,8 +4095,9 @@ void Driver::BuildJobs(Compilation &C) const { << '\n'; Out.flush(); std::error_code EC; - llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC, - llvm::sys::fs::OF_Append); + llvm::raw_fd_ostream OS(CCPrintStatReportFilename.c_str(), EC, + llvm::sys::fs::OF_Append | + llvm::sys::fs::OF_Text); if (EC) return; auto L = OS.lock(); diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index e6a6fe2cb062..e32bbae99fe8 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -735,129 +735,9 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: { - // FIXME: Factor into subclasses. llvm::Triple Triple = getTriple(); - bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb || - getTriple().getArch() == llvm::Triple::thumbeb; - - // Handle pseudo-target flags '-mlittle-endian'/'-EL' and - // '-mbig-endian'/'-EB'. - if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, - options::OPT_mbig_endian)) { - IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); - } - - // Thumb2 is the default for V7 on Darwin. - // - // FIXME: Thumb should just be another -target-feaure, not in the triple. - StringRef MCPU, MArch; - if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) - MCPU = A->getValue(); - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) - MArch = A->getValue(); - std::string CPU = - Triple.isOSBinFormatMachO() - ? tools::arm::getARMCPUForMArch(MArch, Triple).str() - : tools::arm::getARMTargetCPU(MCPU, MArch, Triple); - StringRef Suffix = - tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple); - bool IsMProfile = ARM::parseArchProfile(Suffix) == ARM::ProfileKind::M; - bool ThumbDefault = IsMProfile || (ARM::parseArchVersion(Suffix) == 7 && - getTriple().isOSBinFormatMachO()); - // FIXME: this is invalid for WindowsCE - if (getTriple().isOSWindows()) - ThumbDefault = true; - std::string ArchName; - if (IsBigEndian) - ArchName = "armeb"; - else - ArchName = "arm"; - - // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for - // M-Class CPUs/architecture variants, which is not supported. - bool ARMModeRequested = !Args.hasFlag(options::OPT_mthumb, - options::OPT_mno_thumb, ThumbDefault); - if (IsMProfile && ARMModeRequested) { - if (!MCPU.empty()) - getDriver().Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM"; - else - getDriver().Diag(diag::err_arch_unsupported_isa) - << tools::arm::getARMArch(MArch, getTriple()) << "ARM"; - } - - // Check to see if an explicit choice to use thumb has been made via - // -mthumb. For assembler files we must check for -mthumb in the options - // passed to the assembler via -Wa or -Xassembler. - bool IsThumb = false; - if (InputType != types::TY_PP_Asm) - IsThumb = Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, - ThumbDefault); - else { - // Ideally we would check for these flags in - // CollectArgsForIntegratedAssembler but we can't change the ArchName at - // that point. - llvm::StringRef WaMArch, WaMCPU; - for (const auto *A : - Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { - for (StringRef Value : A->getValues()) { - // There is no assembler equivalent of -mno-thumb, -marm, or -mno-arm. - if (Value == "-mthumb") - IsThumb = true; - else if (Value.startswith("-march=")) - WaMArch = Value.substr(7); - else if (Value.startswith("-mcpu=")) - WaMCPU = Value.substr(6); - } - } - - if (WaMCPU.size() || WaMArch.size()) { - // The way this works means that we prefer -Wa,-mcpu's architecture - // over -Wa,-march. Which matches the compiler behaviour. - Suffix = tools::arm::getLLVMArchSuffixForARM(WaMCPU, WaMArch, Triple); - } - } - // Assembly files should start in ARM mode, unless arch is M-profile, or - // -mthumb has been passed explicitly to the assembler. Windows is always - // thumb. - if (IsThumb || IsMProfile || getTriple().isOSWindows()) { - if (IsBigEndian) - ArchName = "thumbeb"; - else - ArchName = "thumb"; - } - Triple.setArchName(ArchName + Suffix.str()); - - bool isHardFloat = - (arm::getARMFloatABI(getDriver(), Triple, Args) == arm::FloatABI::Hard); - switch (Triple.getEnvironment()) { - case Triple::GNUEABI: - case Triple::GNUEABIHF: - Triple.setEnvironment(isHardFloat ? Triple::GNUEABIHF : Triple::GNUEABI); - break; - case Triple::EABI: - case Triple::EABIHF: - Triple.setEnvironment(isHardFloat ? Triple::EABIHF : Triple::EABI); - break; - case Triple::MuslEABI: - case Triple::MuslEABIHF: - Triple.setEnvironment(isHardFloat ? Triple::MuslEABIHF - : Triple::MuslEABI); - break; - default: { - arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple); - if (DefaultABI != arm::FloatABI::Invalid && - isHardFloat != (DefaultABI == arm::FloatABI::Hard)) { - Arg *ABIArg = - Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, - options::OPT_mfloat_abi_EQ); - assert(ABIArg && "Non-default float abi expected to be from arg"); - D.Diag(diag::err_drv_unsupported_opt_for_target) - << ABIArg->getAsString(Args) << Triple.getTriple(); - } - break; - } - } - + tools::arm::setArchNameInTriple(getDriver(), Args, InputType, Triple); + tools::arm::setFloatABIInTriple(getDriver(), Args, Triple); return Triple.getTriple(); } } @@ -1018,6 +898,29 @@ void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs, } } +std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const { + std::error_code EC; + int MaxVersion = 0; + std::string MaxVersionString; + SmallString<128> Path(IncludePath); + llvm::sys::path::append(Path, "c++"); + for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE; + !EC && LI != LE; LI = LI.increment(EC)) { + StringRef VersionText = llvm::sys::path::filename(LI->path()); + int Version; + if (VersionText[0] == 'v' && + !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) { + if (Version > MaxVersion) { + MaxVersion = Version; + MaxVersionString = std::string(VersionText); + } + } + } + if (!MaxVersion) + return ""; + return MaxVersionString; +} + void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { // Header search paths should be handled by each of the subclasses. @@ -1036,7 +939,8 @@ void ToolChain::AddClangCXXStdlibIsystemArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem); - if (!DriverArgs.hasArg(options::OPT_nostdincxx)) + if (!DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx, + options::OPT_nostdlibinc)) for (const auto &P : DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem)) addSystemInclude(DriverArgs, CC1Args, P); diff --git a/clang/lib/Driver/ToolChains/AIX.h b/clang/lib/Driver/ToolChains/AIX.h index c6aac09ddfac..1534af950c88 100644 --- a/clang/lib/Driver/ToolChains/AIX.h +++ b/clang/lib/Driver/ToolChains/AIX.h @@ -77,6 +77,10 @@ class LLVM_LIBRARY_VISIBILITY AIX : public ToolChain { // Set default DWARF version to 3 for now as latest AIX OS supports version 3. unsigned GetDefaultDwarfVersion() const override { return 3; } + llvm::DebuggerKind getDefaultDebuggerTuning() const override { + return llvm::DebuggerKind::DBX; + } + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index d6cf5a868555..2ce040cfca01 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -186,6 +186,12 @@ RocmInstallationDetector::getInstallationPathCandidates() { ROCmSearchDirs.emplace_back(RocmPathArg.str()); DoPrintROCmSearchDirs(); return ROCmSearchDirs; + } else if (const char *RocmPathEnv = ::getenv("ROCM_PATH")) { + if (!StringRef(RocmPathEnv).empty()) { + ROCmSearchDirs.emplace_back(RocmPathEnv); + DoPrintROCmSearchDirs(); + return ROCmSearchDirs; + } } // Try to find relative to the compiler binary. @@ -247,6 +253,43 @@ RocmInstallationDetector::getInstallationPathCandidates() { ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/rocm", /*StrictChecking=*/true); + + // Find the latest /opt/rocm-{release} directory. + std::error_code EC; + std::string LatestROCm; + llvm::VersionTuple LatestVer; + // Get ROCm version from ROCm directory name. + auto GetROCmVersion = [](StringRef DirName) { + llvm::VersionTuple V; + std::string VerStr = DirName.drop_front(strlen("rocm-")).str(); + // The ROCm directory name follows the format of + // rocm-{major}.{minor}.{subMinor}[-{build}] + std::replace(VerStr.begin(), VerStr.end(), '-', '.'); + V.tryParse(VerStr); + return V; + }; + for (llvm::vfs::directory_iterator + File = D.getVFS().dir_begin(D.SysRoot + "/opt", EC), + FileEnd; + File != FileEnd && !EC; File.increment(EC)) { + llvm::StringRef FileName = llvm::sys::path::filename(File->path()); + if (!FileName.startswith("rocm-")) + continue; + if (LatestROCm.empty()) { + LatestROCm = FileName.str(); + LatestVer = GetROCmVersion(LatestROCm); + continue; + } + auto Ver = GetROCmVersion(FileName); + if (LatestVer < Ver) { + LatestROCm = FileName.str(); + LatestVer = Ver; + } + } + if (!LatestROCm.empty()) + ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/" + LatestROCm, + /*StrictChecking=*/true); + DoPrintROCmSearchDirs(); return ROCmSearchDirs; } diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp index 53d25c05b623..38abd2f48368 100644 --- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp @@ -161,6 +161,11 @@ void AMDGCN::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, // Each command outputs different files. const char *LLVMLinkCommand = constructLLVMLinkCommand(C, JA, Inputs, Args, GPUArch, Prefix); + + // Produce readable assembly if save-temps is enabled. + if (C.getDriver().isSaveTempsEnabled()) + constructLlcCommand(C, JA, Inputs, Args, GPUArch, Prefix, LLVMLinkCommand, + /*OutputIsAsm=*/true); const char *LlcCommand = constructLlcCommand(C, JA, Inputs, Args, GPUArch, Prefix, LLVMLinkCommand); constructLldCommand(C, JA, Inputs, Output, Args, LlcCommand); @@ -189,7 +194,6 @@ void AMDGPUOpenMPToolChain::addClangTargetOptions( CC1Args.push_back("-target-cpu"); CC1Args.push_back(DriverArgs.MakeArgStringRef(GpuArch)); CC1Args.push_back("-fcuda-is-device"); - CC1Args.push_back("-emit-llvm-bc"); if (DriverArgs.hasArg(options::OPT_nogpulib)) return; diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index d0606eb882f1..952ebf9dcbe9 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -166,6 +166,132 @@ arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args) { return ReadTPMode::Soft; } +void arm::setArchNameInTriple(const Driver &D, const ArgList &Args, + types::ID InputType, llvm::Triple &Triple) { + StringRef MCPU, MArch; + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + MCPU = A->getValue(); + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + MArch = A->getValue(); + + std::string CPU = Triple.isOSBinFormatMachO() + ? tools::arm::getARMCPUForMArch(MArch, Triple).str() + : tools::arm::getARMTargetCPU(MCPU, MArch, Triple); + StringRef Suffix = tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple); + + bool IsBigEndian = Triple.getArch() == llvm::Triple::armeb || + Triple.getArch() == llvm::Triple::thumbeb; + // Handle pseudo-target flags '-mlittle-endian'/'-EL' and + // '-mbig-endian'/'-EB'. + if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, + options::OPT_mbig_endian)) { + IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); + } + std::string ArchName = IsBigEndian ? "armeb" : "arm"; + + // FIXME: Thumb should just be another -target-feaure, not in the triple. + bool IsMProfile = + llvm::ARM::parseArchProfile(Suffix) == llvm::ARM::ProfileKind::M; + bool ThumbDefault = IsMProfile || + // Thumb2 is the default for V7 on Darwin. + (llvm::ARM::parseArchVersion(Suffix) == 7 && + Triple.isOSBinFormatMachO()) || + // FIXME: this is invalid for WindowsCE + Triple.isOSWindows(); + + // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for + // M-Class CPUs/architecture variants, which is not supported. + bool ARMModeRequested = + !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault); + if (IsMProfile && ARMModeRequested) { + if (MCPU.size()) + D.Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM"; + else + D.Diag(diag::err_arch_unsupported_isa) + << tools::arm::getARMArch(MArch, Triple) << "ARM"; + } + + // Check to see if an explicit choice to use thumb has been made via + // -mthumb. For assembler files we must check for -mthumb in the options + // passed to the assembler via -Wa or -Xassembler. + bool IsThumb = false; + if (InputType != types::TY_PP_Asm) + IsThumb = + Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault); + else { + // Ideally we would check for these flags in + // CollectArgsForIntegratedAssembler but we can't change the ArchName at + // that point. + llvm::StringRef WaMArch, WaMCPU; + for (const auto *A : + Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { + for (StringRef Value : A->getValues()) { + // There is no assembler equivalent of -mno-thumb, -marm, or -mno-arm. + if (Value == "-mthumb") + IsThumb = true; + else if (Value.startswith("-march=")) + WaMArch = Value.substr(7); + else if (Value.startswith("-mcpu=")) + WaMCPU = Value.substr(6); + } + } + + if (WaMCPU.size() || WaMArch.size()) { + // The way this works means that we prefer -Wa,-mcpu's architecture + // over -Wa,-march. Which matches the compiler behaviour. + Suffix = tools::arm::getLLVMArchSuffixForARM(WaMCPU, WaMArch, Triple); + } + } + + // Assembly files should start in ARM mode, unless arch is M-profile, or + // -mthumb has been passed explicitly to the assembler. Windows is always + // thumb. + if (IsThumb || IsMProfile || Triple.isOSWindows()) { + if (IsBigEndian) + ArchName = "thumbeb"; + else + ArchName = "thumb"; + } + Triple.setArchName(ArchName + Suffix.str()); +} + +void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args, + llvm::Triple &Triple) { + bool isHardFloat = + (arm::getARMFloatABI(D, Triple, Args) == arm::FloatABI::Hard); + + switch (Triple.getEnvironment()) { + case llvm::Triple::GNUEABI: + case llvm::Triple::GNUEABIHF: + Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHF + : llvm::Triple::GNUEABI); + break; + case llvm::Triple::EABI: + case llvm::Triple::EABIHF: + Triple.setEnvironment(isHardFloat ? llvm::Triple::EABIHF + : llvm::Triple::EABI); + break; + case llvm::Triple::MuslEABI: + case llvm::Triple::MuslEABIHF: + Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF + : llvm::Triple::MuslEABI); + break; + default: { + arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple); + if (DefaultABI != arm::FloatABI::Invalid && + isHardFloat != (DefaultABI == arm::FloatABI::Hard)) { + Arg *ABIArg = + Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, + options::OPT_mfloat_abi_EQ); + assert(ABIArg && "Non-default float abi expected to be from arg"); + D.Diag(diag::err_drv_unsupported_opt_for_target) + << ABIArg->getAsString(Args) << Triple.getTriple(); + } + break; + } + } +} + arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) { return arm::getARMFloatABI(TC.getDriver(), TC.getEffectiveTriple(), Args); } diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.h b/clang/lib/Driver/ToolChains/Arch/ARM.h index 02d91cdaee13..8e7c10ecd5d6 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.h +++ b/clang/lib/Driver/ToolChains/Arch/ARM.h @@ -51,7 +51,11 @@ FloatABI getDefaultFloatABI(const llvm::Triple &Triple); FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args); FloatABI getARMFloatABI(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); +void setFloatABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, + llvm::Triple &triple); ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args); +void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args, + types::ID InputType, llvm::Triple &Triple); bool useAAPCSForMachO(const llvm::Triple &T); void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 6ba65e25426e..da286542f6bb 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -404,7 +404,7 @@ shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime, /// master flag, -fexceptions and also language specific flags to enable/disable /// C++ and Objective-C exceptions. This makes it possible to for example /// disable C++ exceptions but enable Objective-C exceptions. -static void addExceptionArgs(const ArgList &Args, types::ID InputType, +static bool addExceptionArgs(const ArgList &Args, types::ID InputType, const ToolChain &TC, bool KernelOrKext, const ObjCRuntime &objcRuntime, ArgStringList &CmdArgs) { @@ -419,7 +419,7 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, Args.ClaimAllArgs(options::OPT_fno_objc_exceptions); Args.ClaimAllArgs(options::OPT_fcxx_exceptions); Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions); - return; + return false; } // See if the user explicitly enabled exceptions. @@ -462,6 +462,7 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, if (EH) CmdArgs.push_back("-fexceptions"); + return EH; } static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC, @@ -1051,6 +1052,9 @@ static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs, case llvm::DebuggerKind::SCE: CmdArgs.push_back("-debugger-tuning=sce"); break; + case llvm::DebuggerKind::DBX: + CmdArgs.push_back("-debugger-tuning=dbx"); + break; default: break; } @@ -2357,7 +2361,8 @@ void Clang::DumpCompilationDatabaseFragmentToDir( Twine(llvm::sys::path::filename(Input.getFilename())) + ".%%%%.json"); int FD; SmallString<256> TempPath; - Err = llvm::sys::fs::createUniqueFile(Path, FD, TempPath); + Err = llvm::sys::fs::createUniqueFile(Path, FD, TempPath, + llvm::sys::fs::OF_Text); if (Err) { Driver.Diag(diag::err_drv_compilationdatabase) << Path << Err.message(); return; @@ -3915,6 +3920,8 @@ static void renderDebugOptions(const ToolChain &TC, const Driver &D, DebuggerTuning = llvm::DebuggerKind::LLDB; else if (A->getOption().matches(options::OPT_gsce)) DebuggerTuning = llvm::DebuggerKind::SCE; + else if (A->getOption().matches(options::OPT_gdbx)) + DebuggerTuning = llvm::DebuggerKind::DBX; else DebuggerTuning = llvm::DebuggerKind::GDB; } @@ -4272,7 +4279,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) { - CmdArgs.push_back("-fsycl"); CmdArgs.push_back("-fsycl-is-device"); if (Arg *A = Args.getLastArg(options::OPT_sycl_std_EQ)) { @@ -4890,9 +4896,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_ffine_grained_bitfield_accesses, options::OPT_fno_fine_grained_bitfield_accesses); + Args.AddLastArg(CmdArgs, options::OPT_fexperimental_relative_cxx_abi_vtables, + options::OPT_fno_experimental_relative_cxx_abi_vtables); + // Handle segmented stacks. - if (Args.hasArg(options::OPT_fsplit_stack)) - CmdArgs.push_back("-split-stacks"); + if (Args.hasFlag(options::OPT_fsplit_stack, options::OPT_fno_split_stack, + false)) + CmdArgs.push_back("-fsplit-stack"); RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs, JA); @@ -4993,14 +5003,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // This is a coarse approximation of what llvm-gcc actually does, both // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more // complicated ways. - bool AsynchronousUnwindTables = + bool UnwindTables = Args.hasFlag(options::OPT_fasynchronous_unwind_tables, options::OPT_fno_asynchronous_unwind_tables, (TC.IsUnwindTablesDefault(Args) || TC.getSanitizerArgs().needsUnwindTables()) && !Freestanding); - if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables, - AsynchronousUnwindTables)) + UnwindTables = Args.hasFlag(options::OPT_funwind_tables, + options::OPT_fno_unwind_tables, UnwindTables); + if (UnwindTables) CmdArgs.push_back("-munwind-tables"); // Prepare `-aux-target-cpu` and `-aux-target-feature` unless @@ -5124,8 +5135,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (D.CCPrintHeaders && !D.CCGenDiagnostics) { CmdArgs.push_back("-header-include-file"); - CmdArgs.push_back(D.CCPrintHeadersFilename ? D.CCPrintHeadersFilename - : "-"); + CmdArgs.push_back(!D.CCPrintHeadersFilename.empty() + ? D.CCPrintHeadersFilename.c_str() + : "-"); CmdArgs.push_back("-sys-header-deps"); } Args.AddLastArg(CmdArgs, options::OPT_P); @@ -5133,8 +5145,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (D.CCLogDiagnostics && !D.CCGenDiagnostics) { CmdArgs.push_back("-diagnostic-log-file"); - CmdArgs.push_back(D.CCLogDiagnosticsFilename ? D.CCLogDiagnosticsFilename - : "-"); + CmdArgs.push_back(!D.CCLogDiagnosticsFilename.empty() + ? D.CCLogDiagnosticsFilename.c_str() + : "-"); } // Give the gen diagnostics more chances to succeed, by avoiding intentional @@ -5631,8 +5644,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) { StringRef S0 = A->getValue(), S = S0; unsigned Size, Offset = 0; - if (!Triple.isAArch64() && Triple.getArch() != llvm::Triple::x86 && - Triple.getArch() != llvm::Triple::x86_64) + if (!Triple.isAArch64() && !Triple.isRISCV() && !Triple.isX86()) D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args) << TripleStr; else if (S.consumeInteger(10, Size) || @@ -6061,8 +6073,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fapplication-extension"); // Handle GCC-style exception args. + bool EH = false; if (!C.getDriver().IsCLMode()) - addExceptionArgs(Args, InputType, TC, KernelOrKext, Runtime, CmdArgs); + EH = addExceptionArgs(Args, InputType, TC, KernelOrKext, Runtime, CmdArgs); // Handle exception personalities Arg *A = Args.getLastArg( @@ -6624,6 +6637,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, !TC.getTriple().isAndroid() && TC.useIntegratedAs())) CmdArgs.push_back("-faddrsig"); + if ((Triple.isOSBinFormatELF() || Triple.isOSBinFormatMachO()) && + (EH || UnwindTables || DebugInfoKind != codegenoptions::NoDebugInfo)) + CmdArgs.push_back("-D__GCC_HAVE_DWARF2_CFI_ASM=1"); + if (Arg *A = Args.getLastArg(options::OPT_fsymbol_partition_EQ)) { std::string Str = A->getAsString(Args); if (!TC.getTriple().isOSBinFormatELF()) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 62432b5b7576..6baf1d1acbb3 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -550,6 +550,8 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb"); else if (A->getOption().matches(options::OPT_gsce)) CmdArgs.push_back("-plugin-opt=-debugger-tune=sce"); + else if (A->getOption().matches(options::OPT_gdbx)) + CmdArgs.push_back("-plugin-opt=-debugger-tune=dbx"); else CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb"); } diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 91241ff9bd81..bc59b6beafc7 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -373,6 +373,18 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain); } + // If GlobalISel is enabled, pass it through to LLVM. + if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel, + options::OPT_fno_global_isel)) { + if (A->getOption().matches(options::OPT_fglobal_isel)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-global-isel"); + // Disable abort and fall back to SDAG silently. + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-global-isel-abort=0"); + } + } + Args.AddLastArg(CmdArgs, options::OPT_prebind); Args.AddLastArg(CmdArgs, options::OPT_noprebind); Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); @@ -1628,6 +1640,15 @@ getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver, return None; } +/// Returns the SDK name without the optional prefix that ends with a '.' or an +/// empty string otherwise. +static StringRef dropSDKNamePrefix(StringRef SDKName) { + size_t PrefixPos = SDKName.find('.'); + if (PrefixPos == StringRef::npos) + return ""; + return SDKName.substr(PrefixPos + 1); +} + /// Tries to infer the deployment target from the SDK specified by -isysroot /// (or SDKROOT). Uses the version specified in the SDKSettings.json file if /// it's available. @@ -1657,22 +1678,29 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args, if (Version.empty()) return None; - if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator")) - return DarwinPlatform::createFromSDK( - Darwin::IPhoneOS, Version, - /*IsSimulator=*/SDK.startswith("iPhoneSimulator")); - else if (SDK.startswith("MacOSX")) - return DarwinPlatform::createFromSDK(Darwin::MacOS, - getSystemOrSDKMacOSVersion(Version)); - else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) - return DarwinPlatform::createFromSDK( - Darwin::WatchOS, Version, - /*IsSimulator=*/SDK.startswith("WatchSimulator")); - else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator")) - return DarwinPlatform::createFromSDK( - Darwin::TvOS, Version, - /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); - return None; + auto CreatePlatformFromSDKName = + [&](StringRef SDK) -> Optional { + if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator")) + return DarwinPlatform::createFromSDK( + Darwin::IPhoneOS, Version, + /*IsSimulator=*/SDK.startswith("iPhoneSimulator")); + else if (SDK.startswith("MacOSX")) + return DarwinPlatform::createFromSDK(Darwin::MacOS, + getSystemOrSDKMacOSVersion(Version)); + else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) + return DarwinPlatform::createFromSDK( + Darwin::WatchOS, Version, + /*IsSimulator=*/SDK.startswith("WatchSimulator")); + else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator")) + return DarwinPlatform::createFromSDK( + Darwin::TvOS, Version, + /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); + return None; + }; + if (auto Result = CreatePlatformFromSDKName(SDK)) + return Result; + // The SDK can be an SDK variant with a name like `.`. + return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK)); } std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple, @@ -1928,7 +1956,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { if (SDK.size() > 0) { size_t StartVer = SDK.find_first_of("0123456789"); StringRef SDKName = SDK.slice(0, StartVer); - if (!SDKName.startswith(getPlatformFamily())) + if (!SDKName.startswith(getPlatformFamily()) && + !dropSDKNamePrefix(SDKName).startswith(getPlatformFamily())) getDriver().Diag(diag::warn_incompatible_sysroot) << SDKName << getPlatformFamily(); } diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 1a812589d473..bf2a19e7c54a 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -41,7 +41,10 @@ void Flang::AddPreprocessingOptions(const ArgList &Args, } void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { - Args.AddAllArgs(CmdArgs, options::OPT_module_dir); + Args.AddAllArgs(CmdArgs, + {options::OPT_module_dir, options::OPT_fdebug_module_writer, + options::OPT_fintrinsic_modules_path, options::OPT_pedantic, + options::OPT_std_EQ}); } void Flang::ConstructJob(Compilation &C, const JobAction &JA, diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp index d59bb6f8c3b0..c508af655ac2 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -409,8 +409,8 @@ void FreeBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, void FreeBSD::addLibStdCxxIncludePaths( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { - addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/4.2", "", "", - "", "", DriverArgs, CC1Args); + addLibStdCXXIncludePaths(getDriver().SysRoot + "/usr/include/c++/4.2", "", "", + DriverArgs, CC1Args); } void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp index 8e086010a984..17671b37ad1d 100644 --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -95,6 +95,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, std::string Dyld = D.DyldPrefix; if (SanArgs.needsAsanRt() && SanArgs.needsSharedRt()) Dyld += "asan/"; + if (SanArgs.needsHwasanRt() && SanArgs.needsSharedRt()) + Dyld += "hwasan/"; if (SanArgs.needsTsanRt() && SanArgs.needsSharedRt()) Dyld += "tsan/"; Dyld += "ld.so.1"; @@ -210,23 +212,41 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, .flag("+fsanitize=address") .flag("-fexceptions") .flag("+fno-exceptions")); + // HWASan has higher priority because we always want the instrumentated + // version. + Multilibs.push_back( + Multilib("hwasan", {}, {}, 4).flag("+fsanitize=hwaddress")); + // Use the hwasan+noexcept variant with HWASan and -fno-exceptions. + Multilibs.push_back(Multilib("hwasan+noexcept", {}, {}, 5) + .flag("+fsanitize=hwaddress") + .flag("-fexceptions") + .flag("+fno-exceptions")); // Use the relative vtables ABI. // TODO: Remove these multilibs once relative vtables are enabled by default // for Fuchsia. - Multilibs.push_back(Multilib("relative-vtables", {}, {}, 4) + Multilibs.push_back(Multilib("relative-vtables", {}, {}, 6) .flag("+fexperimental-relative-c++-abi-vtables")); - Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 5) + Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 7) .flag("+fexperimental-relative-c++-abi-vtables") .flag("-fexceptions") .flag("+fno-exceptions")); - Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 6) + Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 8) .flag("+fexperimental-relative-c++-abi-vtables") .flag("+fsanitize=address")); - Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 7) + Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 9) .flag("+fexperimental-relative-c++-abi-vtables") .flag("+fsanitize=address") .flag("-fexceptions") .flag("+fno-exceptions")); + Multilibs.push_back(Multilib("relative-vtables+hwasan", {}, {}, 10) + .flag("+fexperimental-relative-c++-abi-vtables") + .flag("+fsanitize=hwaddress")); + Multilibs.push_back(Multilib("relative-vtables+hwasan+noexcept", {}, {}, 11) + .flag("+fexperimental-relative-c++-abi-vtables") + .flag("+fsanitize=hwaddress") + .flag("-fexceptions") + .flag("+fno-exceptions")); + Multilibs.FilterOut([&](const Multilib &M) { std::vector RD = FilePaths(M); return std::all_of(RD.begin(), RD.end(), [&](std::string P) { @@ -239,6 +259,8 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true), "fexceptions", Flags); addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags); + addMultilibFlag(getSanitizerArgs().needsHwasanRt(), "fsanitize=hwaddress", + Flags); addMultilibFlag( Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables, @@ -343,7 +365,9 @@ void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, switch (GetCXXStdlibType(DriverArgs)) { case ToolChain::CST_Libcxx: { SmallString<128> P(getDriver().Dir); - llvm::sys::path::append(P, "..", "include", "c++", "v1"); + llvm::sys::path::append(P, "..", "include"); + std::string Version = detectLibcxxVersion(P); + llvm::sys::path::append(P, "c++", Version); addSystemInclude(DriverArgs, CC1Args, P.str()); break; } @@ -368,6 +392,7 @@ void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args, SanitizerMask Fuchsia::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::HWAddress; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 3d88053c6b08..4a8a11a8d416 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -1909,9 +1909,7 @@ void Generic_GCC::GCCInstallationDetector::init( CandidateBiarchTripleAliases); // Compute the set of prefixes for our search. - SmallVector Prefixes(D.PrefixDirs.begin(), - D.PrefixDirs.end()); - + SmallVector Prefixes; StringRef GCCToolchainDir = getGCCToolchainDir(Args, D.SysRoot); if (GCCToolchainDir != "") { if (GCCToolchainDir.back() == '/') @@ -1934,13 +1932,10 @@ void Generic_GCC::GCCInstallationDetector::init( // Typically /usr. AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot); } - } - // Try to respect gcc-config on Gentoo. However, do that only - // if --gcc-toolchain is not provided or equal to the Gentoo install - // in /usr. This avoids accidentally enforcing the system GCC version - // when using a custom toolchain. - if (GCCToolchainDir == "" || GCCToolchainDir == D.SysRoot + "/usr") { + // Try to respect gcc-config on Gentoo if --gcc-toolchain is not provided. + // This avoids accidentally enforcing the system GCC version when using a + // custom toolchain. SmallVector GentooTestTriples; // Try to match an exact triple as target triple first. // e.g. crossdev -S x86_64-gentoo-linux-gnu will install gcc libs for @@ -1960,7 +1955,8 @@ void Generic_GCC::GCCInstallationDetector::init( // Loop over the various components which exist and select the best GCC // installation available. GCC installs are ranked by version number. - Version = GCCVersion::Parse("0.0.0"); + const GCCVersion VersionZero = GCCVersion::Parse("0.0.0"); + Version = VersionZero; for (const std::string &Prefix : Prefixes) { auto &VFS = D.getVFS(); if (!VFS.exists(Prefix)) @@ -1993,6 +1989,10 @@ void Generic_GCC::GCCInstallationDetector::init( ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true, GCCDirExists, GCCCrossDirExists); } + + // Skip other prefixes once a GCC installation is found. + if (Version > VersionZero) + break; } } @@ -2106,15 +2106,17 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", "x86_64-unknown-linux", "x86_64-amazon-linux", "x86_64-linux-android"}; - static const char *const X32LibDirs[] = {"/libx32"}; + static const char *const X32Triples[] = {"x86_64-linux-gnux32", + "x86_64-pc-linux-gnux32"}; + static const char *const X32LibDirs[] = {"/libx32", "/lib"}; static const char *const X86LibDirs[] = {"/lib32", "/lib"}; static const char *const X86Triples[] = { - "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", - "i386-linux-gnu", "i386-redhat-linux6E", "i686-redhat-linux", - "i586-redhat-linux", "i386-redhat-linux", "i586-suse-linux", - "i486-slackware-linux", "i686-montavista-linux", "i586-linux-gnu", - "i686-linux-android", "i386-gnu", "i486-gnu", - "i586-gnu", "i686-gnu"}; + "i586-linux-gnu", "i686-linux-gnu", + "i686-pc-linux-gnu", "i386-redhat-linux6E", + "i686-redhat-linux", "i386-redhat-linux", + "i586-suse-linux", "i686-montavista-linux", + "i686-linux-android", "i386-gnu", + }; static const char *const M68kLibDirs[] = {"/lib"}; static const char *const M68kTriples[] = { @@ -2337,17 +2339,19 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( TripleAliases.append(begin(AVRTriples), end(AVRTriples)); break; case llvm::Triple::x86_64: - LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); - TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); - // x32 is always available when x86_64 is available, so adding it as - // secondary arch with x86_64 triples if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) { - BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); + LibDirs.append(begin(X32LibDirs), end(X32LibDirs)); + TripleAliases.append(begin(X32Triples), end(X32Triples)); + BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); } else { - BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); - BiarchTripleAliases.append(begin(X86Triples), end(X86Triples)); + LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); + TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); + BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); + BiarchTripleAliases.append(begin(X32Triples), end(X32Triples)); } + BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); + BiarchTripleAliases.append(begin(X86Triples), end(X86Triples)); break; case llvm::Triple::x86: LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); @@ -2357,6 +2361,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( TripleAliases.append(begin(X86Triples), end(X86Triples)); BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); + BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); + BiarchTripleAliases.append(begin(X32Triples), end(X32Triples)); } break; case llvm::Triple::m68k: @@ -2506,7 +2512,6 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( const llvm::Triple &TargetTriple, const ArgList &Args, const std::string &LibDir, StringRef CandidateTriple, bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) { - llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); // Locations relative to the system lib directory where GCC's triple-specific // directories might reside. struct GCCLibSuffix { @@ -2530,24 +2535,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( // files in that location, not just GCC installation data. {CandidateTriple.str(), "..", TargetTriple.getVendor() == llvm::Triple::Freescale || - TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}, - - // Natively multiarch systems sometimes put the GCC triple-specific - // directory within their multiarch lib directory, resulting in the - // triple appearing twice. - {CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), "../../..", - TargetTriple.getOS() != llvm::Triple::Solaris}, - - // Deal with cases (on Ubuntu) where the system architecture could be i386 - // but the GCC target architecture could be (say) i686. - // FIXME: It may be worthwhile to generalize this and look for a second - // triple. - {"i386-linux-gnu/gcc/" + CandidateTriple.str(), "../../..", - (TargetArch == llvm::Triple::x86 && - TargetTriple.getOS() != llvm::Triple::Solaris)}, - {"i386-gnu/gcc/" + CandidateTriple.str(), "../../..", - (TargetArch == llvm::Triple::x86 && - TargetTriple.getOS() != llvm::Triple::Solaris)}}; + TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}}; for (auto &Suffix : Suffixes) { if (!Suffix.Active) @@ -2784,15 +2772,6 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const { } } -static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs, - const Multilib &Multilib, - StringRef InstallPath, - ToolChain::path_list &Paths) { - if (const auto &PathsCallback = Multilibs.filePathsCallback()) - for (const auto &Path : PathsCallback(Multilib)) - addPathIfExists(D, InstallPath + Path, Paths); -} - void Generic_GCC::PushPPaths(ToolChain::path_list &PPaths) { // Cross-compiling binutils and GCC installations (vanilla and openSUSE at // least) put various tools in a triple-prefixed directory off of the parent @@ -2819,12 +2798,13 @@ void Generic_GCC::AddMultilibPaths(const Driver &D, const std::string &LibPath = std::string(GCCInstallation.getParentLibPath()); - // Add toolchain / multilib specific file paths. - addMultilibsFilePaths(D, Multilibs, SelectedMultilib, - GCCInstallation.getInstallPath(), Paths); - // Sourcery CodeBench MIPS toolchain holds some libraries under // a biarch-like suffix of the GCC installation. + if (const auto &PathsCallback = Multilibs.filePathsCallback()) + for (const auto &Path : PathsCallback(SelectedMultilib)) + addPathIfExists(D, GCCInstallation.getInstallPath() + Path, Paths); + + // Add lib/gcc/$triple/$version, with an optional /multilib suffix. addPathIfExists( D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(), Paths); @@ -2861,10 +2841,8 @@ void Generic_GCC::AddMultilibPaths(const Driver &D, // the cross. Note that GCC does include some of these directories in some // configurations but this seems somewhere between questionable and simply // a bug. - if (StringRef(LibPath).startswith(SysRoot)) { - addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths); + if (StringRef(LibPath).startswith(SysRoot)) addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); - } } } @@ -2872,24 +2850,7 @@ void Generic_GCC::AddMultiarchPaths(const Driver &D, const std::string &SysRoot, const std::string &OSLibDir, path_list &Paths) { - // Try walking via the GCC triple path in case of biarch or multiarch GCC - // installations with strange symlinks. if (GCCInstallation.isValid()) { - addPathIfExists(D, - SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + - "/../../" + OSLibDir, - Paths); - - // Add the 'other' biarch variant path - Multilib BiarchSibling; - if (GCCInstallation.getBiarchSibling(BiarchSibling)) { - addPathIfExists( - D, GCCInstallation.getInstallPath() + BiarchSibling.gccSuffix(), - Paths); - } - - // See comments above on the multilib variant for details of why this is - // included even from outside the sysroot. const std::string &LibPath = std::string(GCCInstallation.getParentLibPath()); const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); @@ -2897,31 +2858,33 @@ void Generic_GCC::AddMultiarchPaths(const Driver &D, addPathIfExists( D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(), Paths); - - // See comments above on the multilib variant for details of why this is - // only included from within the sysroot. - if (StringRef(LibPath).startswith(SysRoot)) - addPathIfExists(D, LibPath, Paths); } } void Generic_GCC::AddMultilibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { // Add include directories specific to the selected multilib set and multilib. - if (GCCInstallation.isValid()) { - const auto &Callback = Multilibs.includeDirsCallback(); - if (Callback) { - for (const auto &Path : Callback(GCCInstallation.getMultilib())) - addExternCSystemIncludeIfExists( - DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path); - } + if (!GCCInstallation.isValid()) + return; + // gcc TOOL_INCLUDE_DIR. + const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); + std::string LibPath(GCCInstallation.getParentLibPath()); + addSystemInclude(DriverArgs, CC1Args, + Twine(LibPath) + "/../" + GCCTriple.str() + "/include"); + + const auto &Callback = Multilibs.includeDirsCallback(); + if (Callback) { + for (const auto &Path : Callback(GCCInstallation.getMultilib())) + addExternCSystemIncludeIfExists(DriverArgs, CC1Args, + GCCInstallation.getInstallPath() + Path); } } void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - if (DriverArgs.hasArg(options::OPT_nostdlibinc) || - DriverArgs.hasArg(options::OPT_nostdincxx)) + if (DriverArgs.hasArg(options::OPT_nostdinc) || + DriverArgs.hasArg(options::OPT_nostdincxx) || + DriverArgs.hasArg(options::OPT_nostdlibinc)) return; switch (GetCXXStdlibType(DriverArgs)) { @@ -2935,32 +2898,13 @@ void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } } -static std::string DetectLibcxxIncludePath(llvm::vfs::FileSystem &vfs, - StringRef base) { - std::error_code EC; - int MaxVersion = 0; - std::string MaxVersionString; - for (llvm::vfs::directory_iterator LI = vfs.dir_begin(base, EC), LE; - !EC && LI != LE; LI = LI.increment(EC)) { - StringRef VersionText = llvm::sys::path::filename(LI->path()); - int Version; - if (VersionText[0] == 'v' && - !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) { - if (Version > MaxVersion) { - MaxVersion = Version; - MaxVersionString = std::string(VersionText); - } - } - } - return MaxVersion ? (base + "/" + MaxVersionString).str() : ""; -} - void Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { auto AddIncludePath = [&](std::string Path) { - std::string IncludePath = DetectLibcxxIncludePath(getVFS(), Path); - if (IncludePath.empty() || !getVFS().exists(IncludePath)) + std::string Version = detectLibcxxVersion(Path); + std::string IncludePath = Path + "/c++/" + Version; + if (Version.empty() || !getVFS().exists(IncludePath)) return false; addSystemInclude(DriverArgs, CC1Args, IncludePath); return true; @@ -2968,48 +2912,53 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, // Android never uses the libc++ headers installed alongside the toolchain, // which are generally incompatible with the NDK libraries anyway. if (!getTriple().isAndroid()) - if (AddIncludePath(getDriver().Dir + "/../include/c++")) + if (AddIncludePath(getDriver().Dir + "/../include")) return; // If this is a development, non-installed, clang, libcxx will // not be found at ../include/c++ but it likely to be found at // one of the following two locations: std::string SysRoot = computeSysRoot(); - if (AddIncludePath(SysRoot + "/usr/local/include/c++")) + if (AddIncludePath(SysRoot + "/usr/local/include")) return; - if (AddIncludePath(SysRoot + "/usr/include/c++")) + if (AddIncludePath(SysRoot + "/usr/include")) return; } -/// Helper to add the variant paths of a libstdc++ installation. -bool Generic_GCC::addLibStdCXXIncludePaths( - Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple, - StringRef TargetMultiarchTriple, Twine IncludeSuffix, - const ArgList &DriverArgs, ArgStringList &CC1Args) const { - if (!getVFS().exists(Base + Suffix)) +bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, + Twine IncludeSuffix, + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + bool DetectDebian) const { + if (!getVFS().exists(IncludeDir)) return false; - addSystemInclude(DriverArgs, CC1Args, Base + Suffix); - - // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If - // that path exists or we have neither a GCC nor target multiarch triple, use - // this vanilla search path. - if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) || - getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) { - addSystemInclude(DriverArgs, CC1Args, - Base + Suffix + "/" + GCCTriple + IncludeSuffix); - } else { - // Otherwise try to use multiarch naming schemes which have normalized the - // triples and put the triple before the suffix. - // - // GCC surprisingly uses *both* the GCC triple with a multilib suffix and - // the target triple, so we support that here. - addSystemInclude(DriverArgs, CC1Args, - Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix); - addSystemInclude(DriverArgs, CC1Args, - Base + "/" + TargetMultiarchTriple + Suffix); + // GPLUSPLUS_INCLUDE_DIR + addSystemInclude(DriverArgs, CC1Args, IncludeDir); + // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent + // include directory. + if (!Triple.empty()) { + if (DetectDebian) { + // Debian native gcc has an awful patch g++-multiarch-incdir.diff which + // uses include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of + // include/c++/10/x86_64-linux-gnu$IncludeSuffix. + std::string Dir = IncludeDir.str(); + StringRef Include = + llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); + std::string Path = + (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix) + .str(); + if (getVFS().exists(Path)) + addSystemInclude(DriverArgs, CC1Args, Path); + else + addSystemInclude(DriverArgs, CC1Args, + IncludeDir + "/" + Triple + IncludeSuffix); + } else { + addSystemInclude(DriverArgs, CC1Args, + IncludeDir + "/" + Triple + IncludeSuffix); + } } - - addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward"); + // GPLUSPLUS_BACKWARD_INCLUDE_DIR + addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward"); return true; } @@ -3027,17 +2976,17 @@ Generic_GCC::addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, StringRef InstallDir = GCCInstallation.getInstallPath(); StringRef TripleStr = GCCInstallation.getTriple().str(); const Multilib &Multilib = GCCInstallation.getMultilib(); - const std::string GCCMultiarchTriple = getMultiarchTriple( - getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot); - const std::string TargetMultiarchTriple = - getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot); const GCCVersion &Version = GCCInstallation.getVersion(); - // The primary search for libstdc++ supports multiarch variants. - if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", - "/c++/" + Version.Text, TripleStr, - GCCMultiarchTriple, TargetMultiarchTriple, - Multilib.includeSuffix(), DriverArgs, CC1Args)) + // Try /../$triple/include/c++/$version then /../include/c++/$version. + if (addLibStdCXXIncludePaths( + LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text, + TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args)) + return true; + // Detect Debian g++-multiarch-incdir.diff. + if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, + TripleStr, Multilib.includeSuffix(), DriverArgs, + CC1Args, /*Debian=*/true)) return true; // Otherwise, fall back on a bunch of options which don't use multiarch @@ -3052,9 +3001,7 @@ Generic_GCC::addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, }; for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { - if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr, - /*GCCMultiarchTriple*/ "", - /*TargetMultiarchTriple*/ "", + if (addLibStdCXXIncludePaths(IncludePath, TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args)) return true; } diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h index 90d3bafc1f00..bcd0807174b0 100644 --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -351,12 +351,11 @@ class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; - bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple, - StringRef GCCMultiarchTriple, - StringRef TargetMultiarchTriple, + bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, Twine IncludeSuffix, const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const; + llvm::opt::ArgStringList &CC1Args, + bool DetectDebian = false) const; /// @} diff --git a/clang/lib/Driver/ToolChains/Haiku.cpp b/clang/lib/Driver/ToolChains/Haiku.cpp index 18f550c9ceca..a79f0f7622ad 100644 --- a/clang/lib/Driver/ToolChains/Haiku.cpp +++ b/clang/lib/Driver/ToolChains/Haiku.cpp @@ -29,6 +29,6 @@ void Haiku::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, void Haiku::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { - addLibStdCXXIncludePaths(getDriver().SysRoot, "/system/develop/headers/c++", - getTriple().str(), "", "", "", DriverArgs, CC1Args); + addLibStdCXXIncludePaths(getDriver().SysRoot + "/system/develop/headers/c++", + getTriple().str(), "", DriverArgs, CC1Args); } diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp index fb54f73bcd4c..e58b666dbfc0 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -613,15 +613,15 @@ void HexagonToolChain::addLibCxxIncludePaths( llvm::opt::ArgStringList &CC1Args) const { const Driver &D = getDriver(); if (!D.SysRoot.empty() && getTriple().isMusl()) - addLibStdCXXIncludePaths(D.SysRoot + "/usr/include/c++/v1", "", "", "", "", - "", DriverArgs, CC1Args); - else if (getTriple().isMusl()) - addLibStdCXXIncludePaths("/usr/include/c++/v1", "", "", "", "", "", + addLibStdCXXIncludePaths(D.SysRoot + "/usr/include/c++/v1", "", "", DriverArgs, CC1Args); + else if (getTriple().isMusl()) + addLibStdCXXIncludePaths("/usr/include/c++/v1", "", "", DriverArgs, + CC1Args); else { std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs); - addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++/v1", "", "", "", - "", DriverArgs, CC1Args); + addLibStdCXXIncludePaths(TargetDir + "/hexagon/include/c++/v1", "", "", + DriverArgs, CC1Args); } } void HexagonToolChain::addLibStdCxxIncludePaths( @@ -629,7 +629,7 @@ void HexagonToolChain::addLibStdCxxIncludePaths( llvm::opt::ArgStringList &CC1Args) const { const Driver &D = getDriver(); std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs); - addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "", + addLibStdCXXIncludePaths(TargetDir + "/hexagon/include/c++", "", "", DriverArgs, CC1Args); } diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 93a56be6a7a4..826e937c839e 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -58,70 +58,42 @@ std::string Linux::getMultiarchTriple(const Driver &D, // regardless of what the actual target triple is. case llvm::Triple::arm: case llvm::Triple::thumb: - if (IsAndroid) { + if (IsAndroid) return "arm-linux-androideabi"; - } else if (TargetEnvironment == llvm::Triple::GNUEABIHF) { - if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf")) - return "arm-linux-gnueabihf"; - } else { - if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi")) - return "arm-linux-gnueabi"; - } - break; + if (TargetEnvironment == llvm::Triple::GNUEABIHF) + return "arm-linux-gnueabihf"; + return "arm-linux-gnueabi"; case llvm::Triple::armeb: case llvm::Triple::thumbeb: - if (TargetEnvironment == llvm::Triple::GNUEABIHF) { - if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf")) - return "armeb-linux-gnueabihf"; - } else { - if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi")) - return "armeb-linux-gnueabi"; - } - break; + if (TargetEnvironment == llvm::Triple::GNUEABIHF) + return "armeb-linux-gnueabihf"; + return "armeb-linux-gnueabi"; case llvm::Triple::x86: if (IsAndroid) return "i686-linux-android"; - if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu")) - return "i386-linux-gnu"; - break; + return "i386-linux-gnu"; case llvm::Triple::x86_64: if (IsAndroid) return "x86_64-linux-android"; - // We don't want this for x32, otherwise it will match x86_64 libs - if (TargetEnvironment != llvm::Triple::GNUX32 && - D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) - return "x86_64-linux-gnu"; - break; + if (TargetEnvironment == llvm::Triple::GNUX32) + return "x86_64-linux-gnux32"; + return "x86_64-linux-gnu"; case llvm::Triple::aarch64: if (IsAndroid) return "aarch64-linux-android"; - if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu")) - return "aarch64-linux-gnu"; - break; + return "aarch64-linux-gnu"; case llvm::Triple::aarch64_be: - if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu")) - return "aarch64_be-linux-gnu"; - break; + return "aarch64_be-linux-gnu"; case llvm::Triple::m68k: - if (D.getVFS().exists(SysRoot + "/lib/m68k-linux-gnu")) - return "m68k-linux-gnu"; - break; + return "m68k-linux-gnu"; - case llvm::Triple::mips: { - std::string MT = IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu"; - if (D.getVFS().exists(SysRoot + "/lib/" + MT)) - return MT; - break; - } - case llvm::Triple::mipsel: { + case llvm::Triple::mips: + return IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu"; + case llvm::Triple::mipsel: if (IsAndroid) return "mipsel-linux-android"; - std::string MT = IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu"; - if (D.getVFS().exists(SysRoot + "/lib/" + MT)) - return MT; - break; - } + return IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu"; case llvm::Triple::mips64: { std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") + "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64"); @@ -145,33 +117,19 @@ std::string Linux::getMultiarchTriple(const Driver &D, case llvm::Triple::ppc: if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe")) return "powerpc-linux-gnuspe"; - if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu")) - return "powerpc-linux-gnu"; - break; + return "powerpc-linux-gnu"; case llvm::Triple::ppcle: - if (D.getVFS().exists(SysRoot + "/lib/powerpcle-linux-gnu")) - return "powerpcle-linux-gnu"; - break; + return "powerpcle-linux-gnu"; case llvm::Triple::ppc64: - if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu")) - return "powerpc64-linux-gnu"; - break; + return "powerpc64-linux-gnu"; case llvm::Triple::ppc64le: - if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu")) - return "powerpc64le-linux-gnu"; - break; + return "powerpc64le-linux-gnu"; case llvm::Triple::sparc: - if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu")) - return "sparc-linux-gnu"; - break; + return "sparc-linux-gnu"; case llvm::Triple::sparcv9: - if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu")) - return "sparc64-linux-gnu"; - break; + return "sparc64-linux-gnu"; case llvm::Triple::systemz: - if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu")) - return "s390x-linux-gnu"; - break; + return "s390x-linux-gnu"; } return TargetTriple.str(); } @@ -307,16 +265,6 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths); - // Similar to the logic for GCC above, if we currently running Clang inside - // of the requested system root, add its parent library paths to - // those searched. - // FIXME: It's not clear whether we should use the driver's installed - // directory ('Dir' below) or the ResourceDir. - if (StringRef(D.Dir).startswith(SysRoot)) { - addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths); - addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths); - } - addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths); addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths); @@ -363,6 +311,12 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) addPathIfExists(D, SysRoot + "/usr/lib", Paths); } +ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const { + if (getTriple().isAndroid()) + return ToolChain::RLT_CompilerRT; + return Generic_ELF::GetDefaultRuntimeLibType(); +} + ToolChain::CXXStdlibType Linux::GetDefaultCXXStdlibType() const { if (getTriple().isAndroid()) return ToolChain::CST_Libcxx; @@ -444,6 +398,14 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { ArchName = "armeb"; IsArm = true; break; + case llvm::Triple::x86: + ArchName = "i386"; + break; + case llvm::Triple::x86_64: + ArchName = Triple.getEnvironment() == llvm::Triple::MuslX32 + ? "x32" + : Triple.getArchName().str(); + break; default: ArchName = Triple.getArchName().str(); } @@ -578,9 +540,10 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) return; - if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) - addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); - + // Add 'include' in the resource directory, which is similar to + // GCC_INCLUDE_DIR (private headers) in GCC. Note: the include directory + // contains some files conflicting with system /usr/include. musl systems + // prefer the /usr/include copies which are more relevant. SmallString<128> ResourceDirInclude(D.ResourceDir); llvm::sys::path::append(ResourceDirInclude, "include"); if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && @@ -590,6 +553,11 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, if (DriverArgs.hasArg(options::OPT_nostdlibinc)) return; + // LOCAL_INCLUDE_DIR + addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); + // TOOL_INCLUDE_DIR + AddMultilibIncludeArgs(DriverArgs, CC1Args); + // Check for configure-time C include directories. StringRef CIncludeDirs(C_INCLUDE_DIRS); if (CIncludeDirs != "") { @@ -603,177 +571,13 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, return; } - // Lacking those, try to detect the correct set of system includes for the - // target triple. - - AddMultilibIncludeArgs(DriverArgs, CC1Args); - - // Implement generic Debian multiarch support. - const StringRef X86_64MultiarchIncludeDirs[] = { - "/usr/include/x86_64-linux-gnu", - - // FIXME: These are older forms of multiarch. It's not clear that they're - // in use in any released version of Debian, so we should consider - // removing them. - "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"}; - const StringRef X86MultiarchIncludeDirs[] = { - "/usr/include/i386-linux-gnu", - - // FIXME: These are older forms of multiarch. It's not clear that they're - // in use in any released version of Debian, so we should consider - // removing them. - "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", - "/usr/include/i486-linux-gnu"}; - const StringRef AArch64MultiarchIncludeDirs[] = { - "/usr/include/aarch64-linux-gnu"}; - const StringRef ARMMultiarchIncludeDirs[] = { - "/usr/include/arm-linux-gnueabi"}; - const StringRef ARMHFMultiarchIncludeDirs[] = { - "/usr/include/arm-linux-gnueabihf"}; - const StringRef ARMEBMultiarchIncludeDirs[] = { - "/usr/include/armeb-linux-gnueabi"}; - const StringRef ARMEBHFMultiarchIncludeDirs[] = { - "/usr/include/armeb-linux-gnueabihf"}; - const StringRef M68kMultiarchIncludeDirs[] = {"/usr/include/m68k-linux-gnu"}; - const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"}; - const StringRef MIPSELMultiarchIncludeDirs[] = { - "/usr/include/mipsel-linux-gnu"}; - const StringRef MIPS64MultiarchIncludeDirs[] = { - "/usr/include/mips64-linux-gnuabi64"}; - const StringRef MIPS64ELMultiarchIncludeDirs[] = { - "/usr/include/mips64el-linux-gnuabi64"}; - const StringRef MIPSN32MultiarchIncludeDirs[] = { - "/usr/include/mips64-linux-gnuabin32"}; - const StringRef MIPSN32ELMultiarchIncludeDirs[] = { - "/usr/include/mips64el-linux-gnuabin32"}; - const StringRef MIPSR6MultiarchIncludeDirs[] = { - "/usr/include/mipsisa32-linux-gnu"}; - const StringRef MIPSR6ELMultiarchIncludeDirs[] = { - "/usr/include/mipsisa32r6el-linux-gnu"}; - const StringRef MIPS64R6MultiarchIncludeDirs[] = { - "/usr/include/mipsisa64r6-linux-gnuabi64"}; - const StringRef MIPS64R6ELMultiarchIncludeDirs[] = { - "/usr/include/mipsisa64r6el-linux-gnuabi64"}; - const StringRef MIPSN32R6MultiarchIncludeDirs[] = { - "/usr/include/mipsisa64r6-linux-gnuabin32"}; - const StringRef MIPSN32R6ELMultiarchIncludeDirs[] = { - "/usr/include/mipsisa64r6el-linux-gnuabin32"}; - const StringRef PPCMultiarchIncludeDirs[] = { - "/usr/include/powerpc-linux-gnu", - "/usr/include/powerpc-linux-gnuspe"}; - const StringRef PPCLEMultiarchIncludeDirs[] = { - "/usr/include/powerpcle-linux-gnu"}; - const StringRef PPC64MultiarchIncludeDirs[] = { - "/usr/include/powerpc64-linux-gnu"}; - const StringRef PPC64LEMultiarchIncludeDirs[] = { - "/usr/include/powerpc64le-linux-gnu"}; - const StringRef SparcMultiarchIncludeDirs[] = { - "/usr/include/sparc-linux-gnu"}; - const StringRef Sparc64MultiarchIncludeDirs[] = { - "/usr/include/sparc64-linux-gnu"}; - const StringRef SYSTEMZMultiarchIncludeDirs[] = { - "/usr/include/s390x-linux-gnu"}; - ArrayRef MultiarchIncludeDirs; - switch (getTriple().getArch()) { - case llvm::Triple::x86_64: - MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; - break; - case llvm::Triple::x86: - MultiarchIncludeDirs = X86MultiarchIncludeDirs; - break; - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_be: - MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; - break; - case llvm::Triple::arm: - case llvm::Triple::thumb: - if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) - MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; - else - MultiarchIncludeDirs = ARMMultiarchIncludeDirs; - break; - case llvm::Triple::armeb: - case llvm::Triple::thumbeb: - if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) - MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs; - else - MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs; - break; - case llvm::Triple::m68k: - MultiarchIncludeDirs = M68kMultiarchIncludeDirs; - break; - case llvm::Triple::mips: - if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) - MultiarchIncludeDirs = MIPSR6MultiarchIncludeDirs; - else - MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; - break; - case llvm::Triple::mipsel: - if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) - MultiarchIncludeDirs = MIPSR6ELMultiarchIncludeDirs; - else - MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; - break; - case llvm::Triple::mips64: - if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) - if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) - MultiarchIncludeDirs = MIPSN32R6MultiarchIncludeDirs; - else - MultiarchIncludeDirs = MIPS64R6MultiarchIncludeDirs; - else if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) - MultiarchIncludeDirs = MIPSN32MultiarchIncludeDirs; - else - MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs; - break; - case llvm::Triple::mips64el: - if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) - if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) - MultiarchIncludeDirs = MIPSN32R6ELMultiarchIncludeDirs; - else - MultiarchIncludeDirs = MIPS64R6ELMultiarchIncludeDirs; - else if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) - MultiarchIncludeDirs = MIPSN32ELMultiarchIncludeDirs; - else - MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs; - break; - case llvm::Triple::ppc: - MultiarchIncludeDirs = PPCMultiarchIncludeDirs; - break; - case llvm::Triple::ppcle: - MultiarchIncludeDirs = PPCLEMultiarchIncludeDirs; - break; - case llvm::Triple::ppc64: - MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; - break; - case llvm::Triple::ppc64le: - MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs; - break; - case llvm::Triple::sparc: - MultiarchIncludeDirs = SparcMultiarchIncludeDirs; - break; - case llvm::Triple::sparcv9: - MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs; - break; - case llvm::Triple::systemz: - MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs; - break; - default: - break; - } - - const std::string AndroidMultiarchIncludeDir = - std::string("/usr/include/") + - getMultiarchTriple(D, getTriple(), SysRoot); - const StringRef AndroidMultiarchIncludeDirs[] = {AndroidMultiarchIncludeDir}; - if (getTriple().isAndroid()) - MultiarchIncludeDirs = AndroidMultiarchIncludeDirs; - - for (StringRef Dir : MultiarchIncludeDirs) { - if (D.getVFS().exists(SysRoot + Dir)) { - addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir); - break; - } - } + // On systems using multiarch and Android, add /usr/include/$triple before + // /usr/include. + std::string MultiarchIncludeDir = getMultiarchTriple(D, getTriple(), SysRoot); + if (!MultiarchIncludeDir.empty() && + D.getVFS().exists(SysRoot + "/usr/include/" + MultiarchIncludeDir)) + addExternCSystemInclude(DriverArgs, CC1Args, + SysRoot + "/usr/include/" + MultiarchIncludeDir); if (getTriple().getOS() == llvm::Triple::RTEMS) return; @@ -817,9 +621,7 @@ void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, }; for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { - if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr, - /*GCCMultiarchTriple*/ "", - /*TargetMultiarchTriple*/ "", + if (addLibStdCXXIncludePaths(IncludePath, TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args)) break; } diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index a45236bc10d3..05e01a208456 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -35,6 +35,7 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { llvm::opt::ArgStringList &CC1Args) const override; void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + RuntimeLibType GetDefaultRuntimeLibType() const override; CXXStdlibType GetDefaultCXXStdlibType() const override; bool IsAArch64OutlineAtomicsDefault(const llvm::opt::ArgList &Args) const override; diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 96de02378ca2..877919e11464 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -11,6 +11,7 @@ #include "Darwin.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Version.h" +#include "clang/Config/config.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -577,7 +578,10 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, // translate 'lld' into 'lld-link', and in the case of the regular msvc // linker, we need to use a special search algorithm. llvm::SmallString<128> linkPath; - StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link"); + StringRef Linker + = Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER); + if (Linker.empty()) + Linker = "link"; if (Linker.equals_lower("lld")) Linker = "lld-link"; diff --git a/clang/lib/Driver/ToolChains/Myriad.cpp b/clang/lib/Driver/ToolChains/Myriad.cpp index ab0df5d8f168..f31466633104 100644 --- a/clang/lib/Driver/ToolChains/Myriad.cpp +++ b/clang/lib/Driver/ToolChains/Myriad.cpp @@ -260,7 +260,7 @@ void MyriadToolChain::addLibStdCxxIncludePaths( const Multilib &Multilib = GCCInstallation.getMultilib(); addLibStdCXXIncludePaths( LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, - "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args); + TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args); } // MyriadToolChain handles several triples: diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp index 48bf061c6650..1ce5a2a203c2 100644 --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -452,8 +452,8 @@ void NetBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { - addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "", - "", DriverArgs, CC1Args); + addLibStdCXXIncludePaths(getDriver().SysRoot + "/usr/include/g++", "", "", + DriverArgs, CC1Args); } llvm::ExceptionHandling NetBSD::GetExceptionModel(const ArgList &Args) const { diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp index 0dc12c7a84b5..9a29cc0985fc 100644 --- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -112,7 +112,8 @@ void RISCVToolChain::addLibStdCxxIncludePaths( StringRef TripleStr = GCCInstallation.getTriple().str(); const Multilib &Multilib = GCCInstallation.getMultilib(); addLibStdCXXIncludePaths(computeSysRoot() + "/include/c++/" + Version.Text, - "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args); + TripleStr, Multilib.includeSuffix(), DriverArgs, + CC1Args); } std::string RISCVToolChain::computeSysRoot() const { diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 4ed4d839ad10..4d1af094f481 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -283,9 +283,7 @@ void Solaris::addLibStdCxxIncludePaths( const GCCVersion &Version = GCCInstallation.getVersion(); // The primary search for libstdc++ supports multiarch variants. - addLibStdCXXIncludePaths(LibDir.str() + "/../include", "/c++/" + Version.Text, - TripleStr, - /*GCCMultiarchTriple*/ "", - /*TargetMultiarchTriple*/ "", - Multilib.includeSuffix(), DriverArgs, CC1Args); + addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, + TripleStr, Multilib.includeSuffix(), DriverArgs, + CC1Args); } diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index 8c4d99b8ad07..e1ca90b195e2 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -294,6 +294,36 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, CC1Args.push_back("-target-feature"); CC1Args.push_back("+exception-handling"); } + + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { + StringRef Opt = A->getValue(0); + if (Opt.startswith("-emscripten-cxx-exceptions-allowed")) { + // '-mllvm -emscripten-cxx-exceptions-allowed' should be used with + // '-mllvm -enable-emscripten-cxx-exceptions' + bool EmExceptionArgExists = false; + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { + if (StringRef(A->getValue(0)) == "-enable-emscripten-cxx-exceptions") { + EmExceptionArgExists = true; + break; + } + } + if (!EmExceptionArgExists) + getDriver().Diag(diag::err_drv_argument_only_allowed_with) + << "-mllvm -emscripten-cxx-exceptions-allowed" + << "-mllvm -enable-emscripten-cxx-exceptions"; + + // Prevent functions specified in -emscripten-cxx-exceptions-allowed list + // from being inlined before reaching the wasm backend. + StringRef FuncNamesStr = Opt.split('=').second; + SmallVector FuncNames; + FuncNamesStr.split(FuncNames, ','); + for (auto Name : FuncNames) { + CC1Args.push_back("-mllvm"); + CC1Args.push_back(DriverArgs.MakeArgString("--force-attribute=" + Name + + ":noinline")); + } + } + } } ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const { diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp index 9bdebe2dd761..b7ccdf23cbaa 100644 --- a/clang/lib/Driver/Types.cpp +++ b/clang/lib/Driver/Types.cpp @@ -126,7 +126,7 @@ bool types::isAcceptedByClang(ID Id) { case TY_Asm: case TY_C: case TY_PP_C: - case TY_CL: + case TY_CL: case TY_CLCXX: case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE: case TY_HIP: @@ -160,7 +160,7 @@ bool types::isObjC(ID Id) { } } -bool types::isOpenCL(ID Id) { return Id == TY_CL; } +bool types::isOpenCL(ID Id) { return Id == TY_CL || Id == TY_CLCXX; } bool types::isCXX(ID Id) { switch (Id) { @@ -249,6 +249,7 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { .Case("cc", TY_CXX) .Case("CC", TY_CXX) .Case("cl", TY_CL) + .Case("clcpp", TY_CLCXX) .Case("cp", TY_CXX) .Case("cu", TY_CUDA) .Case("hh", TY_CXXHeader) @@ -396,6 +397,7 @@ ID types::lookupHeaderTypeForSourceType(ID Id) { case types::TY_ObjCXX: return types::TY_ObjCXXHeader; case types::TY_CL: + case types::TY_CLCXX: return types::TY_CLHeader; } } diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 34c291ecc492..e42f28ed55cd 100755 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2957,6 +2957,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, // Space between the type and the * in: // operator void*() // operator char*() + // operator void const*() + // operator void volatile*() // operator /*comment*/ const char*() // operator volatile /*comment*/ char*() // operator Foo*() @@ -2964,11 +2966,15 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, // operator std::Foo*() // operator C::D*() // dependent on PointerAlignment style. - if (Previous && - (Previous->endsSequence(tok::kw_operator) || - Previous->endsSequence(tok::kw_const, tok::kw_operator) || - Previous->endsSequence(tok::kw_volatile, tok::kw_operator))) - return (Style.PointerAlignment != FormatStyle::PAS_Left); + if (Previous) { + if (Previous->endsSequence(tok::kw_operator)) + return (Style.PointerAlignment != FormatStyle::PAS_Left); + if (Previous->is(tok::kw_const) || Previous->is(tok::kw_volatile)) + return (Style.PointerAlignment != FormatStyle::PAS_Left) || + (Style.SpaceAroundPointerQualifiers == + FormatStyle::SAPQ_After) || + (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both); + } } const auto SpaceRequiredForArrayInitializerLSquare = [](const FormatToken &LSquareTok, const FormatStyle &Style) { @@ -3370,6 +3376,12 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, Style.BitFieldColonSpacing == FormatStyle::BFCS_Before; return true; } + // Do not merge "- -" into "--". + if ((Left.isOneOf(tok::minus, tok::minusminus) && + Right.isOneOf(tok::minus, tok::minusminus)) || + (Left.isOneOf(tok::plus, tok::plusplus) && + Right.isOneOf(tok::plus, tok::plusplus))) + return true; if (Left.is(TT_UnaryOperator)) { if (!Right.is(tok::l_paren)) { // The alternative operators for ~ and ! are "compl" and "not". diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 1404d4a8eaeb..e424fcb34219 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -649,7 +649,6 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, nextToken(); Line->Level = InitialLevel; - FormatTok->setBlockKind(BK_Block); if (PPStartHash == PPEndHash) { Line->MatchingOpeningBlockLineIndex = OpeningLineIndex; diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index ac68fe0aa01a..6016f8d131c7 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -278,6 +278,14 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches, // double z); // In the above example, we need to take special care to ensure that // 'double z' is indented along with it's owning function 'b'. + // The same holds for calling a function: + // double a = foo(x); + // int b = bar(foo(y), + // foor(z)); + // Similar for broken string literals: + // double x = 3.14; + // auto s = "Hello" + // "World"; // Special handling is required for 'nested' ternary operators. SmallVector ScopeStack; @@ -298,8 +306,12 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches, ScopeStack.push_back(i); bool InsideNestedScope = ScopeStack.size() != 0; + bool ContinuedStringLiteral = i > Start && + Changes[i].Tok->is(tok::string_literal) && + Changes[i - 1].Tok->is(tok::string_literal); + bool SkipMatchCheck = InsideNestedScope || ContinuedStringLiteral; - if (Changes[i].NewlinesBefore > 0 && !InsideNestedScope) { + if (Changes[i].NewlinesBefore > 0 && !SkipMatchCheck) { Shift = 0; FoundMatchOnLine = false; } @@ -307,7 +319,7 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches, // If this is the first matching token to be aligned, remember by how many // spaces it has to be shifted, so the rest of the changes on the line are // shifted by the same amount - if (!FoundMatchOnLine && !InsideNestedScope && Matches(Changes[i])) { + if (!FoundMatchOnLine && !SkipMatchCheck && Matches(Changes[i])) { FoundMatchOnLine = true; Shift = Column - Changes[i].StartOfTokenColumn; Changes[i].Spaces += Shift; @@ -317,15 +329,41 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches, // as mentioned in the ScopeStack comment. if (InsideNestedScope && Changes[i].NewlinesBefore > 0) { unsigned ScopeStart = ScopeStack.back(); - if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) || - (ScopeStart > Start + 1 && - Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) || - Changes[i].Tok->is(TT_ConditionalExpr) || - (Changes[i].Tok->Previous && - Changes[i].Tok->Previous->is(TT_ConditionalExpr))) + auto ShouldShiftBeAdded = [&] { + // Function declaration + if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName)) + return true; + + // Continued function declaration + if (ScopeStart > Start + 1 && + Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) + return true; + + // Continued function call + if (ScopeStart > Start + 1 && + Changes[ScopeStart - 2].Tok->is(tok::identifier) && + Changes[ScopeStart - 1].Tok->is(tok::l_paren)) + return true; + + // Ternary operator + if (Changes[i].Tok->is(TT_ConditionalExpr)) + return true; + + // Continued ternary operator + if (Changes[i].Tok->Previous && + Changes[i].Tok->Previous->is(TT_ConditionalExpr)) + return true; + + return false; + }; + + if (ShouldShiftBeAdded()) Changes[i].Spaces += Shift; } + if (ContinuedStringLiteral) + Changes[i].Spaces += Shift; + assert(Shift >= 0); Changes[i].StartOfTokenColumn += Shift; if (i + 1 != Changes.size()) @@ -434,7 +472,10 @@ static unsigned AlignTokens( AlignCurrentSequence(); // A new line starts, re-initialize line status tracking bools. - FoundMatchOnLine = false; + // Keep the match state if a string literal is continued on this line. + if (i == 0 || !Changes[i].Tok->is(tok::string_literal) || + !Changes[i - 1].Tok->is(tok::string_literal)) + FoundMatchOnLine = false; LineIsComment = true; } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index d40240b5b527..284b20cb400a 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -814,15 +814,18 @@ CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary, TempPath += OutputExtension; TempPath += ".tmp"; int fd; - std::error_code EC = - llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); + std::error_code EC = llvm::sys::fs::createUniqueFile( + TempPath, fd, TempPath, + Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_Text); if (CreateMissingDirectories && EC == llvm::errc::no_such_file_or_directory) { StringRef Parent = llvm::sys::path::parent_path(OutputPath); EC = llvm::sys::fs::create_directories(Parent); if (!EC) { - EC = llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); + EC = llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath, + Binary ? llvm::sys::fs::OF_None + : llvm::sys::fs::OF_Text); } } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 08a7a3952714..7bd1874e3f0c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -211,6 +211,7 @@ static void denormalizeStringImpl(SmallVectorImpl &Args, switch (OptClass) { case Option::SeparateClass: case Option::JoinedOrSeparateClass: + case Option::JoinedAndSeparateClass: Args.push_back(Spelling); Args.push_back(SA(Value)); break; @@ -466,6 +467,11 @@ static bool FixupInvocation(CompilerInvocation &Invocation, LangOpts.NewAlignOverride = 0; } + // Prevent the user from specifying both -fsycl-is-device and -fsycl-is-host. + if (LangOpts.SYCLIsDevice && LangOpts.SYCLIsHost) + Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fsycl-is-device" + << "-fsycl-is-host"; + if (Args.hasArg(OPT_fgnu89_inline) && LangOpts.CPlusPlus) Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fgnu89-inline" << GetInputKindName(IK); @@ -515,7 +521,9 @@ static bool FixupInvocation(CompilerInvocation &Invocation, static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, DiagnosticsEngine &Diags) { unsigned DefaultOpt = llvm::CodeGenOpt::None; - if (IK.getLanguage() == Language::OpenCL && !Args.hasArg(OPT_cl_opt_disable)) + if ((IK.getLanguage() == Language::OpenCL || + IK.getLanguage() == Language::OpenCLCXX) && + !Args.hasArg(OPT_cl_opt_disable)) DefaultOpt = llvm::CodeGenOpt::Default; if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { @@ -663,7 +671,7 @@ static bool RoundTrip(ParseFn Parse, GenerateFn Generate, // Generate arguments from the dummy invocation. If Generate is the // inverse of Parse, the newly generated arguments must have the same // semantics as the original. - SmallVector GeneratedArgs1; + SmallVector GeneratedArgs1; Generate(DummyInvocation, GeneratedArgs1, SA); // Run the second parse, now on the generated arguments, and with the real @@ -683,7 +691,7 @@ static bool RoundTrip(ParseFn Parse, GenerateFn Generate, // Generate arguments again, this time from the options we will end up using // for the rest of the compilation. - SmallVector GeneratedArgs2; + SmallVector GeneratedArgs2; Generate(RealInvocation, GeneratedArgs2, SA); // Compares two lists of generated arguments. @@ -1483,9 +1491,6 @@ void CompilerInvocation::GenerateCodeGenArgs( GenerateArg(Args, Opt, SA); } - if (Opts.IgnoreXCOFFVisibility) - GenerateArg(Args, OPT_mignore_xcoff_visibility, SA); - if (Opts.EnableAIXExtendedAltivecABI) GenerateArg(Args, OPT_mabi_EQ_vec_extabi, SA); @@ -1644,6 +1649,12 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, llvm::is_contained(DebugEntryValueArchs, T.getArch())) Opts.EmitCallSiteInfo = true; + if (!Opts.EnableDIPreservationVerify && Opts.DIBugsReportFilePath.size()) { + Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export) + << Opts.DIBugsReportFilePath; + Opts.DIBugsReportFilePath = ""; + } + Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) && Args.hasArg(OPT_new_struct_path_tbaa); Opts.OptimizeSize = getOptimizationLevelSize(Args); @@ -1831,27 +1842,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, } } - // This is the reason why '-fvisibility' needs to be always generated: - // its absence implies '-mignore-xcoff-visibility'. - // - // Suppose the original cc1 command line does contain '-fvisibility default': - // '-mignore-xcoff-visibility' should not be implied. - // * If '-fvisibility' is not generated (as most options with default values - // don't), its absence would imply '-mignore-xcoff-visibility'. This changes - // the command line semantics. - // * If '-fvisibility' is generated regardless of its presence and value, - // '-mignore-xcoff-visibility' won't be implied and the command line - // semantics are kept intact. - // - // When the original cc1 command line does **not** contain '-fvisibility', - // '-mignore-xcoff-visibility' is implied. The generated command line will - // contain both '-fvisibility default' and '-mignore-xcoff-visibility' and - // subsequent calls to `CreateFromArgs`/`generateCC1CommandLine` will always - // produce the same arguments. - if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility) || - !Args.hasArg(OPT_fvisibility))) - Opts.IgnoreXCOFFVisibility = 1; - if (Arg *A = Args.getLastArg(OPT_mabi_EQ_vec_default, OPT_mabi_EQ_vec_extabi)) { if (!T.isOSAIX()) @@ -2488,9 +2478,13 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts, GenerateProgramAction(); - for (const auto &PluginArgs : Opts.PluginArgs) + for (const auto &PluginArgs : Opts.PluginArgs) { + Option Opt = getDriverOptTable().getOption(OPT_plugin_arg); + const char *Spelling = + SA(Opt.getPrefix() + Opt.getName() + PluginArgs.first); for (const auto &PluginArg : PluginArgs.second) - GenerateArg(Args, OPT_plugin_arg, PluginArgs.first + PluginArg, SA); + denormalizeString(Args, Spelling, SA, Opt.getKind(), 0, PluginArg); + } for (const auto &Ext : Opts.ModuleFileExtensions) if (auto *TestExt = dyn_cast_or_null(Ext.get())) @@ -2529,6 +2523,9 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts, case Language::OpenCL: Lang = "cl"; break; + case Language::OpenCLCXX: + Lang = "clcpp"; + break; case Language::CUDA: Lang = "cuda"; break; @@ -2717,6 +2714,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, DashX = llvm::StringSwitch(XValue) .Case("c", Language::C) .Case("cl", Language::OpenCL) + .Case("clcpp", Language::OpenCLCXX) .Case("cuda", Language::CUDA) .Case("hip", Language::HIP) .Case("c++", Language::CXX) @@ -3082,6 +3080,9 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, case Language::OpenCL: LangStd = LangStandard::lang_opencl10; break; + case Language::OpenCLCXX: + LangStd = LangStandard::lang_openclcpp; + break; case Language::CUDA: LangStd = LangStandard::lang_cuda; break; @@ -3217,7 +3218,11 @@ static bool IsInputCompatibleWithStandard(InputKind IK, return S.getLanguage() == Language::C; case Language::OpenCL: - return S.getLanguage() == Language::OpenCL; + return S.getLanguage() == Language::OpenCL || + S.getLanguage() == Language::OpenCLCXX; + + case Language::OpenCLCXX: + return S.getLanguage() == Language::OpenCLCXX; case Language::CXX: case Language::ObjCXX: @@ -3254,6 +3259,8 @@ static const StringRef GetInputKindName(InputKind IK) { return "Objective-C++"; case Language::OpenCL: return "OpenCL"; + case Language::OpenCLCXX: + return "C++ for OpenCL"; case Language::CUDA: return "CUDA"; case Language::RenderScript: @@ -3342,6 +3349,9 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts, Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch), SA); } + if (Opts.IgnoreXCOFFVisibility) + GenerateArg(Args, OPT_mignore_xcoff_visibility, SA); + if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) { GenerateArg(Args, OPT_ftrapv, SA); GenerateArg(Args, OPT_ftrapv_handler, Opts.OverflowHandler, SA); @@ -3649,6 +3659,30 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch; } + // In AIX OS, the -mignore-xcoff-visibility is enable by default if there is + // no -fvisibility=* option. + // This is the reason why '-fvisibility' needs to be always generated: + // its absence implies '-mignore-xcoff-visibility'. + // + // Suppose the original cc1 command line does contain '-fvisibility default': + // '-mignore-xcoff-visibility' should not be implied. + // * If '-fvisibility' is not generated (as most options with default values + // don't), its absence would imply '-mignore-xcoff-visibility'. This changes + // the command line semantics. + // * If '-fvisibility' is generated regardless of its presence and value, + // '-mignore-xcoff-visibility' won't be implied and the command line + // semantics are kept intact. + // + // When the original cc1 command line does **not** contain '-fvisibility', + // '-mignore-xcoff-visibility' is implied. The generated command line will + // contain both '-fvisibility default' and '-mignore-xcoff-visibility' and + // subsequent calls to `CreateFromArgs`/`generateCC1CommandLine` will always + // produce the same arguments. + + if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility) || + !Args.hasArg(OPT_fvisibility))) + Opts.IgnoreXCOFFVisibility = 1; + if (Args.hasArg(OPT_ftrapv)) { Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); // Set the handler, if one is specified. diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 38b6f753134c..0a84971c748c 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -795,7 +795,7 @@ void PreprocessOnlyAction::ExecuteAction() { void PrintPreprocessedAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); // Output file may need to be set to 'Binary', to avoid converting Unix style - // line feeds () to Microsoft style line feeds (). + // line feeds () to Microsoft style line feeds () on Windows. // // Look to see what type of line endings the file uses. If there's a // CRLF, then we won't open the file up in binary mode. If there is @@ -807,30 +807,35 @@ void PrintPreprocessedAction::ExecuteAction() { // all of their source code on a single line. However, that is still a // concern, so if we scan for too long, we'll just assume the file should // be opened in binary mode. - bool BinaryMode = true; - const SourceManager& SM = CI.getSourceManager(); - if (llvm::Optional Buffer = - SM.getBufferOrNone(SM.getMainFileID())) { - const char *cur = Buffer->getBufferStart(); - const char *end = Buffer->getBufferEnd(); - const char *next = (cur != end) ? cur + 1 : end; - - // Limit ourselves to only scanning 256 characters into the source - // file. This is mostly a sanity check in case the file has no - // newlines whatsoever. - if (end - cur > 256) end = cur + 256; - - while (next < end) { - if (*cur == 0x0D) { // CR - if (*next == 0x0A) // CRLF - BinaryMode = false; - - break; - } else if (*cur == 0x0A) // LF - break; - - ++cur; - ++next; + + bool BinaryMode = false; + if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) { + BinaryMode = true; + const SourceManager &SM = CI.getSourceManager(); + if (llvm::Optional Buffer = + SM.getBufferOrNone(SM.getMainFileID())) { + const char *cur = Buffer->getBufferStart(); + const char *end = Buffer->getBufferEnd(); + const char *next = (cur != end) ? cur + 1 : end; + + // Limit ourselves to only scanning 256 characters into the source + // file. This is mostly a sanity check in case the file has no + // newlines whatsoever. + if (end - cur > 256) + end = cur + 256; + + while (next < end) { + if (*cur == 0x0D) { // CR + if (*next == 0x0A) // CRLF + BinaryMode = false; + + break; + } else if (*cur == 0x0A) // LF + break; + + ++cur; + ++next; + } } } @@ -862,6 +867,7 @@ void PrintPreambleAction::ExecuteAction() { case Language::ObjC: case Language::ObjCXX: case Language::OpenCL: + case Language::OpenCLCXX: case Language::CUDA: case Language::HIP: break; diff --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp index 4ea13cf0784f..37ac428a8003 100644 --- a/clang/lib/Frontend/FrontendOptions.cpp +++ b/clang/lib/Frontend/FrontendOptions.cpp @@ -29,6 +29,7 @@ InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) { .Case("cppm", Language::CXX) .Case("iim", InputKind(Language::CXX).getPreprocessed()) .Case("cl", Language::OpenCL) + .Case("clcpp", Language::OpenCLCXX) .Cases("cu", "cuh", Language::CUDA) .Case("hip", Language::HIP) .Cases("ll", "bc", Language::LLVM_IR) diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index c64a912ce919..3d69c59d166d 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -474,7 +474,7 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__FAST_RELAXED_MATH__"); } - if (LangOpts.SYCL) { + if (LangOpts.SYCLIsDevice || LangOpts.SYCLIsHost) { // SYCL Version is set to a value when building SYCL applications if (LangOpts.getSYCLVersion() == LangOptions::SYCL_2017) Builder.defineMacro("CL_SYCL_LANGUAGE_VERSION", "121"); @@ -589,6 +589,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, //Builder.defineMacro("__cpp_modules", "201907L"); //Builder.defineMacro("__cpp_using_enum", "201907L"); } + // C++2b features. + if (LangOpts.CPlusPlus2b) + Builder.defineMacro("__cpp_size_t_suffix", "202011L"); if (LangOpts.Char8) Builder.defineMacro("__cpp_char8_t", "201811L"); Builder.defineMacro("__cpp_impl_destroying_delete", "201806L"); diff --git a/clang/lib/Frontend/Rewrite/FrontendActions.cpp b/clang/lib/Frontend/Rewrite/FrontendActions.cpp index 13e668a47a2f..45960068220b 100644 --- a/clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -185,7 +185,7 @@ RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { void RewriteMacrosAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); std::unique_ptr OS = - CI.createDefaultOutputFile(/*Binary=*/false, getCurrentFileOrBufferName()); + CI.createDefaultOutputFile(/*Binary=*/true, getCurrentFileOrBufferName()); if (!OS) return; RewriteMacrosInInput(CI.getPreprocessor(), OS.get()); @@ -194,7 +194,7 @@ void RewriteMacrosAction::ExecuteAction() { void RewriteTestAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); std::unique_ptr OS = - CI.createDefaultOutputFile(false, getCurrentFileOrBufferName()); + CI.createDefaultOutputFile(/*Binary=*/true, getCurrentFileOrBufferName()); if (!OS) return; DoRewriteTest(CI.getPreprocessor(), OS.get()); diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index d0f5a86be16a..7b20255ed21a 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -212,6 +212,8 @@ clang_generate_header(-gen-arm-bf16 arm_bf16.td arm_bf16.h) clang_generate_header(-gen-arm-mve-header arm_mve.td arm_mve.h) # Generate arm_cde.h clang_generate_header(-gen-arm-cde-header arm_cde.td arm_cde.h) +# Generate riscv_vector.h +clang_generate_header(-gen-riscv-vector-header riscv_vector.td riscv_vector.h) add_custom_target(clang-resource-headers ALL DEPENDS ${out_files}) set_target_properties(clang-resource-headers PROPERTIES diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 55f04d0efbd6..81e4cb686d8d 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -41,9 +41,7 @@ #define __ATTRS_o_ai __attribute__((__overloadable__, __always_inline__)) -#ifdef __POWER9_VECTOR__ #include -#endif static __inline__ vector signed char __ATTRS_o_ai vec_perm( vector signed char __a, vector signed char __b, vector unsigned char __c); @@ -295,6 +293,7 @@ vec_add(vector unsigned long long __a, vector unsigned long long __b) { return __a + __b; } +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_add(vector signed __int128 __a, vector signed __int128 __b) { return __a + __b; @@ -304,6 +303,12 @@ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_add(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __a + __b; } +#endif + +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_add_u128(vector unsigned char __a, vector unsigned char __b) { + return __builtin_altivec_vadduqm(__a, __b); +} #endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) static __inline__ vector float __ATTRS_o_ai vec_add(vector float __a, @@ -321,6 +326,7 @@ static __inline__ vector double __ATTRS_o_ai vec_add(vector double __a, /* vec_adde */ #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_adde(vector signed __int128 __a, vector signed __int128 __b, vector signed __int128 __c) { @@ -334,6 +340,13 @@ vec_adde(vector unsigned __int128 __a, vector unsigned __int128 __b, } #endif +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_adde_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (vector unsigned char)__builtin_altivec_vaddeuqm(__a, __b, __c); +} +#endif + static __inline__ vector signed int __ATTRS_o_ai vec_adde(vector signed int __a, vector signed int __b, vector signed int __c) { @@ -353,6 +366,7 @@ vec_adde(vector unsigned int __a, vector unsigned int __b, /* vec_addec */ #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_addec(vector signed __int128 __a, vector signed __int128 __b, vector signed __int128 __c) { @@ -364,6 +378,13 @@ vec_addec(vector unsigned __int128 __a, vector unsigned __int128 __b, vector unsigned __int128 __c) { return __builtin_altivec_vaddecuq(__a, __b, __c); } +#endif + +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_addec_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (vector unsigned char)__builtin_altivec_vaddecuq(__a, __b, __c); +} static __inline__ vector signed int __ATTRS_o_ai vec_addec(vector signed int __a, vector signed int __b, @@ -535,6 +556,7 @@ vec_addc(vector unsigned int __a, vector unsigned int __b) { } #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_addc(vector signed __int128 __a, vector signed __int128 __b) { return (vector signed __int128)__builtin_altivec_vaddcuq( @@ -545,6 +567,12 @@ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_addc(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __builtin_altivec_vaddcuq(__a, __b); } +#endif + +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_addc_u128(vector unsigned char __a, vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vaddcuq(__a, __b); +} #endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) /* vec_vaddcuw */ @@ -748,7 +776,8 @@ vec_vadduws(vector unsigned int __a, vector bool int __b) { return __builtin_altivec_vadduws(__a, (vector unsigned int)__b); } -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) /* vec_vadduqm */ static __inline__ vector signed __int128 __ATTRS_o_ai @@ -1709,7 +1738,7 @@ vec_cmpeq(vector double __a, vector double __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector bool __int128 __ATTRS_o_ai vec_cmpeq(vector signed __int128 __a, vector signed __int128 __b) { return (vector bool __int128)__builtin_altivec_vcmpequq( @@ -1786,7 +1815,7 @@ vec_cmpne(vector float __a, vector float __b) { (vector int)__b); } -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector bool __int128 __ATTRS_o_ai vec_cmpne(vector unsigned __int128 __a, vector unsigned __int128 __b) { return (vector bool __int128) ~(__builtin_altivec_vcmpequq( @@ -1884,6 +1913,7 @@ vec_parity_lsbb(vector signed int __a) { return __builtin_altivec_vprtybw(__a); } +#ifdef __SIZEOF_INT128__ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_parity_lsbb(vector unsigned __int128 __a) { return __builtin_altivec_vprtybq(__a); @@ -1893,6 +1923,7 @@ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_parity_lsbb(vector signed __int128 __a) { return __builtin_altivec_vprtybq(__a); } +#endif static __inline__ vector unsigned long long __ATTRS_o_ai vec_parity_lsbb(vector unsigned long long __a) { @@ -2046,7 +2077,7 @@ vec_cmpgt(vector double __a, vector double __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector bool __int128 __ATTRS_o_ai vec_cmpgt(vector signed __int128 __a, vector signed __int128 __b) { return (vector bool __int128)__builtin_altivec_vcmpgtsq( @@ -2120,7 +2151,7 @@ vec_cmpge(vector unsigned long long __a, vector unsigned long long __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector bool __int128 __ATTRS_o_ai vec_cmpge(vector signed __int128 __a, vector signed __int128 __b) { return ~(vec_cmpgt(__b, __a)); @@ -2244,7 +2275,7 @@ vec_cmple(vector unsigned long long __a, vector unsigned long long __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector bool __int128 __ATTRS_o_ai vec_cmple(vector signed __int128 __a, vector signed __int128 __b) { return vec_cmpge(__b, __a); @@ -2300,7 +2331,7 @@ vec_cmplt(vector double __a, vector double __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector bool __int128 __ATTRS_o_ai vec_cmplt(vector signed __int128 __a, vector signed __int128 __b) { return vec_cmpgt(__b, __a); @@ -2870,6 +2901,7 @@ static __inline__ vector float __ATTRS_o_ai vec_xl_len(const float *__a, size_t return (vector float)__builtin_vsx_lxvl(__a, (__b << 56)); } +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_xl_len(const signed __int128 *__a, size_t __b) { return (vector signed __int128)__builtin_vsx_lxvl(__a, (__b << 56)); @@ -2879,6 +2911,7 @@ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_xl_len(const unsigned __int128 *__a, size_t __b) { return (vector unsigned __int128)__builtin_vsx_lxvl(__a, (__b << 56)); } +#endif static __inline__ vector signed long long __ATTRS_o_ai vec_xl_len(const signed long long *__a, size_t __b) { @@ -2946,6 +2979,7 @@ static __inline__ void __ATTRS_o_ai vec_xst_len(vector float __a, float *__b, return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); } +#ifdef __SIZEOF_INT128__ static __inline__ void __ATTRS_o_ai vec_xst_len(vector signed __int128 __a, signed __int128 *__b, size_t __c) { @@ -2957,6 +2991,7 @@ static __inline__ void __ATTRS_o_ai vec_xst_len(vector unsigned __int128 __a, size_t __c) { return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); } +#endif static __inline__ void __ATTRS_o_ai vec_xst_len(vector signed long long __a, signed long long *__b, @@ -3033,10 +3068,32 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a, (__b))) #endif +/* vec_ctd */ +#ifdef __VSX__ +#define vec_ctd(__a, __b) \ + _Generic((__a), vector signed int \ + : (vec_doublee((vector signed int)(__a)) * \ + (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \ + << 52)), \ + vector unsigned int \ + : (vec_doublee((vector unsigned int)(__a)) * \ + (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \ + << 52)), \ + vector unsigned long long \ + : (__builtin_convertvector((vector unsigned long long)(__a), \ + vector double) * \ + (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \ + << 52)), \ + vector signed long long \ + : (__builtin_convertvector((vector signed long long)(__a), \ + vector double) * \ + (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \ + << 52))) +#endif // __VSX__ + /* vec_vcfsx */ #define vec_vcfux __builtin_altivec_vcfux - /* vec_vcfux */ #define vec_vcfsx(__a, __b) __builtin_altivec_vcfsx((vector int)(__a), (__b)) @@ -3114,7 +3171,7 @@ vec_signextll(vector signed int __a) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_signextq(vector signed long long __a) { return __builtin_altivec_vextsd2q(__a); @@ -3399,6 +3456,15 @@ vec_doubleo(vector float __a) { return __builtin_vsx_xvcvspdp(vec_sld(__a, __a, 4)); #endif } + +/* vec_cvf */ +static __inline__ vector double __ATTRS_o_ai vec_cvf(vector float __a) { + return vec_doublee(__a); +} + +static __inline__ vector float __ATTRS_o_ai vec_cvf(vector double __a) { + return vec_floate(__a); +} #endif /* vec_div */ @@ -3481,6 +3547,7 @@ vec_dive(vector unsigned long long __a, vector unsigned long long __b) { return __builtin_altivec_vdiveud(__a, __b); } +#ifdef __SIZEOF_INT128__ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_dive(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __builtin_altivec_vdiveuq(__a, __b); @@ -3491,8 +3558,9 @@ vec_dive(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vdivesq(__a, __b); } #endif +#endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_div(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __a / __b; @@ -5695,7 +5763,7 @@ vec_msum(vector unsigned short __a, vector unsigned short __b, /* vec_msumc */ -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_msumc(vector unsigned long long __a, vector unsigned long long __b, vector unsigned __int128 __c) { @@ -5929,7 +5997,7 @@ vec_mule(vector unsigned int __a, vector unsigned int __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_mule(vector signed long long __a, vector signed long long __b) { #ifdef __LITTLE_ENDIAN__ @@ -6075,7 +6143,7 @@ vec_mulo(vector unsigned int __a, vector unsigned int __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_mulo(vector signed long long __a, vector signed long long __b) { #ifdef __LITTLE_ENDIAN__ @@ -7927,7 +7995,7 @@ vec_rl(vector unsigned long long __a, vector unsigned long long __b) { } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_rl(vector signed __int128 __a, vector unsigned __int128 __b) { return (__b << __a)|(__b >> ((__CHAR_BIT__ * sizeof(vector signed __int128)) - __a)); @@ -7954,7 +8022,7 @@ vec_rlmi(vector unsigned long long __a, vector unsigned long long __b, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_rlmi(vector unsigned __int128 __a, vector unsigned __int128 __b, vector unsigned __int128 __c) { @@ -7985,7 +8053,7 @@ vec_rlnm(vector unsigned long long __a, vector unsigned long long __b, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_rlnm(vector unsigned __int128 __a, vector unsigned __int128 __b, vector unsigned __int128 __c) { @@ -11409,7 +11477,8 @@ vec_sub(vector unsigned int __a, vector bool int __b) { return __a - (vector unsigned int)__b; } -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_sub(vector signed __int128 __a, vector signed __int128 __b) { return __a - __b; @@ -11419,7 +11488,8 @@ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_sub(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __a - __b; } -#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) && + // defined(__SIZEOF_INT128__) #ifdef __VSX__ static __inline__ vector signed long long __ATTRS_o_ai @@ -11568,6 +11638,7 @@ vec_subc(vector unsigned int __a, vector unsigned int __b) { } #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#ifdef __SIZEOF_INT128__ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_subc(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __builtin_altivec_vsubcuq(__a, __b); @@ -11577,6 +11648,12 @@ static __inline__ vector signed __int128 __ATTRS_o_ai vec_subc(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vsubcuq(__a, __b); } +#endif + +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_subc_u128(vector unsigned char __a, vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsubcuq(__a, __b); +} #endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) /* vec_vsubcuw */ @@ -11783,6 +11860,7 @@ vec_vsubuws(vector unsigned int __a, vector bool int __b) { #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) /* vec_vsubuqm */ +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_vsubuqm(vector signed __int128 __a, vector signed __int128 __b) { return __a - __b; @@ -11792,10 +11870,16 @@ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_vsubuqm(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __a - __b; } +#endif -/* vec_vsubeuqm */ +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_sub_u128(vector unsigned char __a, vector unsigned char __b) { + return __builtin_altivec_vsubuqm(__a, __b); +} +/* vec_vsubeuqm */ +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_vsubeuqm(vector signed __int128 __a, vector signed __int128 __b, vector signed __int128 __c) { @@ -11819,9 +11903,17 @@ vec_sube(vector unsigned __int128 __a, vector unsigned __int128 __b, vector unsigned __int128 __c) { return __builtin_altivec_vsubeuqm(__a, __b, __c); } +#endif + +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_sube_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (vector unsigned char)__builtin_altivec_vsubeuqm(__a, __b, __c); +} /* vec_vsubcuq */ +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_vsubcuq(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vsubcuq(__a, __b); @@ -11845,6 +11937,7 @@ vec_vsubecuq(vector unsigned __int128 __a, vector unsigned __int128 __b, vector unsigned __int128 __c) { return __builtin_altivec_vsubecuq(__a, __b, __c); } +#endif static __inline__ vector signed int __ATTRS_o_ai vec_subec(vector signed int __a, vector signed int __b, @@ -11858,6 +11951,7 @@ vec_subec(vector unsigned int __a, vector unsigned int __b, return vec_addec(__a, ~__b, __c); } +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_subec(vector signed __int128 __a, vector signed __int128 __b, vector signed __int128 __c) { @@ -11869,6 +11963,13 @@ vec_subec(vector unsigned __int128 __a, vector unsigned __int128 __b, vector unsigned __int128 __c) { return __builtin_altivec_vsubecuq(__a, __b, __c); } +#endif + +static __inline__ vector unsigned char __attribute__((__always_inline__)) +vec_subec_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (vector unsigned char)__builtin_altivec_vsubecuq(__a, __b, __c); +} #endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) static __inline__ vector signed int __ATTRS_o_ai @@ -12558,6 +12659,16 @@ static __inline__ void __ATTRS_o_ai vec_vsx_st(vector unsigned char __a, #ifdef __VSX__ #define vec_xxpermdi __builtin_vsx_xxpermdi #define vec_xxsldwi __builtin_vsx_xxsldwi +#define vec_permi(__a, __b, __c) \ + _Generic((__a), vector signed long long \ + : __builtin_shufflevector((__a), (__b), (((__c) >> 1) & 0x1), \ + (((__c)&0x1) + 2)), \ + vector unsigned long long \ + : __builtin_shufflevector((__a), (__b), (((__c) >> 1) & 0x1), \ + (((__c)&0x1) + 2)), \ + vector double \ + : __builtin_shufflevector((__a), (__b), (((__c) >> 1) & 0x1), \ + (((__c)&0x1) + 2))) #endif /* vec_xor */ @@ -14129,7 +14240,8 @@ vec_splats(unsigned long long __a) { return (vector unsigned long long)(__a); } -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_splats(signed __int128 __a) { return (vector signed __int128)(__a); @@ -14340,7 +14452,7 @@ static __inline__ int __ATTRS_o_ai vec_all_eq(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_all_eq(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpequq_p(__CR6_LT, __a, __b); @@ -14523,7 +14635,7 @@ static __inline__ int __ATTRS_o_ai vec_all_ge(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_all_ge(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_EQ, __b, __a); @@ -14706,7 +14818,7 @@ static __inline__ int __ATTRS_o_ai vec_all_gt(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_all_gt(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_LT, __a, __b); @@ -14897,7 +15009,7 @@ static __inline__ int __ATTRS_o_ai vec_all_le(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_all_le(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_EQ, __a, __b); @@ -15081,7 +15193,7 @@ static __inline__ int __ATTRS_o_ai vec_all_lt(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_all_lt(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_LT, __b, __a); @@ -15297,7 +15409,7 @@ static __inline__ int __ATTRS_o_ai vec_all_ne(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_all_ne(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpequq_p(__CR6_EQ, __a, __b); @@ -15586,7 +15698,7 @@ static __inline__ int __ATTRS_o_ai vec_any_eq(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_any_eq(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpequq_p(__CR6_EQ_REV, __a, __b); @@ -15777,7 +15889,7 @@ static __inline__ int __ATTRS_o_ai vec_any_ge(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_any_ge(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_LT_REV, __b, __a); @@ -15968,7 +16080,7 @@ static __inline__ int __ATTRS_o_ai vec_any_gt(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_any_gt(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_EQ_REV, __a, __b); @@ -16159,7 +16271,7 @@ static __inline__ int __ATTRS_o_ai vec_any_le(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_any_le(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_LT_REV, __a, __b); @@ -16350,7 +16462,7 @@ static __inline__ int __ATTRS_o_ai vec_any_lt(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_any_lt(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpgtsq_p(__CR6_EQ_REV, __b, __a); @@ -16364,10 +16476,18 @@ static __inline__ int __ATTRS_o_ai vec_any_lt(vector unsigned __int128 __a, /* vec_any_nan */ -static __inline__ int __attribute__((__always_inline__)) -vec_any_nan(vector float __a) { +static __inline__ int __ATTRS_o_ai vec_any_nan(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_LT_REV, __a, __a); +#else return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, __a, __a); +#endif +} +#ifdef __VSX__ +static __inline__ int __ATTRS_o_ai vec_any_nan(vector double __a) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_LT_REV, __a, __a); } +#endif /* vec_any_ne */ @@ -16557,7 +16677,7 @@ static __inline__ int __ATTRS_o_ai vec_any_ne(vector double __a, } #endif -#ifdef __POWER10_VECTOR__ +#if defined(__POWER10_VECTOR__) && defined(__SIZEOF_INT128__) static __inline__ int __ATTRS_o_ai vec_any_ne(vector signed __int128 __a, vector signed __int128 __b) { return __builtin_altivec_vcmpequq_p(__CR6_LT_REV, __a, __b); @@ -16571,38 +16691,91 @@ static __inline__ int __ATTRS_o_ai vec_any_ne(vector unsigned __int128 __a, /* vec_any_nge */ -static __inline__ int __attribute__((__always_inline__)) -vec_any_nge(vector float __a, vector float __b) { +static __inline__ int __ATTRS_o_ai vec_any_nge(vector float __a, + vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_LT_REV, __a, __b); +#else return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, __a, __b); +#endif +} + +#ifdef __VSX__ +static __inline__ int __ATTRS_o_ai vec_any_nge(vector double __a, + vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_LT_REV, __a, __b); } +#endif /* vec_any_ngt */ -static __inline__ int __attribute__((__always_inline__)) -vec_any_ngt(vector float __a, vector float __b) { +static __inline__ int __ATTRS_o_ai vec_any_ngt(vector float __a, + vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_LT_REV, __a, __b); +#else return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, __a, __b); +#endif } +#ifdef __VSX__ +static __inline__ int __ATTRS_o_ai vec_any_ngt(vector double __a, + vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_LT_REV, __a, __b); +} +#endif + /* vec_any_nle */ -static __inline__ int __attribute__((__always_inline__)) -vec_any_nle(vector float __a, vector float __b) { +static __inline__ int __ATTRS_o_ai vec_any_nle(vector float __a, + vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_LT_REV, __b, __a); +#else return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, __b, __a); +#endif } +#ifdef __VSX__ +static __inline__ int __ATTRS_o_ai vec_any_nle(vector double __a, + vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_LT_REV, __b, __a); +} +#endif + /* vec_any_nlt */ -static __inline__ int __attribute__((__always_inline__)) -vec_any_nlt(vector float __a, vector float __b) { +static __inline__ int __ATTRS_o_ai vec_any_nlt(vector float __a, + vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_LT_REV, __b, __a); +#else return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, __b, __a); +#endif +} + +#ifdef __VSX__ +static __inline__ int __ATTRS_o_ai vec_any_nlt(vector double __a, + vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_LT_REV, __b, __a); } +#endif /* vec_any_numeric */ -static __inline__ int __attribute__((__always_inline__)) -vec_any_numeric(vector float __a) { +static __inline__ int __ATTRS_o_ai vec_any_numeric(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_EQ_REV, __a, __a); +#else return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, __a, __a); +#endif +} + +#ifdef __VSX__ +static __inline__ int __ATTRS_o_ai vec_any_numeric(vector double __a) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ_REV, __a, __a); } +#endif /* vec_any_out */ @@ -16752,6 +16925,16 @@ vec_vgbbd(vector unsigned char __a) { return __builtin_altivec_vgbbd(__a); } +static __inline__ vector signed long long __ATTRS_o_ai +vec_gbb(vector signed long long __a) { + return __builtin_altivec_vgbbd((vector unsigned char)__a); +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_gbb(vector unsigned long long __a) { + return __builtin_altivec_vgbbd((vector unsigned char)__a); +} + static __inline__ vector long long __ATTRS_o_ai vec_vbpermq(vector signed char __a, vector signed char __b) { return __builtin_altivec_vbpermq((vector unsigned char)__a, @@ -16763,7 +16946,7 @@ vec_vbpermq(vector unsigned char __a, vector unsigned char __b) { return __builtin_altivec_vbpermq(__a, __b); } -#ifdef __powerpc64__ +#if defined(__powerpc64__) && defined(__SIZEOF_INT128__) static __inline__ vector unsigned long long __attribute__((__always_inline__)) vec_bperm(vector unsigned __int128 __a, vector unsigned char __b) { return __builtin_altivec_vbpermq((vector unsigned char)__a, @@ -16938,7 +17121,8 @@ vec_revb(vector double __a) { } #endif /* End __VSX__ */ -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_revb(vector signed __int128 __a) { vector unsigned char __indices = @@ -16960,6 +17144,8 @@ vec_revb(vector unsigned __int128 __a) { /* vec_xl */ +#define vec_xld2 vec_xl +#define vec_xlw4 vec_xl typedef vector signed char unaligned_vec_schar __attribute__((aligned(1))); typedef vector unsigned char unaligned_vec_uchar __attribute__((aligned(1))); typedef vector signed short unaligned_vec_sshort __attribute__((aligned(1))); @@ -16968,41 +17154,41 @@ typedef vector signed int unaligned_vec_sint __attribute__((aligned(1))); typedef vector unsigned int unaligned_vec_uint __attribute__((aligned(1))); typedef vector float unaligned_vec_float __attribute__((aligned(1))); -static inline __ATTRS_o_ai vector signed char vec_xl(signed long long __offset, +static inline __ATTRS_o_ai vector signed char vec_xl(ptrdiff_t __offset, const signed char *__ptr) { return *(unaligned_vec_schar *)(__ptr + __offset); } static inline __ATTRS_o_ai vector unsigned char -vec_xl(signed long long __offset, const unsigned char *__ptr) { +vec_xl(ptrdiff_t __offset, const unsigned char *__ptr) { return *(unaligned_vec_uchar*)(__ptr + __offset); } -static inline __ATTRS_o_ai vector signed short vec_xl(signed long long __offset, - const signed short *__ptr) { +static inline __ATTRS_o_ai vector signed short +vec_xl(ptrdiff_t __offset, const signed short *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_sshort *)__addr; } static inline __ATTRS_o_ai vector unsigned short -vec_xl(signed long long __offset, const unsigned short *__ptr) { +vec_xl(ptrdiff_t __offset, const unsigned short *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_ushort *)__addr; } -static inline __ATTRS_o_ai vector signed int vec_xl(signed long long __offset, +static inline __ATTRS_o_ai vector signed int vec_xl(ptrdiff_t __offset, const signed int *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_sint *)__addr; } -static inline __ATTRS_o_ai vector unsigned int vec_xl(signed long long __offset, - const unsigned int *__ptr) { +static inline __ATTRS_o_ai vector unsigned int +vec_xl(ptrdiff_t __offset, const unsigned int *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_uint *)__addr; } -static inline __ATTRS_o_ai vector float vec_xl(signed long long __offset, +static inline __ATTRS_o_ai vector float vec_xl(ptrdiff_t __offset, const float *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_float *)__addr; @@ -17014,36 +17200,37 @@ typedef vector unsigned long long unaligned_vec_ull __attribute__((aligned(1))); typedef vector double unaligned_vec_double __attribute__((aligned(1))); static inline __ATTRS_o_ai vector signed long long -vec_xl(signed long long __offset, const signed long long *__ptr) { +vec_xl(ptrdiff_t __offset, const signed long long *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_sll *)__addr; } static inline __ATTRS_o_ai vector unsigned long long -vec_xl(signed long long __offset, const unsigned long long *__ptr) { +vec_xl(ptrdiff_t __offset, const unsigned long long *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_ull *)__addr; } -static inline __ATTRS_o_ai vector double vec_xl(signed long long __offset, +static inline __ATTRS_o_ai vector double vec_xl(ptrdiff_t __offset, const double *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_double *)__addr; } #endif -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) typedef vector signed __int128 unaligned_vec_si128 __attribute__((aligned(1))); typedef vector unsigned __int128 unaligned_vec_ui128 __attribute__((aligned(1))); static inline __ATTRS_o_ai vector signed __int128 -vec_xl(signed long long __offset, const signed __int128 *__ptr) { +vec_xl(ptrdiff_t __offset, const signed __int128 *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_si128 *)__addr; } static inline __ATTRS_o_ai vector unsigned __int128 -vec_xl(signed long long __offset, const unsigned __int128 *__ptr) { +vec_xl(ptrdiff_t __offset, const unsigned __int128 *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_ui128 *)__addr; } @@ -17053,27 +17240,27 @@ vec_xl(signed long long __offset, const unsigned __int128 *__ptr) { #ifdef __LITTLE_ENDIAN__ static __inline__ vector signed char __ATTRS_o_ai -vec_xl_be(signed long long __offset, const signed char *__ptr) { +vec_xl_be(ptrdiff_t __offset, const signed char *__ptr) { vector signed char __vec = (vector signed char)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); } static __inline__ vector unsigned char __ATTRS_o_ai -vec_xl_be(signed long long __offset, const unsigned char *__ptr) { +vec_xl_be(ptrdiff_t __offset, const unsigned char *__ptr) { vector unsigned char __vec = (vector unsigned char)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); } -static __inline__ vector signed short __ATTRS_o_ai -vec_xl_be(signed long long __offset, const signed short *__ptr) { +static __inline__ vector signed short __ATTRS_o_ai +vec_xl_be(ptrdiff_t __offset, const signed short *__ptr) { vector signed short __vec = (vector signed short)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 3, 2, 1, 0, 7, 6, 5, 4); } static __inline__ vector unsigned short __ATTRS_o_ai -vec_xl_be(signed long long __offset, const unsigned short *__ptr) { +vec_xl_be(ptrdiff_t __offset, const unsigned short *__ptr) { vector unsigned short __vec = (vector unsigned short)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 3, 2, 1, 0, 7, 6, 5, 4); } @@ -17110,7 +17297,8 @@ vec_xl_be(signed long long __offset, const double *__ptr) { } #endif -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) static __inline__ vector signed __int128 __ATTRS_o_ai vec_xl_be(signed long long __offset, const signed __int128 *__ptr) { return vec_xl(__offset, __ptr); @@ -17125,49 +17313,50 @@ vec_xl_be(signed long long __offset, const unsigned __int128 *__ptr) { #define vec_xl_be vec_xl #endif -#if defined(__POWER10_VECTOR__) && defined(__VSX__) +#if defined(__POWER10_VECTOR__) && defined(__VSX__) && \ + defined(__SIZEOF_INT128__) /* vect_xl_sext */ static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, const signed char *__pointer) { +vec_xl_sext(ptrdiff_t __offset, const signed char *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, const signed short *__pointer) { +vec_xl_sext(ptrdiff_t __offset, const signed short *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, const signed int *__pointer) { +vec_xl_sext(ptrdiff_t __offset, const signed int *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, const signed long long *__pointer) { +vec_xl_sext(ptrdiff_t __offset, const signed long long *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } /* vec_xl_zext */ static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, const unsigned char *__pointer) { +vec_xl_zext(ptrdiff_t __offset, const unsigned char *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, const unsigned short *__pointer) { +vec_xl_zext(ptrdiff_t __offset, const unsigned short *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, const unsigned int *__pointer) { +vec_xl_zext(ptrdiff_t __offset, const unsigned int *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, const unsigned long long *__pointer) { +vec_xl_zext(ptrdiff_t __offset, const unsigned long long *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } @@ -17175,48 +17364,44 @@ vec_xl_zext(signed long long __offset, const unsigned long long *__pointer) { /* vec_xst */ -static inline __ATTRS_o_ai void vec_xst(vector signed char __vec, - signed long long __offset, - signed char *__ptr) { +#define vec_xstd2 vec_xst +#define vec_xstw4 vec_xst +static inline __ATTRS_o_ai void +vec_xst(vector signed char __vec, ptrdiff_t __offset, signed char *__ptr) { *(unaligned_vec_schar *)(__ptr + __offset) = __vec; } -static inline __ATTRS_o_ai void vec_xst(vector unsigned char __vec, - signed long long __offset, - unsigned char *__ptr) { +static inline __ATTRS_o_ai void +vec_xst(vector unsigned char __vec, ptrdiff_t __offset, unsigned char *__ptr) { *(unaligned_vec_uchar *)(__ptr + __offset) = __vec; } -static inline __ATTRS_o_ai void vec_xst(vector signed short __vec, - signed long long __offset, - signed short *__ptr) { +static inline __ATTRS_o_ai void +vec_xst(vector signed short __vec, ptrdiff_t __offset, signed short *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_sshort *)__addr = __vec; } static inline __ATTRS_o_ai void vec_xst(vector unsigned short __vec, - signed long long __offset, + ptrdiff_t __offset, unsigned short *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_ushort *)__addr = __vec; } static inline __ATTRS_o_ai void vec_xst(vector signed int __vec, - signed long long __offset, - signed int *__ptr) { + ptrdiff_t __offset, signed int *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_sint *)__addr = __vec; } -static inline __ATTRS_o_ai void vec_xst(vector unsigned int __vec, - signed long long __offset, - unsigned int *__ptr) { +static inline __ATTRS_o_ai void +vec_xst(vector unsigned int __vec, ptrdiff_t __offset, unsigned int *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_uint *)__addr = __vec; } -static inline __ATTRS_o_ai void vec_xst(vector float __vec, - signed long long __offset, +static inline __ATTRS_o_ai void vec_xst(vector float __vec, ptrdiff_t __offset, float *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_float *)__addr = __vec; @@ -17224,37 +17409,37 @@ static inline __ATTRS_o_ai void vec_xst(vector float __vec, #ifdef __VSX__ static inline __ATTRS_o_ai void vec_xst(vector signed long long __vec, - signed long long __offset, + ptrdiff_t __offset, signed long long *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_sll *)__addr = __vec; } static inline __ATTRS_o_ai void vec_xst(vector unsigned long long __vec, - signed long long __offset, + ptrdiff_t __offset, unsigned long long *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_ull *)__addr = __vec; } -static inline __ATTRS_o_ai void vec_xst(vector double __vec, - signed long long __offset, +static inline __ATTRS_o_ai void vec_xst(vector double __vec, ptrdiff_t __offset, double *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_double *)__addr = __vec; } #endif -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) static inline __ATTRS_o_ai void vec_xst(vector signed __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, signed __int128 *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_si128 *)__addr = __vec; } static inline __ATTRS_o_ai void vec_xst(vector unsigned __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, unsigned __int128 *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; *(unaligned_vec_ui128 *)__addr = __vec; @@ -17263,51 +17448,52 @@ static inline __ATTRS_o_ai void vec_xst(vector unsigned __int128 __vec, /* vec_xst_trunc */ -#if defined(__POWER10_VECTOR__) && defined(__VSX__) +#if defined(__POWER10_VECTOR__) && defined(__VSX__) && \ + defined(__SIZEOF_INT128__) static inline __ATTRS_o_ai void vec_xst_trunc(vector signed __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, signed char *__ptr) { *(__ptr + __offset) = (signed char)__vec[0]; } static inline __ATTRS_o_ai void vec_xst_trunc(vector unsigned __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, unsigned char *__ptr) { *(__ptr + __offset) = (unsigned char)__vec[0]; } static inline __ATTRS_o_ai void vec_xst_trunc(vector signed __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, signed short *__ptr) { *(__ptr + __offset) = (signed short)__vec[0]; } static inline __ATTRS_o_ai void vec_xst_trunc(vector unsigned __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, unsigned short *__ptr) { *(__ptr + __offset) = (unsigned short)__vec[0]; } static inline __ATTRS_o_ai void vec_xst_trunc(vector signed __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, signed int *__ptr) { *(__ptr + __offset) = (signed int)__vec[0]; } static inline __ATTRS_o_ai void vec_xst_trunc(vector unsigned __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, unsigned int *__ptr) { *(__ptr + __offset) = (unsigned int)__vec[0]; } static inline __ATTRS_o_ai void vec_xst_trunc(vector signed __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, signed long long *__ptr) { *(__ptr + __offset) = (signed long long)__vec[0]; } static inline __ATTRS_o_ai void vec_xst_trunc(vector unsigned __int128 __vec, - signed long long __offset, + ptrdiff_t __offset, unsigned long long *__ptr) { *(__ptr + __offset) = (unsigned long long)__vec[0]; } @@ -17392,7 +17578,8 @@ static __inline__ void __ATTRS_o_ai vec_xst_be(vector double __vec, } #endif -#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) && \ + defined(__SIZEOF_INT128__) static __inline__ void __ATTRS_o_ai vec_xst_be(vector signed __int128 __vec, signed long long __offset, signed __int128 *__ptr) { @@ -17502,10 +17689,12 @@ vec_extractm(vector unsigned long long __a) { return __builtin_altivec_vextractdm(__a); } +#ifdef __SIZEOF_INT128__ static __inline__ unsigned int __ATTRS_o_ai vec_extractm(vector unsigned __int128 __a) { return __builtin_altivec_vextractqm(__a); } +#endif /* vec_expandm */ @@ -17529,10 +17718,12 @@ vec_expandm(vector unsigned long long __a) { return __builtin_altivec_vexpanddm(__a); } +#ifdef __SIZEOF_INT128__ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_expandm(vector unsigned __int128 __a) { return __builtin_altivec_vexpandqm(__a); } +#endif /* vec_cntm */ @@ -17568,10 +17759,12 @@ vec_gendm(unsigned long long __bm) { return __builtin_altivec_mtvsrdm(__bm); } +#ifdef __SIZEOF_INT128__ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_genqm(unsigned long long __bm) { return __builtin_altivec_mtvsrqm(__bm); } +#endif /* vec_pdep */ @@ -17600,6 +17793,7 @@ vec_cfuge(vector unsigned long long __a, vector unsigned long long __b) { /* vec_ternarylogic */ #ifdef __VSX__ +#ifdef __SIZEOF_INT128__ #define vec_ternarylogic(__a, __b, __c, __imm) \ _Generic((__a), vector unsigned char \ : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ @@ -17621,6 +17815,25 @@ vec_cfuge(vector unsigned long long __a, vector unsigned long long __b) { : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ (vector unsigned long long)(__b), \ (vector unsigned long long)(__c), (__imm))) +#else +#define vec_ternarylogic(__a, __b, __c, __imm) \ + _Generic((__a), vector unsigned char \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm)), \ + vector unsigned short \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm)), \ + vector unsigned int \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm)), \ + vector unsigned long long \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm))) +#endif /* __SIZEOF_INT128__ */ #endif /* __VSX__ */ /* vec_genpcvm */ @@ -17713,6 +17926,7 @@ vec_mod(vector unsigned long long __a, vector unsigned long long __b) { return __a % __b; } +#ifdef __SIZEOF_INT128__ static __inline__ vector signed __int128 __ATTRS_o_ai vec_mod(vector signed __int128 __a, vector signed __int128 __b) { return __a % __b; @@ -17722,6 +17936,7 @@ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_mod(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __a % __b; } +#endif /* vec_sldbi */ @@ -18244,6 +18459,7 @@ static __inline__ int __ATTRS_o_ai vec_strir_p(vector signed short __a) { /* vs[l | r | ra] */ +#ifdef __SIZEOF_INT128__ static __inline__ vector unsigned __int128 __ATTRS_o_ai vec_sl(vector unsigned __int128 __a, vector unsigned __int128 __b) { return __a << (__b % (vector unsigned __int128)(sizeof(unsigned __int128) * @@ -18288,6 +18504,7 @@ vec_sra(vector signed __int128 __a, vector unsigned __int128 __b) { __CHAR_BIT__)); } +#endif /* __SIZEOF_INT128__ */ #endif /* __POWER10_VECTOR__ */ #undef __ATTRS_o_ai diff --git a/clang/lib/Headers/amxintrin.h b/clang/lib/Headers/amxintrin.h index 8c276519e362..12d21d40bcff 100644 --- a/clang/lib/Headers/amxintrin.h +++ b/clang/lib/Headers/amxintrin.h @@ -267,8 +267,8 @@ _tile_stored_internal(unsigned short m, unsigned short n, void *base, } static __inline__ _tile1024i __DEFAULT_FN_ATTRS_BF16 -_tile_tdpbf16ps_internal(unsigned short m, unsigned short n, unsigned short k, - _tile1024i dst, _tile1024i src1, _tile1024i src2) { +_tile_dpbf16ps_internal(unsigned short m, unsigned short n, unsigned short k, + _tile1024i dst, _tile1024i src1, _tile1024i src2) { return __builtin_ia32_tdpbf16ps_internal(m, n, k, dst, src1, src2); } @@ -323,10 +323,10 @@ static void __tile_zero(__tile1024i *dst) { } __DEFAULT_FN_ATTRS_BF16 -static void __tile_tdpbf16ps(__tile1024i *dst, __tile1024i src1, - __tile1024i src2) { - dst->tile = _tile_tdpbf16ps_internal(src1.row, src2.col, src1.col, dst->tile, - src1.tile, src2.tile); +static void __tile_dpbf16ps(__tile1024i *dst, __tile1024i src1, + __tile1024i src2) { + dst->tile = _tile_dpbf16ps_internal(src1.row, src2.col, src1.col, dst->tile, + src1.tile, src2.tile); } #undef __DEFAULT_FN_ATTRS_TILE diff --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h index c156d89c1f84..45fac248dadb 100644 --- a/clang/lib/Headers/arm_acle.h +++ b/clang/lib/Headers/arm_acle.h @@ -639,6 +639,49 @@ __jcvt(double __a) { } #endif +/* Armv8.5-A FP rounding intrinsics */ +#if __ARM_64BIT_STATE && defined(__ARM_FEATURE_FRINT) +static __inline__ float __attribute__((__always_inline__, __nodebug__)) +__frint32zf(float __a) { + return __builtin_arm_frint32zf(__a); +} + +static __inline__ double __attribute__((__always_inline__, __nodebug__)) +__frint32z(double __a) { + return __builtin_arm_frint32z(__a); +} + +static __inline__ float __attribute__((__always_inline__, __nodebug__)) +__frint64zf(float __a) { + return __builtin_arm_frint64zf(__a); +} + +static __inline__ double __attribute__((__always_inline__, __nodebug__)) +__frint64z(double __a) { + return __builtin_arm_frint64z(__a); +} + +static __inline__ float __attribute__((__always_inline__, __nodebug__)) +__frint32xf(float __a) { + return __builtin_arm_frint32xf(__a); +} + +static __inline__ double __attribute__((__always_inline__, __nodebug__)) +__frint32x(double __a) { + return __builtin_arm_frint32x(__a); +} + +static __inline__ float __attribute__((__always_inline__, __nodebug__)) +__frint64xf(float __a) { + return __builtin_arm_frint64xf(__a); +} + +static __inline__ double __attribute__((__always_inline__, __nodebug__)) +__frint64x(double __a) { + return __builtin_arm_frint64x(__a); +} +#endif + /* Armv8.7-A load/store 64-byte intrinsics */ #if __ARM_64BIT_STATE && defined(__ARM_FEATURE_LS64) typedef struct { @@ -709,6 +752,18 @@ __arm_st64bv0(void *__addr, data512_t __value) { #endif /* __ARM_FEATURE_TME */ +/* Armv8.5-A Random number generation intrinsics */ +#if __ARM_64BIT_STATE && defined(__ARM_FEATURE_RNG) +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +__rndr(uint64_t *__p) { + return __builtin_arm_rndr(__p); +} +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +__rndrrs(uint64_t *__p) { + return __builtin_arm_rndrrs(__p); +} +#endif + #if defined(__cplusplus) } #endif diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index 22f7a520c929..56d3dadf6a33 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -72,11 +72,6 @@ #include #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__VPCLMULQDQ__) -#include -#endif - /* No feature check desired due to internal checks */ #include @@ -230,6 +225,11 @@ #include #endif +#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ + defined(__VPCLMULQDQ__) +#include +#endif + #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ defined(__VAES__) #include diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h index 8bc669214f4f..6a532db4b1cb 100644 --- a/clang/lib/Headers/opencl-c.h +++ b/clang/lib/Headers/opencl-c.h @@ -9907,6 +9907,7 @@ ulong16 __ovld __cnfn upsample(uint16 hi, uint16 lo); /* * popcount(x): returns the number of set bit in x */ +#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2) char __ovld __cnfn popcount(char x); uchar __ovld __cnfn popcount(uchar x); char2 __ovld __cnfn popcount(char2 x); @@ -9955,6 +9956,7 @@ long8 __ovld __cnfn popcount(long8 x); ulong8 __ovld __cnfn popcount(ulong8 x); long16 __ovld __cnfn popcount(long16 x); ulong16 __ovld __cnfn popcount(ulong16 x); +#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2) /** * Multiply two 24-bit integer values x and y and add @@ -13393,7 +13395,6 @@ ulong __ovld atomic_fetch_max_explicit(volatile atomic_ulong *object, ulong oper // OpenCL v2.0 s6.13.11.7.5: // add/sub: atomic type argument can be uintptr_t/intptr_t, value type argument can be ptrdiff_t. -// or/xor/and/min/max: atomic type argument can be intptr_t/uintptr_t, value type argument can be intptr_t/uintptr_t. #if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) uintptr_t __ovld atomic_fetch_add(volatile atomic_uintptr_t *object, ptrdiff_t operand); @@ -13402,38 +13403,6 @@ uintptr_t __ovld atomic_fetch_add_explicit(volatile atomic_uintptr_t *object, pt uintptr_t __ovld atomic_fetch_sub(volatile atomic_uintptr_t *object, ptrdiff_t operand); uintptr_t __ovld atomic_fetch_sub_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order); uintptr_t __ovld atomic_fetch_sub_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order, memory_scope scope); - -uintptr_t __ovld atomic_fetch_or(volatile atomic_uintptr_t *object, intptr_t operand); -uintptr_t __ovld atomic_fetch_or_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order); -uintptr_t __ovld atomic_fetch_or_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order, memory_scope scope); -uintptr_t __ovld atomic_fetch_xor(volatile atomic_uintptr_t *object, intptr_t operand); -uintptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order); -uintptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order, memory_scope scope); -uintptr_t __ovld atomic_fetch_and(volatile atomic_uintptr_t *object, intptr_t operand); -uintptr_t __ovld atomic_fetch_and_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order); -uintptr_t __ovld atomic_fetch_and_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order, memory_scope scope); -uintptr_t __ovld atomic_fetch_min(volatile atomic_uintptr_t *object, intptr_t opermax); -uintptr_t __ovld atomic_fetch_min_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder); -uintptr_t __ovld atomic_fetch_min_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder, memory_scope scope); -uintptr_t __ovld atomic_fetch_max(volatile atomic_uintptr_t *object, intptr_t opermax); -uintptr_t __ovld atomic_fetch_max_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder); -uintptr_t __ovld atomic_fetch_max_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder, memory_scope scope); - -intptr_t __ovld atomic_fetch_or(volatile atomic_intptr_t *object, uintptr_t operand); -intptr_t __ovld atomic_fetch_or_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order); -intptr_t __ovld atomic_fetch_or_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order, memory_scope scope); -intptr_t __ovld atomic_fetch_xor(volatile atomic_intptr_t *object, uintptr_t operand); -intptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order); -intptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order, memory_scope scope); -intptr_t __ovld atomic_fetch_and(volatile atomic_intptr_t *object, uintptr_t operand); -intptr_t __ovld atomic_fetch_and_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order); -intptr_t __ovld atomic_fetch_and_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order, memory_scope scope); -intptr_t __ovld atomic_fetch_min(volatile atomic_intptr_t *object, uintptr_t opermax); -intptr_t __ovld atomic_fetch_min_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder); -intptr_t __ovld atomic_fetch_min_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder, memory_scope scope); -intptr_t __ovld atomic_fetch_max(volatile atomic_intptr_t *object, uintptr_t opermax); -intptr_t __ovld atomic_fetch_max_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder); -intptr_t __ovld atomic_fetch_max_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder, memory_scope scope); #endif // atomic_store() diff --git a/clang/lib/Headers/vaesintrin.h b/clang/lib/Headers/vaesintrin.h index c4d5c3e75140..f3c0807bb94a 100644 --- a/clang/lib/Headers/vaesintrin.h +++ b/clang/lib/Headers/vaesintrin.h @@ -28,13 +28,6 @@ static __inline__ __m256i __DEFAULT_FN_ATTRS (__v4di) __B); } -static __inline__ __m512i __DEFAULT_FN_ATTRS_F - _mm512_aesenc_epi128(__m512i __A, __m512i __B) -{ - return (__m512i) __builtin_ia32_aesenc512((__v8di) __A, - (__v8di) __B); -} - static __inline__ __m256i __DEFAULT_FN_ATTRS _mm256_aesdec_epi128(__m256i __A, __m256i __B) { @@ -42,32 +35,40 @@ static __inline__ __m256i __DEFAULT_FN_ATTRS (__v4di) __B); } -static __inline__ __m512i __DEFAULT_FN_ATTRS_F - _mm512_aesdec_epi128(__m512i __A, __m512i __B) +static __inline__ __m256i __DEFAULT_FN_ATTRS + _mm256_aesenclast_epi128(__m256i __A, __m256i __B) { - return (__m512i) __builtin_ia32_aesdec512((__v8di) __A, - (__v8di) __B); + return (__m256i) __builtin_ia32_aesenclast256((__v4di) __A, + (__v4di) __B); } static __inline__ __m256i __DEFAULT_FN_ATTRS - _mm256_aesenclast_epi128(__m256i __A, __m256i __B) + _mm256_aesdeclast_epi128(__m256i __A, __m256i __B) { - return (__m256i) __builtin_ia32_aesenclast256((__v4di) __A, + return (__m256i) __builtin_ia32_aesdeclast256((__v4di) __A, (__v4di) __B); } +#ifdef __AVX512FINTRIN_H static __inline__ __m512i __DEFAULT_FN_ATTRS_F - _mm512_aesenclast_epi128(__m512i __A, __m512i __B) + _mm512_aesenc_epi128(__m512i __A, __m512i __B) { - return (__m512i) __builtin_ia32_aesenclast512((__v8di) __A, + return (__m512i) __builtin_ia32_aesenc512((__v8di) __A, (__v8di) __B); } -static __inline__ __m256i __DEFAULT_FN_ATTRS - _mm256_aesdeclast_epi128(__m256i __A, __m256i __B) +static __inline__ __m512i __DEFAULT_FN_ATTRS_F + _mm512_aesdec_epi128(__m512i __A, __m512i __B) { - return (__m256i) __builtin_ia32_aesdeclast256((__v4di) __A, - (__v4di) __B); + return (__m512i) __builtin_ia32_aesdec512((__v8di) __A, + (__v8di) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS_F + _mm512_aesenclast_epi128(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_aesenclast512((__v8di) __A, + (__v8di) __B); } static __inline__ __m512i __DEFAULT_FN_ATTRS_F @@ -76,7 +77,7 @@ static __inline__ __m512i __DEFAULT_FN_ATTRS_F return (__m512i) __builtin_ia32_aesdeclast512((__v8di) __A, (__v8di) __B); } - +#endif // __AVX512FINTRIN_H #undef __DEFAULT_FN_ATTRS #undef __DEFAULT_FN_ATTRS_F diff --git a/clang/lib/Headers/vpclmulqdqintrin.h b/clang/lib/Headers/vpclmulqdqintrin.h index 470d83254905..44daadb07d57 100644 --- a/clang/lib/Headers/vpclmulqdqintrin.h +++ b/clang/lib/Headers/vpclmulqdqintrin.h @@ -19,10 +19,12 @@ (__v4di)(__m256i)(B), \ (char)(I)) +#ifdef __AVX512FINTRIN_H #define _mm512_clmulepi64_epi128(A, B, I) \ (__m512i)__builtin_ia32_pclmulqdq512((__v8di)(__m512i)(A), \ (__v8di)(__m512i)(B), \ (char)(I)) +#endif // __AVX512FINTRIN_H #endif /* __VPCLMULQDQINTRIN_H */ diff --git a/clang/lib/Headers/wasm_simd128.h b/clang/lib/Headers/wasm_simd128.h index ac88516ac924..eb2a42f303b6 100644 --- a/clang/lib/Headers/wasm_simd128.h +++ b/clang/lib/Headers/wasm_simd128.h @@ -616,14 +616,12 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_add(v128_t __a, static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_add_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_add_saturate_s_i8x16((__i8x16)__a, - (__i8x16)__b); + return (v128_t)__builtin_wasm_add_sat_s_i8x16((__i8x16)__a, (__i8x16)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_add_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_add_saturate_u_i8x16((__u8x16)__a, - (__u8x16)__b); + return (v128_t)__builtin_wasm_add_sat_u_i8x16((__u8x16)__a, (__u8x16)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_sub(v128_t __a, @@ -633,14 +631,12 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_sub(v128_t __a, static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_sub_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_sub_saturate_s_i8x16((__i8x16)__a, - (__i8x16)__b); + return (v128_t)__builtin_wasm_sub_sat_s_i8x16((__i8x16)__a, (__i8x16)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_sub_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_sub_saturate_u_i8x16((__u8x16)__a, - (__u8x16)__b); + return (v128_t)__builtin_wasm_sub_sat_u_i8x16((__u8x16)__a, (__u8x16)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_min(v128_t __a, @@ -706,14 +702,12 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_add(v128_t __a, static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_add_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_add_saturate_s_i16x8((__i16x8)__a, - (__i16x8)__b); + return (v128_t)__builtin_wasm_add_sat_s_i16x8((__i16x8)__a, (__i16x8)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_add_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_add_saturate_u_i16x8((__u16x8)__a, - (__u16x8)__b); + return (v128_t)__builtin_wasm_add_sat_u_i16x8((__u16x8)__a, (__u16x8)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_sub(v128_t __a, @@ -723,14 +717,12 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_sub(v128_t __a, static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_sub_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_sub_saturate_s_i16x8((__i16x8)__a, - (__i16x8)__b); + return (v128_t)__builtin_wasm_sub_sat_s_i16x8((__i16x8)__a, (__i16x8)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_sub_saturate(v128_t __a, v128_t __b) { - return (v128_t)__builtin_wasm_sub_saturate_u_i16x8((__u16x8)__a, - (__u16x8)__b); + return (v128_t)__builtin_wasm_sub_sat_u_i16x8((__u16x8)__a, (__u16x8)__b); } static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_mul(v128_t __a, @@ -833,18 +825,6 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_neg(v128_t __a) { return (v128_t)(-(__u64x2)__a); } -#ifdef __wasm_unimplemented_simd128__ - -static __inline__ bool __DEFAULT_FN_ATTRS wasm_i64x2_any_true(v128_t __a) { - return __builtin_wasm_any_true_i64x2((__i64x2)__a); -} - -static __inline__ bool __DEFAULT_FN_ATTRS wasm_i64x2_all_true(v128_t __a) { - return __builtin_wasm_all_true_i64x2((__i64x2)__a); -} - -#endif // __wasm_unimplemented_simd128__ - static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_shl(v128_t __a, int32_t __b) { return (v128_t)((__i64x2)__a << (int64_t)__b); @@ -887,24 +867,6 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_sqrt(v128_t __a) { return (v128_t)__builtin_wasm_sqrt_f32x4((__f32x4)__a); } -#ifdef __wasm_unimplemented_simd128__ - -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_qfma(v128_t __a, - v128_t __b, - v128_t __c) { - return (v128_t)__builtin_wasm_qfma_f32x4((__f32x4)__a, (__f32x4)__b, - (__f32x4)__c); -} - -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_qfms(v128_t __a, - v128_t __b, - v128_t __c) { - return (v128_t)__builtin_wasm_qfms_f32x4((__f32x4)__a, (__f32x4)__b, - (__f32x4)__c); -} - -#endif // __wasm_unimplemented_simd128__ - static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_add(v128_t __a, v128_t __b) { return (v128_t)((__f32x4)__a + (__f32x4)__b); @@ -957,24 +919,6 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_sqrt(v128_t __a) { return (v128_t)__builtin_wasm_sqrt_f64x2((__f64x2)__a); } -#ifdef __wasm_unimplemented_simd128__ - -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_qfma(v128_t __a, - v128_t __b, - v128_t __c) { - return (v128_t)__builtin_wasm_qfma_f64x2((__f64x2)__a, (__f64x2)__b, - (__f64x2)__c); -} - -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_qfms(v128_t __a, - v128_t __b, - v128_t __c) { - return (v128_t)__builtin_wasm_qfms_f64x2((__f64x2)__a, (__f64x2)__b, - (__f64x2)__c); -} - -#endif // __wasm_unimplemented_simd128__ - static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_add(v128_t __a, v128_t __b) { return (v128_t)((__f64x2)__a + (__f64x2)__b); diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 34732b659771..75c0fb65f5b1 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1788,12 +1788,14 @@ bool Lexer::LexNumericConstant(Token &Result, const char *CurPtr) { } // If we have a digit separator, continue. - if (C == '\'' && getLangOpts().CPlusPlus14) { + if (C == '\'' && (getLangOpts().CPlusPlus14 || getLangOpts().C2x)) { unsigned NextSize; char Next = getCharAndSizeNoWarn(CurPtr + Size, NextSize, getLangOpts()); if (isIdentifierBody(Next)) { if (!isLexingRawMode()) - Diag(CurPtr, diag::warn_cxx11_compat_digit_separator); + Diag(CurPtr, getLangOpts().CPlusPlus + ? diag::warn_cxx11_compat_digit_separator + : diag::warn_c2x_compat_digit_separator); CurPtr = ConsumeChar(CurPtr, Size, Result); CurPtr = ConsumeChar(CurPtr, NextSize, Result); return LexNumericConstant(Result, CurPtr); @@ -2059,7 +2061,7 @@ bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) { if (C == '\\') C = getAndAdvanceChar(CurPtr, Result); - if (C == '\n' || C == '\r' || // Newline. + if (isVerticalWhitespace(C) || // Newline. (C == 0 && (CurPtr - 1 == BufferEnd))) { // End of file. // If the filename is unterminated, then it must just be a lone < // character. Return this as such. @@ -3206,10 +3208,10 @@ bool Lexer::LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine) { const char *CurPtr = BufferPtr; // Small amounts of horizontal whitespace is very common between tokens. - if ((*CurPtr == ' ') || (*CurPtr == '\t')) { - ++CurPtr; - while ((*CurPtr == ' ') || (*CurPtr == '\t')) + if (isHorizontalWhitespace(*CurPtr)) { + do { ++CurPtr; + } while (isHorizontalWhitespace(*CurPtr)); // If we are keeping whitespace and other tokens, just return what we just // skipped. The next lexer invocation will return the token after the diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 6c3cdbdf6492..bfcb3c478b62 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -546,6 +546,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, isLong = false; isUnsigned = false; isLongLong = false; + isSizeT = false; isHalf = false; isFloat = false; isImaginary = false; @@ -589,6 +590,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // integer constant. bool isFixedPointConstant = isFixedPointLiteral(); bool isFPConstant = isFloatingLiteral(); + bool HasSize = false; // Loop over all of the characters of the suffix. If we see something bad, // we break out of the loop. @@ -616,14 +618,17 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (!(LangOpts.Half || LangOpts.FixedPoint)) break; if (isIntegerLiteral()) break; // Error for integer constant. - if (isHalf || isFloat || isLong) break; // HH, FH, LH invalid. + if (HasSize) + break; + HasSize = true; isHalf = true; continue; // Success. case 'f': // FP Suffix for "float" case 'F': if (!isFPConstant) break; // Error for integer constant. - if (isHalf || isFloat || isLong || isFloat128) - break; // HF, FF, LF, QF invalid. + if (HasSize) + break; + HasSize = true; // CUDA host and device may have different _Float16 support, therefore // allows f16 literals to avoid false alarm. @@ -640,8 +645,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, case 'q': // FP Suffix for "__float128" case 'Q': if (!isFPConstant) break; // Error for integer constant. - if (isHalf || isFloat || isLong || isFloat128) - break; // HQ, FQ, LQ, QQ invalid. + if (HasSize) + break; + HasSize = true; isFloat128 = true; continue; // Success. case 'u': @@ -652,8 +658,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, continue; // Success. case 'l': case 'L': - if (isLong || isLongLong) break; // Cannot be repeated. - if (isHalf || isFloat || isFloat128) break; // LH, LF, LQ invalid. + if (HasSize) + break; + HasSize = true; // Check for long long. The L's need to be adjacent and the same case. if (s[1] == s[0]) { @@ -665,42 +672,54 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, isLong = true; } continue; // Success. + case 'z': + case 'Z': + if (isFPConstant) + break; // Invalid for floats. + if (HasSize) + break; + HasSize = true; + isSizeT = true; + continue; case 'i': case 'I': - if (LangOpts.MicrosoftExt) { - if (isLong || isLongLong || MicrosoftInteger) + if (LangOpts.MicrosoftExt && !isFPConstant) { + // Allow i8, i16, i32, and i64. First, look ahead and check if + // suffixes are Microsoft integers and not the imaginary unit. + uint8_t Bits = 0; + size_t ToSkip = 0; + switch (s[1]) { + case '8': // i8 suffix + Bits = 8; + ToSkip = 2; break; - - if (!isFPConstant) { - // Allow i8, i16, i32, and i64. - switch (s[1]) { - case '8': - s += 2; // i8 suffix - MicrosoftInteger = 8; - break; - case '1': - if (s[2] == '6') { - s += 3; // i16 suffix - MicrosoftInteger = 16; - } - break; - case '3': - if (s[2] == '2') { - s += 3; // i32 suffix - MicrosoftInteger = 32; - } - break; - case '6': - if (s[2] == '4') { - s += 3; // i64 suffix - MicrosoftInteger = 64; - } - break; - default: - break; + case '1': + if (s[2] == '6') { // i16 suffix + Bits = 16; + ToSkip = 3; + } + break; + case '3': + if (s[2] == '2') { // i32 suffix + Bits = 32; + ToSkip = 3; + } + break; + case '6': + if (s[2] == '4') { // i64 suffix + Bits = 64; + ToSkip = 3; } + break; + default: + break; } - if (MicrosoftInteger) { + if (Bits) { + if (HasSize) + break; + HasSize = true; + MicrosoftInteger = Bits; + s += ToSkip; assert(s <= ThisTokEnd && "didn't maximally munch?"); break; } @@ -727,6 +746,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, isLong = false; isUnsigned = false; isLongLong = false; + isSizeT = false; isFloat = false; isFloat16 = false; isHalf = false; @@ -1628,16 +1648,28 @@ void StringLiteralParser::init(ArrayRef StringToks){ // Check for raw string if (ThisTokBuf[0] == 'R') { + if (ThisTokBuf[1] != '"') { + // The file may have come from PCH and then changed after loading the + // PCH; Fail gracefully. + return DiagnoseLexingError(StringToks[i].getLocation()); + } ThisTokBuf += 2; // skip R" + // C++11 [lex.string]p2: A `d-char-sequence` shall consist of at most 16 + // characters. + constexpr unsigned MaxRawStrDelimLen = 16; + const char *Prefix = ThisTokBuf; - while (ThisTokBuf[0] != '(') + while (ThisTokBuf - Prefix < MaxRawStrDelimLen && ThisTokBuf[0] != '(') ++ThisTokBuf; + if (ThisTokBuf[0] != '(') + return DiagnoseLexingError(StringToks[i].getLocation()); ++ThisTokBuf; // skip '(' // Remove same number of characters from the end ThisTokEnd -= ThisTokBuf - Prefix; - assert(ThisTokEnd >= ThisTokBuf && "malformed raw string literal"); + if (ThisTokEnd < ThisTokBuf) + return DiagnoseLexingError(StringToks[i].getLocation()); // C++14 [lex.string]p4: A source-file new-line in a raw string literal // results in a new-line in the resulting execution string-literal. diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index c854d3e9c02b..a771b7c5d122 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -124,7 +124,7 @@ static bool isReservedId(StringRef Text, const LangOptions &Lang) { // the specified module, meaning clang won't build the specified module. This is // useful in a number of situations, for instance, when building a library that // vends a module map, one might want to avoid hitting intermediate build -// products containimg the the module map or avoid finding the system installed +// products containing the the module map or avoid finding the system installed // modulemap for that library. static bool isForModuleBuilding(Module *M, StringRef CurrentModule, StringRef ModuleName) { @@ -441,9 +441,9 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, CurLexer->Lex(Tok); if (Tok.is(tok::code_completion)) { + setCodeCompletionReached(); if (CodeComplete) CodeComplete->CodeCompleteInConditionalExclusion(); - setCodeCompletionReached(); continue; } @@ -966,10 +966,10 @@ void Preprocessor::HandleDirective(Token &Result) { case tok::eod: return; // null directive. case tok::code_completion: + setCodeCompletionReached(); if (CodeComplete) CodeComplete->CodeCompleteDirective( CurPPLexer->getConditionalStackDepth() > 0); - setCodeCompletionReached(); return; case tok::numeric_constant: // # 7 GNU line marker directive. if (getLangOpts().AsmPreprocessor) @@ -1045,12 +1045,12 @@ void Preprocessor::HandleDirective(Token &Result) { break; case tok::pp___public_macro: - if (getLangOpts().Modules) + if (getLangOpts().Modules || getLangOpts().ModulesLocalVisibility) return HandleMacroPublicDirective(Result); break; case tok::pp___private_macro: - if (getLangOpts().Modules) + if (getLangOpts().Modules || getLangOpts().ModulesLocalVisibility) return HandleMacroPrivateDirective(); break; } diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 8c120c13d7d2..8537b31b9dc9 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -321,6 +321,14 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, PP.Diag(PeekTok, diag::ext_c99_longlong); } + // 'z/uz' literals are a C++2b feature. + if (Literal.isSizeT) + PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus + ? PP.getLangOpts().CPlusPlus2b + ? diag::warn_cxx20_compat_size_t_suffix + : diag::ext_cxx2b_size_t_suffix + : diag::err_cxx2b_size_t_suffix); + // Parse the integer literal into Result. if (Literal.GetIntegerValue(Result.Val)) { // Overflow parsing integer literal. diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 43d31d6c5732..9528a8f575f0 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -170,7 +170,8 @@ ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, IdentifierInfo *II, return MM; } -ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) { +ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, + const IdentifierInfo *II) { llvm::FoldingSetNodeID ID; ModuleMacro::Profile(ID, Mod, II); diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index a05df060813e..5b42241a32c2 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -1122,6 +1122,57 @@ struct PragmaDebugHandler : public PragmaHandler { DebugOverflowStack(); } else if (II->isStr("captured")) { HandleCaptured(PP); + } else if (II->isStr("modules")) { + struct ModuleVisitor { + Preprocessor &PP; + void visit(Module *M, bool VisibleOnly) { + SourceLocation ImportLoc = PP.getModuleImportLoc(M); + if (!VisibleOnly || ImportLoc.isValid()) { + llvm::errs() << M->getFullModuleName() << " "; + if (ImportLoc.isValid()) { + llvm::errs() << M << " visible "; + ImportLoc.print(llvm::errs(), PP.getSourceManager()); + } + llvm::errs() << "\n"; + } + for (Module *Sub : M->submodules()) { + if (!VisibleOnly || ImportLoc.isInvalid() || Sub->IsExplicit) + visit(Sub, VisibleOnly); + } + } + void visitAll(bool VisibleOnly) { + for (auto &NameAndMod : + PP.getHeaderSearchInfo().getModuleMap().modules()) + visit(NameAndMod.second, VisibleOnly); + } + } Visitor{PP}; + + Token Kind; + PP.LexUnexpandedToken(Kind); + auto *DumpII = Kind.getIdentifierInfo(); + if (!DumpII) { + PP.Diag(Kind, diag::warn_pragma_debug_missing_argument) + << II->getName(); + } else if (DumpII->isStr("all")) { + Visitor.visitAll(false); + } else if (DumpII->isStr("visible")) { + Visitor.visitAll(true); + } else if (DumpII->isStr("building")) { + for (auto &Building : PP.getBuildingSubmodules()) { + llvm::errs() << "in " << Building.M->getFullModuleName(); + if (Building.ImportLoc.isValid()) { + llvm::errs() << " imported "; + if (Building.IsPragma) + llvm::errs() << "via pragma "; + llvm::errs() << "at "; + Building.ImportLoc.print(llvm::errs(), PP.getSourceManager()); + llvm::errs() << "\n"; + } + } + } else { + PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command) + << DumpII->getName(); + } } else { PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command) << II->getName(); diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 177786d90390..e39b78d5ffec 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -442,15 +442,15 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, void Preprocessor::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) { + setCodeCompletionReached(); if (CodeComplete) CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled); - setCodeCompletionReached(); } void Preprocessor::CodeCompleteNaturalLanguage() { + setCodeCompletionReached(); if (CodeComplete) CodeComplete->CodeCompleteNaturalLanguage(); - setCodeCompletionReached(); } /// getSpelling - This method is used to get the spelling of a token into a diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 069f981d1b02..104b1b54f578 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1607,7 +1607,30 @@ void Parser::DiagnoseProhibitedAttributes( } void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, - unsigned DiagID) { + unsigned DiagID, bool DiagnoseEmptyAttrs) { + + if (DiagnoseEmptyAttrs && Attrs.empty() && Attrs.Range.isValid()) { + // An attribute list has been parsed, but it was empty. + // This is the case for [[]]. + const auto &LangOpts = getLangOpts(); + auto &SM = PP.getSourceManager(); + Token FirstLSquare; + Lexer::getRawToken(Attrs.Range.getBegin(), FirstLSquare, SM, LangOpts); + + if (FirstLSquare.is(tok::l_square)) { + llvm::Optional SecondLSquare = + Lexer::findNextToken(FirstLSquare.getLocation(), SM, LangOpts); + + if (SecondLSquare && SecondLSquare->is(tok::l_square)) { + // The attribute range starts with [[, but is empty. So this must + // be [[]], which we are supposed to diagnose because + // DiagnoseEmptyAttrs is true. + Diag(Attrs.Range.getBegin(), DiagID) << Attrs.Range; + return; + } + } + } + for (const ParsedAttr &AL : Attrs) { if (!AL.isCXX11Attribute() && !AL.isC2xAttribute()) continue; @@ -1970,8 +1993,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, // Check to see if we have a function *definition* which must have a body. if (D.isFunctionDeclarator()) { if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) { - Actions.CodeCompleteAfterFunctionEquals(D); cutOffParsing(); + Actions.CodeCompleteAfterFunctionEquals(D); return nullptr; } // Look at the next token to make sure that this isn't a function @@ -2310,9 +2333,9 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( InitializerScopeRAII InitScope(*this, D, ThisDecl); if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); Actions.FinalizeDeclaration(ThisDecl); - cutOffParsing(); return nullptr; } @@ -3090,10 +3113,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, = DSContext == DeclSpecContext::DSC_top_level || (DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified()); + cutOffParsing(); Actions.CodeCompleteDeclSpec(getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers); - return cutOffParsing(); + return; } if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) @@ -3106,8 +3130,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, else if (CurParsedObjCImpl) CCC = Sema::PCC_ObjCImplementation; + cutOffParsing(); Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); - return cutOffParsing(); + return; } case tok::coloncolon: // ::foo::bar @@ -3646,8 +3671,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // C++ for OpenCL does not allow virtual function qualifier, to avoid // function pointers restricted in OpenCL v2.0 s6.9.a. if (getLangOpts().OpenCLCPlusPlus && - !getActions().getOpenCLOptions().isEnabled( - "__cl_clang_function_pointers")) { + !getActions().getOpenCLOptions().isAvailableOption( + "__cl_clang_function_pointers", getLangOpts())) { DiagID = diag::err_openclcxx_virtual_function; PrevSpec = Tok.getIdentifierInfo()->getNameStart(); isInvalid = true; @@ -4362,8 +4387,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, // Parse the tag portion of this. if (Tok.is(tok::code_completion)) { // Code completion for an enum name. + cutOffParsing(); Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); - return cutOffParsing(); + return; } // If attributes exist after tag, parse them. @@ -4627,7 +4653,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, // or opaque-enum-declaration anywhere. if (IsElaboratedTypeSpecifier && !getLangOpts().MicrosoftExt && !getLangOpts().ObjC) { - ProhibitAttributes(attrs); + ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, + /*DiagnoseEmptyAttrs=*/true); if (BaseType.isUsable()) Diag(BaseRange.getBegin(), diag::ext_enum_base_in_type_specifier) << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange; @@ -5457,11 +5484,12 @@ void Parser::ParseTypeQualifierListOpt( switch (Tok.getKind()) { case tok::code_completion: + cutOffParsing(); if (CodeCompletionHandler) (*CodeCompletionHandler)(); else Actions.CodeCompleteTypeQualifiers(DS); - return cutOffParsing(); + return; case tok::kw_const: isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, @@ -6998,8 +7026,9 @@ void Parser::ParseBracketDeclarator(Declarator &D) { std::move(attrs), T.getCloseLocation()); return; } else if (Tok.getKind() == tok::code_completion) { + cutOffParsing(); Actions.CodeCompleteBracketDeclarator(getCurScope()); - return cutOffParsing(); + return; } // If valid, this location is the position where we read the 'static' keyword. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index df71ba34cdd9..829ed179f54c 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -63,8 +63,8 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context, ObjCDeclContextSwitch ObjCDC(*this); if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteNamespaceDecl(getCurScope()); cutOffParsing(); + Actions.CodeCompleteNamespaceDecl(getCurScope()); return nullptr; } @@ -283,8 +283,8 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, ConsumeToken(); // eat the '='. if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteNamespaceAliasDecl(getCurScope()); cutOffParsing(); + Actions.CodeCompleteNamespaceAliasDecl(getCurScope()); return nullptr; } @@ -471,8 +471,8 @@ Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context, SourceLocation UsingLoc = ConsumeToken(); if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteUsing(getCurScope()); cutOffParsing(); + Actions.CodeCompleteUsing(getCurScope()); return nullptr; } @@ -525,8 +525,8 @@ Decl *Parser::ParseUsingDirective(DeclaratorContext Context, SourceLocation NamespcLoc = ConsumeToken(); if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteUsingDirective(getCurScope()); cutOffParsing(); + Actions.CodeCompleteUsingDirective(getCurScope()); return nullptr; } @@ -1433,8 +1433,9 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, if (Tok.is(tok::code_completion)) { // Code completion for a struct, class, or union name. + cutOffParsing(); Actions.CodeCompleteTag(getCurScope(), TagType); - return cutOffParsing(); + return; } // C++03 [temp.explicit] 14.7.2/8: @@ -1835,7 +1836,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && TUK == Sema::TUK_Declaration) { // This is an explicit instantiation of a class template. - ProhibitAttributes(attrs); + ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, + /*DiagnoseEmptyAttrs=*/true); TagOrTempResult = Actions.ActOnExplicitInstantiation( getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, @@ -1931,7 +1933,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateParams ? TemplateParams->size() : 0)); } else { if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) - ProhibitAttributes(attrs); + ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, + /* DiagnoseEmptyAttrs=*/true); if (TUK == Sema::TUK_Definition && TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { @@ -2749,8 +2752,8 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, else if (KW.is(tok::kw_delete)) DefinitionKind = FunctionDefinitionKind::Deleted; else if (KW.is(tok::code_completion)) { - Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo); cutOffParsing(); + Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo); return nullptr; } } @@ -3417,15 +3420,6 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // declarations and the lexed inline method definitions, along with any // delayed attributes. - // Save the state of Sema.FPFeatures, and change the setting - // to the levels specified on the command line. Previous level - // will be restored when the RAII object is destroyed. - Sema::FPFeaturesStateRAII SaveFPFeaturesState(Actions); - FPOptionsOverride NewOverrides; - Actions.CurFPFeatures = NewOverrides.applyOverrides(getLangOpts()); - Actions.FpPragmaStack.Act(Tok.getLocation(), Sema::PSK_Reset, StringRef(), - {} /*unused*/); - SourceLocation SavedPrevTokLocation = PrevTokLocation; ParseLexedPragmas(getCurrentClass()); ParseLexedAttributes(getCurrentClass()); @@ -3507,9 +3501,10 @@ void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) { do { if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteConstructorInitializer(ConstructorDecl, MemInitializers); - return cutOffParsing(); + return; } MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 3b0dd3f4036f..c2b47f6375b8 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -159,9 +159,9 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { /// Parse an expr that doesn't include (top-level) commas. ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteExpression(getCurScope(), PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); } @@ -1156,9 +1156,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, ConsumeToken(); if (Tok.is(tok::code_completion) && &II != Ident_super) { + cutOffParsing(); Actions.CodeCompleteObjCClassPropertyRefExpr( getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc); - cutOffParsing(); return ExprError(); } // Allow either an identifier or the keyword 'class' (in C++). @@ -1724,9 +1724,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, Res = ParseBlockLiteralExpression(); break; case tok::code_completion: { + cutOffParsing(); Actions.CodeCompleteExpression(getCurScope(), PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); } case tok::l_square: @@ -1807,8 +1807,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // These can be followed by postfix-expr pieces. PreferredType = SavedType; Res = ParsePostfixExpressionSuffix(Res); - if (getLangOpts().OpenCL && !getActions().getOpenCLOptions().isEnabled( - "__cl_clang_function_pointers")) + if (getLangOpts().OpenCL && + !getActions().getOpenCLOptions().isAvailableOption( + "__cl_clang_function_pointers", getLangOpts())) if (Expr *PostfixExpr = Res.get()) { QualType Ty = PostfixExpr->getType(); if (!Ty.isNull() && Ty->isFunctionType()) { @@ -1855,9 +1856,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (InMessageExpression) return LHS; + cutOffParsing(); Actions.CodeCompletePostfixExpression( getCurScope(), LHS, PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); case tok::identifier: @@ -2139,12 +2140,12 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { CorrectedBase = Base; // Code completion for a member access expression. + cutOffParsing(); Actions.CodeCompleteMemberReferenceExpr( getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, Base && ExprStatementTokLoc == Base->getBeginLoc(), PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); } @@ -2777,10 +2778,10 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, CastTy = nullptr; if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteExpression( getCurScope(), PreferredType.get(Tok.getLocation()), /*IsParenthesized=*/ExprType >= CompoundLiteral); - cutOffParsing(); return ExprError(); } @@ -3411,8 +3412,9 @@ Parser::ParseSimpleExpressionList(SmallVectorImpl &Exprs, /// \endverbatim void Parser::ParseBlockId(SourceLocation CaretLoc) { if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); - return cutOffParsing(); + return; } // Parse the specifier-qualifier-list piece. @@ -3597,8 +3599,8 @@ Optional Parser::ParseAvailabilitySpec() { } else { // Parse the platform name. if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteAvailabilityPlatformName(); cutOffParsing(); + Actions.CodeCompleteAvailabilityPlatformName(); return None; } if (Tok.isNot(tok::identifier)) { diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 9292541d7ede..644df55bf46e 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -235,6 +235,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier( while (true) { if (HasScopeSpecifier) { if (Tok.is(tok::code_completion)) { + cutOffParsing(); // Code completion for a nested-name-specifier, where the code // completion token follows the '::'. Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext, @@ -245,7 +246,6 @@ bool Parser::ParseOptionalCXXScopeSpecifier( // token will cause assertion in // Preprocessor::AnnotatePreviousCachedTokens. SS.setEndLoc(Tok.getLocation()); - cutOffParsing(); return true; } @@ -688,9 +688,9 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { /// ParseLambdaExpression - Parse a C++11 lambda expression. /// /// lambda-expression: -/// lambda-introducer lambda-declarator[opt] compound-statement +/// lambda-introducer lambda-declarator compound-statement /// lambda-introducer '<' template-parameter-list '>' -/// lambda-declarator[opt] compound-statement +/// requires-clause[opt] lambda-declarator compound-statement /// /// lambda-introducer: /// '[' lambda-capture[opt] ']' @@ -722,9 +722,13 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { /// '&' identifier initializer /// /// lambda-declarator: -/// '(' parameter-declaration-clause ')' attribute-specifier[opt] -/// 'mutable'[opt] exception-specification[opt] -/// trailing-return-type[opt] +/// lambda-specifiers [C++2b] +/// '(' parameter-declaration-clause ')' lambda-specifiers +/// requires-clause[opt] +/// +/// lambda-specifiers: +/// decl-specifier-seq[opt] noexcept-specifier[opt] +/// attribute-specifier-seq[opt] trailing-return-type[opt] /// ExprResult Parser::ParseLambdaExpression() { // Parse lambda-introducer. @@ -877,9 +881,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, // expression parser perform the completion. if (Tok.is(tok::code_completion) && !(getLangOpts().ObjC && Tentative)) { + cutOffParsing(); Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, /*AfterAmpersand=*/false); - cutOffParsing(); break; } @@ -891,6 +895,7 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, } if (Tok.is(tok::code_completion)) { + cutOffParsing(); // If we're in Objective-C++ and we have a bare '[', then this is more // likely to be a message receiver. if (getLangOpts().ObjC && Tentative && First) @@ -898,7 +903,6 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, else Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, /*AfterAmpersand=*/false); - cutOffParsing(); break; } @@ -943,9 +947,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, ConsumeToken(); if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, /*AfterAmpersand=*/true); - cutOffParsing(); break; } } @@ -1249,7 +1253,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( Actions.PushLambdaScope(); ParsedAttributes Attr(AttrFactory); - SourceLocation DeclLoc = Tok.getLocation(); if (getLangOpts().CUDA) { // In CUDA code, GNU attributes are allowed to appear immediately after the // "[...]", even if there is no "(...)" before the lambda body. @@ -1315,11 +1318,86 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( TypeResult TrailingReturnType; SourceLocation TrailingReturnTypeLoc; + + auto ParseLambdaSpecifiers = + [&](SourceLocation LParenLoc, SourceLocation RParenLoc, + MutableArrayRef ParamInfo, + SourceLocation EllipsisLoc) { + SourceLocation DeclEndLoc = RParenLoc; + + // GNU-style attributes must be parsed before the mutable specifier to + // be compatible with GCC. MSVC-style attributes must be parsed before + // the mutable specifier to be compatible with MSVC. + MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attr); + + // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update + // the DeclEndLoc. + SourceLocation MutableLoc; + SourceLocation ConstexprLoc; + SourceLocation ConstevalLoc; + tryConsumeLambdaSpecifierToken(*this, MutableLoc, ConstexprLoc, + ConstevalLoc, DeclEndLoc); + + addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); + addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); + // Parse exception-specification[opt]. + ExceptionSpecificationType ESpecType = EST_None; + SourceRange ESpecRange; + SmallVector DynamicExceptions; + SmallVector DynamicExceptionRanges; + ExprResult NoexceptExpr; + CachedTokens *ExceptionSpecTokens; + ESpecType = tryParseExceptionSpecification( + /*Delayed=*/false, ESpecRange, DynamicExceptions, + DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens); + + if (ESpecType != EST_None) + DeclEndLoc = ESpecRange.getEnd(); + + // Parse attribute-specifier[opt]. + MaybeParseCXX11Attributes(Attr, &DeclEndLoc); + + // Parse OpenCL addr space attribute. + if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local, + tok::kw___constant, tok::kw___generic)) { + ParseOpenCLQualifiers(DS.getAttributes()); + ConsumeToken(); + } + + SourceLocation FunLocalRangeEnd = DeclEndLoc; + + // Parse trailing-return-type[opt]. + if (Tok.is(tok::arrow)) { + FunLocalRangeEnd = Tok.getLocation(); + SourceRange Range; + TrailingReturnType = ParseTrailingReturnType( + Range, /*MayBeFollowedByDirectInit*/ false); + TrailingReturnTypeLoc = Range.getBegin(); + if (Range.getEnd().isValid()) + DeclEndLoc = Range.getEnd(); + } + + SourceLocation NoLoc; + D.AddTypeInfo( + DeclaratorChunk::getFunction( + /*HasProto=*/true, + /*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(), + ParamInfo.size(), EllipsisLoc, RParenLoc, + /*RefQualifierIsLvalueRef=*/true, + /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, ESpecRange, + DynamicExceptions.data(), DynamicExceptionRanges.data(), + DynamicExceptions.size(), + NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, + /*ExceptionSpecTokens*/ nullptr, + /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D, + TrailingReturnType, TrailingReturnTypeLoc, &DS), + std::move(Attr), DeclEndLoc); + }; + if (Tok.is(tok::l_paren)) { - ParseScope PrototypeScope(this, - Scope::FunctionPrototypeScope | - Scope::FunctionDeclarationScope | - Scope::DeclScope); + ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | + Scope::FunctionDeclarationScope | + Scope::DeclScope); BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); @@ -1345,167 +1423,36 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( } T.consumeClose(); - SourceLocation RParenLoc = T.getCloseLocation(); - SourceLocation DeclEndLoc = RParenLoc; - - // GNU-style attributes must be parsed before the mutable specifier to be - // compatible with GCC. MSVC-style attributes must be parsed before the - // mutable specifier to be compatible with MSVC. - MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attr); - - // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update the - // DeclEndLoc. - SourceLocation MutableLoc; - SourceLocation ConstexprLoc; - SourceLocation ConstevalLoc; - tryConsumeLambdaSpecifierToken(*this, MutableLoc, ConstexprLoc, - ConstevalLoc, DeclEndLoc); - - addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); - addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); - // Parse exception-specification[opt]. - ExceptionSpecificationType ESpecType = EST_None; - SourceRange ESpecRange; - SmallVector DynamicExceptions; - SmallVector DynamicExceptionRanges; - ExprResult NoexceptExpr; - CachedTokens *ExceptionSpecTokens; - ESpecType = tryParseExceptionSpecification(/*Delayed=*/false, - ESpecRange, - DynamicExceptions, - DynamicExceptionRanges, - NoexceptExpr, - ExceptionSpecTokens); - - if (ESpecType != EST_None) - DeclEndLoc = ESpecRange.getEnd(); - - // Parse attribute-specifier[opt]. - MaybeParseCXX11Attributes(Attr, &DeclEndLoc); - - // Parse OpenCL addr space attribute. - if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local, - tok::kw___constant, tok::kw___generic)) { - ParseOpenCLQualifiers(DS.getAttributes()); - ConsumeToken(); - } - SourceLocation FunLocalRangeEnd = DeclEndLoc; - - // Parse trailing-return-type[opt]. - if (Tok.is(tok::arrow)) { - FunLocalRangeEnd = Tok.getLocation(); - SourceRange Range; - TrailingReturnType = - ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false); - TrailingReturnTypeLoc = Range.getBegin(); - if (Range.getEnd().isValid()) - DeclEndLoc = Range.getEnd(); - } - - SourceLocation NoLoc; - D.AddTypeInfo(DeclaratorChunk::getFunction( - /*HasProto=*/true, - /*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(), - ParamInfo.size(), EllipsisLoc, RParenLoc, - /*RefQualifierIsLvalueRef=*/true, - /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, - ESpecRange, DynamicExceptions.data(), - DynamicExceptionRanges.data(), DynamicExceptions.size(), - NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, - /*ExceptionSpecTokens*/ nullptr, - /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D, - TrailingReturnType, TrailingReturnTypeLoc, &DS), - std::move(Attr), DeclEndLoc); + // Parse lambda-specifiers. + ParseLambdaSpecifiers(LParenLoc, /*DeclEndLoc=*/T.getCloseLocation(), + ParamInfo, EllipsisLoc); // Parse requires-clause[opt]. if (Tok.is(tok::kw_requires)) ParseTrailingRequiresClause(D); - - PrototypeScope.Exit(); - - WarnIfHasCUDATargetAttr(); } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, tok::kw_constexpr, tok::kw_consteval, tok::kw___private, tok::kw___global, tok::kw___local, tok::kw___constant, tok::kw___generic, - tok::kw_requires) || + tok::kw_requires, tok::kw_noexcept) || (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) { - // It's common to forget that one needs '()' before 'mutable', an attribute - // specifier, the result type, or the requires clause. Deal with this. - unsigned TokKind = 0; - switch (Tok.getKind()) { - case tok::kw_mutable: TokKind = 0; break; - case tok::arrow: TokKind = 1; break; - case tok::kw___attribute: - case tok::kw___private: - case tok::kw___global: - case tok::kw___local: - case tok::kw___constant: - case tok::kw___generic: - case tok::l_square: TokKind = 2; break; - case tok::kw_constexpr: TokKind = 3; break; - case tok::kw_consteval: TokKind = 4; break; - case tok::kw_requires: TokKind = 5; break; - default: llvm_unreachable("Unknown token kind"); - } - - Diag(Tok, diag::err_lambda_missing_parens) - << TokKind - << FixItHint::CreateInsertion(Tok.getLocation(), "() "); - SourceLocation DeclEndLoc = DeclLoc; - - // GNU-style attributes must be parsed before the mutable specifier to be - // compatible with GCC. - MaybeParseGNUAttributes(Attr, &DeclEndLoc); - - // Parse 'mutable', if it's there. - SourceLocation MutableLoc; - if (Tok.is(tok::kw_mutable)) { - MutableLoc = ConsumeToken(); - DeclEndLoc = MutableLoc; - } - - // Parse attribute-specifier[opt]. - MaybeParseCXX11Attributes(Attr, &DeclEndLoc); - - // Parse the return type, if there is one. - if (Tok.is(tok::arrow)) { - SourceRange Range; - TrailingReturnType = - ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false); - if (Range.getEnd().isValid()) - DeclEndLoc = Range.getEnd(); - } + if (!getLangOpts().CPlusPlus2b) + // It's common to forget that one needs '()' before 'mutable', an + // attribute specifier, the result type, or the requires clause. Deal with + // this. + Diag(Tok, diag::ext_lambda_missing_parens) + << FixItHint::CreateInsertion(Tok.getLocation(), "() "); SourceLocation NoLoc; - D.AddTypeInfo(DeclaratorChunk::getFunction( - /*HasProto=*/true, - /*IsAmbiguous=*/false, - /*LParenLoc=*/NoLoc, - /*Params=*/nullptr, - /*NumParams=*/0, - /*EllipsisLoc=*/NoLoc, - /*RParenLoc=*/NoLoc, - /*RefQualifierIsLvalueRef=*/true, - /*RefQualifierLoc=*/NoLoc, MutableLoc, EST_None, - /*ESpecRange=*/SourceRange(), - /*Exceptions=*/nullptr, - /*ExceptionRanges=*/nullptr, - /*NumExceptions=*/0, - /*NoexceptExpr=*/nullptr, - /*ExceptionSpecTokens=*/nullptr, - /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D, - TrailingReturnType), - std::move(Attr), DeclEndLoc); - - // Parse the requires-clause, if present. - if (Tok.is(tok::kw_requires)) - ParseTrailingRequiresClause(D); - - WarnIfHasCUDATargetAttr(); + // Parse lambda-specifiers. + std::vector EmptyParamInfo; + ParseLambdaSpecifiers(/*LParenLoc=*/NoLoc, /*RParenLoc=*/NoLoc, + EmptyParamInfo, /*EllipsisLoc=*/NoLoc); } + WarnIfHasCUDATargetAttr(); + // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using // it. unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope | @@ -1987,17 +1934,36 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { /// \param FRI If non-null, a for range declaration is permitted, and if /// present will be parsed and stored here, and a null result will be returned. /// +/// \param EnterForConditionScope If true, enter a continue/break scope at the +/// appropriate moment for a 'for' loop. +/// /// \returns The parsed condition. Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc, Sema::ConditionKind CK, - ForRangeInfo *FRI) { + ForRangeInfo *FRI, + bool EnterForConditionScope) { + // Helper to ensure we always enter a continue/break scope if requested. + struct ForConditionScopeRAII { + Scope *S; + void enter(bool IsConditionVariable) { + if (S) { + S->AddFlags(Scope::BreakScope | Scope::ContinueScope); + S->setIsConditionVarScope(IsConditionVariable); + } + } + ~ForConditionScopeRAII() { + if (S) + S->setIsConditionVarScope(false); + } + } ForConditionScope{EnterForConditionScope ? getCurScope() : nullptr}; + ParenBraceBracketBalancer BalancerRAIIObj(*this); PreferredType.enterCondition(Actions, Tok.getLocation()); if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); cutOffParsing(); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); return Sema::ConditionError(); } @@ -2014,6 +1980,9 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, // Determine what kind of thing we have. switch (isCXXConditionDeclarationOrInitStatement(InitStmt, FRI)) { case ConditionOrInitStatement::Expression: { + // If this is a for loop, we're entering its condition. + ForConditionScope.enter(/*IsConditionVariable=*/false); + ProhibitAttributes(attrs); // We can have an empty expression here. @@ -2056,6 +2025,9 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, } case ConditionOrInitStatement::ForRangeDecl: { + // This is 'for (init-stmt; for-range-decl : range-expr)'. + // We're not actually in a for loop yet, so 'break' and 'continue' aren't + // permitted here. assert(FRI && "should not parse a for range declaration here"); SourceLocation DeclStart = Tok.getLocation(), DeclEnd; DeclGroupPtrTy DG = ParseSimpleDeclaration(DeclaratorContext::ForInit, @@ -2069,6 +2041,9 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, break; } + // If this is a for loop, we're entering its condition. + ForConditionScope.enter(/*IsConditionVariable=*/true); + // type-specifier-seq DeclSpec DS(AttrFactory); DS.takeAttributesFrom(attrs); @@ -2608,10 +2583,10 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, } case tok::code_completion: { + // Don't try to parse any further. + cutOffParsing(); // Code completion for the operator name. Actions.CodeCompleteOperatorName(getCurScope()); - cutOffParsing(); - // Don't try to parse any further. return true; } diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 50e1f1eaba4d..9d9c03d28a97 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -160,9 +160,6 @@ static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, /// \p CodeCompleteCB is called with Designation parsed so far. ExprResult Parser::ParseInitializerWithPotentialDesignator( DesignatorCompletionInfo DesignatorCompletion) { - if (!getPreprocessor().isCodeCompletionEnabled()) - DesignatorCompletion.PreferredBaseType = QualType(); // skip field lookup - // If this is the old-style GNU extension: // designation ::= identifier ':' // Handle it as a field designator. Otherwise, this must be the start of a @@ -203,9 +200,9 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator( SourceLocation DotLoc = ConsumeToken(); if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteDesignator(DesignatorCompletion.PreferredBaseType, DesignatorCompletion.InitExprs, Desig); - cutOffParsing(); return ExprError(); } if (Tok.isNot(tok::identifier)) { diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 223b36d7a0e6..9e145f57d61f 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -50,8 +50,8 @@ Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) { SourceLocation AtLoc = ConsumeToken(); // the "@" if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCAtDirective(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCAtDirective(getCurScope()); return nullptr; } @@ -219,8 +219,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, // Code completion after '@interface'. if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCInterfaceDecl(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCInterfaceDecl(getCurScope()); return nullptr; } @@ -253,8 +253,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, SourceLocation categoryLoc; IdentifierInfo *categoryId = nullptr; if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc); cutOffParsing(); + Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc); return nullptr; } @@ -308,8 +308,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, // Code completion of superclass names. if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc); cutOffParsing(); + Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc); return nullptr; } @@ -472,8 +472,8 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( if (Tok.is(tok::code_completion)) { // FIXME: If these aren't protocol references, we'll need different // completions. - Actions.CodeCompleteObjCProtocolReferences(protocolIdents); cutOffParsing(); + Actions.CodeCompleteObjCProtocolReferences(protocolIdents); // FIXME: Better recovery here?. return nullptr; @@ -635,10 +635,11 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, // Code completion within an Objective-C interface. if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteOrdinaryName(getCurScope(), CurParsedObjCImpl? Sema::PCC_ObjCImplementation : Sema::PCC_ObjCInterface); - return cutOffParsing(); + return; } // If we don't have an @ directive, parse it as a function definition. @@ -668,8 +669,9 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, // Otherwise, we have an @ directive, eat the @. SourceLocation AtLoc = ConsumeToken(); // the "@" if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCAtDirective(getCurScope()); - return cutOffParsing(); + return; } tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID(); @@ -778,8 +780,9 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, // We break out of the big loop in two cases: when we see @end or when we see // EOF. In the former case, eat the @end. In the later case, emit an error. if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCAtDirective(getCurScope()); - return cutOffParsing(); + return; } else if (Tok.isObjCAtKeyword(tok::objc_end)) { ConsumeToken(); // the "end" identifier } else { @@ -847,8 +850,9 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { while (1) { if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS); - return cutOffParsing(); + return; } const IdentifierInfo *II = Tok.getIdentifierInfo(); @@ -893,11 +897,12 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { } if (Tok.is(tok::code_completion)) { + cutOffParsing(); if (IsSetter) Actions.CodeCompleteObjCPropertySetter(getCurScope()); else Actions.CodeCompleteObjCPropertyGetter(getCurScope()); - return cutOffParsing(); + return; } SourceLocation SelLoc; @@ -1146,9 +1151,10 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, while (1) { if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCPassingType( getCurScope(), DS, Context == DeclaratorContext::ObjCParameter); - return cutOffParsing(); + return; } if (Tok.isNot(tok::identifier)) @@ -1335,9 +1341,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, /*ReturnType=*/nullptr); - cutOffParsing(); return nullptr; } @@ -1354,9 +1360,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, methodAttrs); if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, ReturnType); - cutOffParsing(); return nullptr; } @@ -1416,12 +1422,12 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, // Code completion for the next piece of the selector. if (Tok.is(tok::code_completion)) { + cutOffParsing(); KeyIdents.push_back(SelIdent); Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), mType == tok::minus, /*AtParameterName=*/true, ReturnType, KeyIdents); - cutOffParsing(); return nullptr; } @@ -1441,11 +1447,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, // Code completion for the next piece of the selector. if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), mType == tok::minus, /*AtParameterName=*/false, ReturnType, KeyIdents); - cutOffParsing(); return nullptr; } @@ -1527,8 +1533,8 @@ ParseObjCProtocolReferences(SmallVectorImpl &Protocols, while (1) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents); cutOffParsing(); + Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents); return true; } @@ -1626,12 +1632,12 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers( } QualType BaseT = Actions.GetTypeFromParser(baseType); + cutOffParsing(); if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) { Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); } else { Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs); } - cutOffParsing(); return; } @@ -1920,8 +1926,9 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, // Set the default visibility to private. if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteObjCAtVisibility(getCurScope()); - return cutOffParsing(); + return; } switch (Tok.getObjCKeywordID()) { @@ -1950,9 +1957,10 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, } if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_ObjCInstanceVariableList); - return cutOffParsing(); + return; } // This needs to duplicate a small amount of code from @@ -2017,8 +2025,8 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, ConsumeToken(); // the "protocol" identifier if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCProtocolDecl(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCProtocolDecl(getCurScope()); return nullptr; } @@ -2101,8 +2109,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc, // Code completion after '@implementation'. if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCImplementationDecl(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCImplementationDecl(getCurScope()); return nullptr; } @@ -2139,8 +2147,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc, IdentifierInfo *categoryId = nullptr; if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc); cutOffParsing(); + Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc); return nullptr; } @@ -2309,8 +2317,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { while (true) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); return nullptr; } @@ -2327,8 +2335,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { if (TryConsumeToken(tok::equal)) { // property '=' ivar-name if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId); cutOffParsing(); + Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId); return nullptr; } @@ -2387,8 +2395,8 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { while (true) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); return nullptr; } @@ -2724,8 +2732,8 @@ Decl *Parser::ParseObjCMethodDefinition() { StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc, ParsedStmtContext StmtCtx) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCAtStatement(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCAtStatement(getCurScope()); return StmtError(); } @@ -2765,8 +2773,8 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc, ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { switch (Tok.getKind()) { case tok::code_completion: - Actions.CodeCompleteObjCAtExpression(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCAtExpression(getCurScope()); return ExprError(); case tok::minus: @@ -3012,8 +3020,8 @@ ExprResult Parser::ParseObjCMessageExpression() { SourceLocation LBracLoc = ConsumeBracket(); // consume '[' if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCMessageReceiver(getCurScope()); cutOffParsing(); + Actions.CodeCompleteObjCMessageReceiver(getCurScope()); return ExprError(); } @@ -3149,6 +3157,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, InMessageExpressionRAIIObject InMessage(*this, true); if (Tok.is(tok::code_completion)) { + cutOffParsing(); if (SuperLoc.isValid()) Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None, false); @@ -3158,7 +3167,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, else Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, None, false); - cutOffParsing(); return ExprError(); } @@ -3187,6 +3195,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, /// Parse the expression after ':' if (Tok.is(tok::code_completion)) { + cutOffParsing(); if (SuperLoc.isValid()) Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, KeyIdents, @@ -3200,7 +3209,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, KeyIdents, /*AtArgumentExpression=*/true); - cutOffParsing(); return ExprError(); } @@ -3225,6 +3233,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, // Code completion after each argument. if (Tok.is(tok::code_completion)) { + cutOffParsing(); if (SuperLoc.isValid()) Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, KeyIdents, @@ -3237,7 +3246,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, KeyIdents, /*AtArgumentExpression=*/false); - cutOffParsing(); return ExprError(); } @@ -3577,8 +3585,8 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { ConsumeParen(); if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); cutOffParsing(); + Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); return ExprError(); } @@ -3603,8 +3611,8 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { break; if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); cutOffParsing(); + Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); return ExprError(); } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 3de01be0db87..54e24e94e661 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -441,9 +441,9 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) { ConsumeToken(); if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm); Actions.FinalizeDeclaration(OmpPrivParm); - cutOffParsing(); return; } @@ -2115,9 +2115,18 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false); llvm::SmallVector Decls; - DKind = parseOpenMPDirectiveKind(*this); - while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) && - Tok.isNot(tok::r_brace)) { + while (Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) { + if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) { + TentativeParsingAction TPA(*this); + ConsumeAnnotationToken(); + DKind = parseOpenMPDirectiveKind(*this); + if (DKind != OMPD_end_declare_target) + TPA.Revert(); + else + TPA.Commit(); + } + if (DKind == OMPD_end_declare_target) + break; DeclGroupPtrTy Ptr; // Here we expect to see some function declaration. if (AS == AS_none) { @@ -2133,15 +2142,6 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( DeclGroupRef Ref = Ptr.get(); Decls.append(Ref.begin(), Ref.end()); } - if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) { - TentativeParsingAction TPA(*this); - ConsumeAnnotationToken(); - DKind = parseOpenMPDirectiveKind(*this); - if (DKind != OMPD_end_declare_target) - TPA.Revert(); - else - TPA.Commit(); - } } ParseOMPEndDeclareTargetDirective(DKind, DTLoc); @@ -2207,6 +2207,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_target_teams_distribute_parallel_for: case OMPD_target_teams_distribute_parallel_for_simd: case OMPD_target_teams_distribute_simd: + case OMPD_dispatch: Diag(Tok, diag::err_omp_unexpected_directive) << 1 << getOpenMPDirectiveName(DKind); break; @@ -2378,6 +2379,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { case OMPD_target_enter_data: case OMPD_target_exit_data: case OMPD_target_update: + case OMPD_interop: if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Tok, diag::err_omp_immediate_directive) @@ -2429,7 +2431,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { case OMPD_target_teams_distribute: case OMPD_target_teams_distribute_parallel_for: case OMPD_target_teams_distribute_parallel_for_simd: - case OMPD_target_teams_distribute_simd: { + case OMPD_target_teams_distribute_simd: + case OMPD_dispatch: { // Special processing for flush and depobj clauses. Token ImplicitTok; bool ImplicitClauseAllowed = false; @@ -2864,7 +2867,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: - case OMPC_destroy: // OpenMP [2.7.1, Restrictions, p. 9] // Only one ordered clause can appear on a loop directive. // OpenMP [2.7.1, Restrictions, C/C++, p. 4] @@ -2928,6 +2930,21 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_uses_allocators: Clause = ParseOpenMPUsesAllocatorClause(DKind); break; + case OMPC_destroy: + if (DKind != OMPD_interop) { + if (!FirstClause) { + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + ErrorFound = true; + } + Clause = ParseOpenMPClause(CKind, WrongDirective); + break; + } + LLVM_FALLTHROUGH; + case OMPC_init: + case OMPC_use: + Clause = ParseOpenMPInteropClause(CKind, WrongDirective); + break; case OMPC_device_type: case OMPC_unknown: skipUntilPragmaOpenMPEnd(DKind); @@ -3024,6 +3041,144 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc); } +/// Parsing of OpenMP clauses that use an interop-var. +/// +/// init-clause: +/// init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var) +/// +/// destroy-clause: +/// destroy(interop-var) +/// +/// use-clause: +/// use(interop-var) +/// +/// interop-modifier: +/// prefer_type(preference-list) +/// +/// preference-list: +/// foreign-runtime-id [, foreign-runtime-id]... +/// +/// foreign-runtime-id: +/// | +/// +/// interop-type: +/// target | targetsync +/// +OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind, + bool ParseOnly) { + SourceLocation Loc = ConsumeToken(); + // Parse '('. + BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); + if (T.expectAndConsume(diag::err_expected_lparen_after, + getOpenMPClauseName(Kind).data())) + return nullptr; + + bool IsTarget = false; + bool IsTargetSync = false; + SmallVector Prefs; + + if (Kind == OMPC_init) { + + // Parse optional interop-modifier. + if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "prefer_type") { + ConsumeToken(); + BalancedDelimiterTracker PT(*this, tok::l_paren, + tok::annot_pragma_openmp_end); + if (PT.expectAndConsume(diag::err_expected_lparen_after, "prefer_type")) + return nullptr; + + while (Tok.isNot(tok::r_paren)) { + SourceLocation Loc = Tok.getLocation(); + ExprResult LHS = ParseCastExpression(AnyCastExpr); + ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr( + ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc, + /*DiscardedValue=*/false); + if (PTExpr.isUsable()) + Prefs.push_back(PTExpr.get()); + else + SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); + + if (Tok.is(tok::comma)) + ConsumeToken(); + } + PT.consumeClose(); + } + + if (!Prefs.empty()) { + if (Tok.is(tok::comma)) + ConsumeToken(); + else + Diag(Tok, diag::err_omp_expected_punc_after_interop_mod); + } + + // Parse the interop-types. + bool HasError = false; + while (Tok.is(tok::identifier)) { + if (PP.getSpelling(Tok) == "target") { + // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] + // Each interop-type may be specified on an action-clause at most + // once. + if (IsTarget) + Diag(Tok, diag::warn_omp_more_one_interop_type) << "target"; + IsTarget = true; + } else if (PP.getSpelling(Tok) == "targetsync") { + if (IsTargetSync) + Diag(Tok, diag::warn_omp_more_one_interop_type) << "targetsync"; + IsTargetSync = true; + } else { + HasError = true; + Diag(Tok, diag::err_omp_expected_interop_type); + } + ConsumeToken(); + + if (!Tok.is(tok::comma)) + break; + ConsumeToken(); + } + if (!HasError && !IsTarget && !IsTargetSync) + Diag(Tok, diag::err_omp_expected_interop_type); + + if (Tok.is(tok::colon)) + ConsumeToken(); + else if (IsTarget || IsTargetSync) + Diag(Tok, diag::warn_pragma_expected_colon) << "interop types"; + } + + // Parse the variable. + SourceLocation VarLoc = Tok.getLocation(); + ExprResult InteropVarExpr = + Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + if (!InteropVarExpr.isUsable()) { + SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); + } + + // Parse ')'. + SourceLocation RLoc = Tok.getLocation(); + if (!T.consumeClose()) + RLoc = T.getCloseLocation(); + + if (ParseOnly || !InteropVarExpr.isUsable() || + (Kind == OMPC_init && !IsTarget && !IsTargetSync)) + return nullptr; + + if (Kind == OMPC_init) + return Actions.ActOnOpenMPInitClause(InteropVarExpr.get(), Prefs, IsTarget, + IsTargetSync, Loc, T.getOpenLocation(), + VarLoc, RLoc); + if (Kind == OMPC_use) + return Actions.ActOnOpenMPUseClause(InteropVarExpr.get(), Loc, + T.getOpenLocation(), VarLoc, RLoc); + + if (Kind == OMPC_destroy) + return Actions.ActOnOpenMPDestroyClause(InteropVarExpr.get(), Loc, + T.getOpenLocation(), VarLoc, RLoc); + + llvm_unreachable("Unexpected interop variable clause."); +} + /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. /// /// default-clause: diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 8f7b977e3cb1..4ce8e4c4bb9d 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -14,11 +14,13 @@ #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/Token.h" #include "clang/Parse/LoopHint.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/Scope.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; @@ -292,6 +294,10 @@ struct PragmaMaxTokensTotalHandler : public PragmaHandler { Token &FirstToken) override; }; +void markAsReinjectedForRelexing(llvm::MutableArrayRef Toks) { + for (auto &T : Toks) + T.setFlag(clang::Token::IsReinjected); +} } // end namespace void Parser::initializePragmaHandlers() { @@ -771,12 +777,10 @@ void Parser::HandlePragmaOpenCLExtension() { // overriding all previously issued extension directives, but only if the // behavior is set to disable." if (Name == "all") { - if (State == Disable) { + if (State == Disable) Opt.disableAll(); - Opt.enableSupportedCore(getLangOpts()); - } else { + else PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1; - } } else if (State == Begin) { if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) { Opt.support(Name); @@ -2621,6 +2625,7 @@ void PragmaMSPragma::HandlePragma(Preprocessor &PP, TokenVector.push_back(EoF); // We must allocate this array with new because EnterTokenStream is going to // delete it later. + markAsReinjectedForRelexing(TokenVector); auto TokenArray = std::make_unique(TokenVector.size()); std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get()); auto Value = new (PP.getPreprocessorAllocator()) @@ -3178,6 +3183,7 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, EOFTok.setLocation(Tok.getLocation()); ValueList.push_back(EOFTok); // Terminates expression for parsing. + markAsReinjectedForRelexing(ValueList); Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator()); Info.PragmaName = PragmaName; @@ -3634,6 +3640,7 @@ void PragmaAttributeHandler::HandlePragma(Preprocessor &PP, EOFTok.setLocation(EndLoc); AttributeTokens.push_back(EOFTok); + markAsReinjectedForRelexing(AttributeTokens); Info->Tokens = llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator()); } diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f59271c45848..bcda3560ce63 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -172,14 +172,13 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( switch (Kind) { case tok::at: // May be a @try or @throw statement { - ProhibitAttributes(Attrs); // TODO: is it correct? AtLoc = ConsumeToken(); // consume @ return ParseObjCAtStatement(AtLoc, StmtCtx); } case tok::code_completion: - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement); cutOffParsing(); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement); return StmtError(); case tok::identifier: { @@ -726,8 +725,8 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, ColonLoc = SourceLocation(); if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteCase(getCurScope()); cutOffParsing(); + Actions.CodeCompleteCase(getCurScope()); return StmtError(); } @@ -1472,8 +1471,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { // Pop the 'else' scope if needed. InnerScope.Exit(); } else if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen); cutOffParsing(); + Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen); return StmtError(); } else if (InnerStatementTrailingElseLoc.isValid()) { Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else); @@ -1827,10 +1826,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { FullExprArg ThirdPart(Actions); if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteOrdinaryName(getCurScope(), C99orCXXorObjC? Sema::PCC_ForInit : Sema::PCC_Expression); - cutOffParsing(); return StmtError(); } @@ -1898,8 +1897,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { ConsumeToken(); // consume 'in' if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCForCollection(getCurScope(), DG); cutOffParsing(); + Actions.CodeCompleteObjCForCollection(getCurScope(), DG); return StmtError(); } Collection = ParseExpression(); @@ -1934,8 +1933,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { ConsumeToken(); // consume 'in' if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCForCollection(getCurScope(), nullptr); cutOffParsing(); + Actions.CodeCompleteObjCForCollection(getCurScope(), nullptr); return StmtError(); } Collection = ParseExpression(); @@ -1959,7 +1958,6 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { } // Parse the second part of the for specifier. - getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope); if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() && !SecondPart.isInvalid()) { // Parse the second part of the for specifier. @@ -1975,7 +1973,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt); SecondPart = ParseCXXCondition(nullptr, ForLoc, Sema::ConditionKind::Boolean, - MightBeForRangeStmt ? &ForRangeInfo : nullptr); + MightBeForRangeStmt ? &ForRangeInfo : nullptr, + /*EnterForConditionScope*/ true); if (ForRangeInfo.ParsedForRangeDecl()) { Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc() @@ -1992,6 +1991,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { } } } else { + // We permit 'continue' and 'break' in the condition of a for loop. + getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope); + ExprResult SecondExpr = ParseExpression(); if (SecondExpr.isInvalid()) SecondPart = Sema::ConditionError(); @@ -2003,6 +2005,11 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { } } + // Enter a break / continue scope, if we didn't already enter one while + // parsing the second part. + if (!(getCurScope()->getFlags() & Scope::ContinueScope)) + getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope); + // Parse the third part of the for statement. if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) { if (Tok.isNot(tok::semi)) { @@ -2188,9 +2195,9 @@ StmtResult Parser::ParseReturnStatement() { PreferredType.enterReturn(Actions, Tok.getLocation()); // FIXME: Code completion for co_return. if (Tok.is(tok::code_completion) && !IsCoreturn) { + cutOffParsing(); Actions.CodeCompleteExpression(getCurScope(), PreferredType.get(Tok.getLocation())); - cutOffParsing(); return StmtError(); } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 9b0f921b4269..b178b56e967c 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -49,10 +49,10 @@ IdentifierInfo *Parser::getSEHExceptKeyword() { } Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) - : PP(pp), Actions(actions), Diags(PP.getDiagnostics()), - GreaterThanIsOperator(true), ColonIsSacred(false), - InMessageExpression(false), TemplateParameterDepth(0), - ParsingInObjCContainer(false) { + : PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions), + Diags(PP.getDiagnostics()), GreaterThanIsOperator(true), + ColonIsSacred(false), InMessageExpression(false), + TemplateParameterDepth(0), ParsingInObjCContainer(false) { SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies; Tok.startToken(); Tok.setKind(tok::eof); @@ -870,6 +870,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, SingleDecl = ParseObjCMethodDefinition(); break; case tok::code_completion: + cutOffParsing(); if (CurParsedObjCImpl) { // Code-complete Objective-C methods even without leading '-'/'+' prefix. Actions.CodeCompleteObjCMethodDecl(getCurScope(), @@ -879,7 +880,6 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, Actions.CodeCompleteOrdinaryName( getCurScope(), CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace); - cutOffParsing(); return nullptr; case tok::kw_import: SingleDecl = ParseModuleImport(SourceLocation()); @@ -2114,21 +2114,21 @@ SourceLocation Parser::handleUnexpectedCodeCompletionToken() { for (Scope *S = getCurScope(); S; S = S->getParent()) { if (S->getFlags() & Scope::FnScope) { + cutOffParsing(); Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_RecoveryInFunction); - cutOffParsing(); return PrevTokLocation; } if (S->getFlags() & Scope::ClassScope) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class); cutOffParsing(); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class); return PrevTokLocation; } } - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace); cutOffParsing(); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace); return PrevTokLocation; } @@ -2452,8 +2452,8 @@ bool Parser::ParseModuleName( while (true) { if (!Tok.is(tok::identifier)) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteModuleImport(UseLoc, Path); cutOffParsing(); + Actions.CodeCompleteModuleImport(UseLoc, Path); return true; } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index edd9742ed207..bcd6a00d7ba5 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1506,6 +1506,25 @@ static void diagnoseRepeatedUseOfWeak(Sema &S, } } +namespace clang { +namespace { +typedef SmallVector OptionalNotes; +typedef std::pair DelayedDiag; +typedef std::list DiagList; + +struct SortDiagBySourceLocation { + SourceManager &SM; + SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {} + + bool operator()(const DelayedDiag &left, const DelayedDiag &right) { + // Although this call will be slow, this is only called when outputting + // multiple warnings. + return SM.isBeforeInTranslationUnit(left.first.first, right.first.first); + } +}; +} // anonymous namespace +} // namespace clang + namespace { class UninitValsDiagReporter : public UninitVariablesHandler { Sema &S; @@ -1626,9 +1645,35 @@ class UninitValsDiagReporter : public UninitVariablesHandler { } }; +/// Inter-procedural data for the called-once checker. +class CalledOnceInterProceduralData { +public: + // Add the delayed warning for the given block. + void addDelayedWarning(const BlockDecl *Block, + PartialDiagnosticAt &&Warning) { + DelayedBlockWarnings[Block].emplace_back(std::move(Warning)); + } + // Report all of the warnings we've gathered for the given block. + void flushWarnings(const BlockDecl *Block, Sema &S) { + for (const PartialDiagnosticAt &Delayed : DelayedBlockWarnings[Block]) + S.Diag(Delayed.first, Delayed.second); + + discardWarnings(Block); + } + // Discard all of the warnings we've gathered for the given block. + void discardWarnings(const BlockDecl *Block) { + DelayedBlockWarnings.erase(Block); + } + +private: + using DelayedDiagnostics = SmallVector; + llvm::DenseMap DelayedBlockWarnings; +}; + class CalledOnceCheckReporter : public CalledOnceCheckHandler { public: - CalledOnceCheckReporter(Sema &S) : S(S) {} + CalledOnceCheckReporter(Sema &S, CalledOnceInterProceduralData &Data) + : S(S), Data(Data) {} void handleDoubleCall(const ParmVarDecl *Parameter, const Expr *Call, const Expr *PrevCall, bool IsCompletionHandler, bool Poised) override { @@ -1649,14 +1694,24 @@ class CalledOnceCheckReporter : public CalledOnceCheckHandler { << Parameter << /* Captured */ false; } - void handleNeverCalled(const ParmVarDecl *Parameter, const Stmt *Where, - NeverCalledReason Reason, bool IsCalledDirectly, + void handleNeverCalled(const ParmVarDecl *Parameter, const Decl *Function, + const Stmt *Where, NeverCalledReason Reason, + bool IsCalledDirectly, bool IsCompletionHandler) override { auto DiagToReport = IsCompletionHandler ? diag::warn_completion_handler_never_called_when : diag::warn_called_once_never_called_when; - S.Diag(Where->getBeginLoc(), DiagToReport) - << Parameter << IsCalledDirectly << (unsigned)Reason; + PartialDiagnosticAt Warning(Where->getBeginLoc(), S.PDiag(DiagToReport) + << Parameter + << IsCalledDirectly + << (unsigned)Reason); + + if (const auto *Block = dyn_cast(Function)) { + // We shouldn't report these warnings on blocks immediately + Data.addDelayedWarning(Block, std::move(Warning)); + } else { + S.Diag(Warning.first, Warning.second); + } } void handleCapturedNeverCalled(const ParmVarDecl *Parameter, @@ -1669,8 +1724,18 @@ class CalledOnceCheckReporter : public CalledOnceCheckHandler { << Parameter << /* Captured */ true; } + void + handleBlockThatIsGuaranteedToBeCalledOnce(const BlockDecl *Block) override { + Data.flushWarnings(Block, S); + } + + void handleBlockWithNoGuarantees(const BlockDecl *Block) override { + Data.discardWarnings(Block); + } + private: Sema &S; + CalledOnceInterProceduralData &Data; }; constexpr unsigned CalledOnceWarnings[] = { @@ -1703,25 +1768,6 @@ bool shouldAnalyzeCalledOnceParameters(const DiagnosticsEngine &Diags, } } // anonymous namespace -namespace clang { -namespace { -typedef SmallVector OptionalNotes; -typedef std::pair DelayedDiag; -typedef std::list DiagList; - -struct SortDiagBySourceLocation { - SourceManager &SM; - SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {} - - bool operator()(const DelayedDiag &left, const DelayedDiag &right) { - // Although this call will be slow, this is only called when outputting - // multiple warnings. - return SM.isBeforeInTranslationUnit(left.first.first, right.first.first); - } -}; -} // anonymous namespace -} // namespace clang - //===----------------------------------------------------------------------===// // -Wthread-safety //===----------------------------------------------------------------------===// @@ -2107,54 +2153,68 @@ class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase { // warnings on a function, method, or block. //===----------------------------------------------------------------------===// -clang::sema::AnalysisBasedWarnings::Policy::Policy() { +sema::AnalysisBasedWarnings::Policy::Policy() { enableCheckFallThrough = 1; enableCheckUnreachable = 0; enableThreadSafetyAnalysis = 0; enableConsumedAnalysis = 0; } +/// InterProceduralData aims to be a storage of whatever data should be passed +/// between analyses of different functions. +/// +/// At the moment, its primary goal is to make the information gathered during +/// the analysis of the blocks available during the analysis of the enclosing +/// function. This is important due to the fact that blocks are analyzed before +/// the enclosed function is even parsed fully, so it is not viable to access +/// anything in the outer scope while analyzing the block. On the other hand, +/// re-building CFG for blocks and re-analyzing them when we do have all the +/// information (i.e. during the analysis of the enclosing function) seems to be +/// ill-designed. +class sema::AnalysisBasedWarnings::InterProceduralData { +public: + // It is important to analyze blocks within functions because it's a very + // common pattern to capture completion handler parameters by blocks. + CalledOnceInterProceduralData CalledOnceData; +}; + static unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) { return (unsigned)!D.isIgnored(diag, SourceLocation()); } -clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) - : S(s), - NumFunctionsAnalyzed(0), - NumFunctionsWithBadCFGs(0), - NumCFGBlocks(0), - MaxCFGBlocksPerFunction(0), - NumUninitAnalysisFunctions(0), - NumUninitAnalysisVariables(0), - MaxUninitAnalysisVariablesPerFunction(0), - NumUninitAnalysisBlockVisits(0), - MaxUninitAnalysisBlockVisitsPerFunction(0) { +sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) + : S(s), IPData(std::make_unique()), + NumFunctionsAnalyzed(0), NumFunctionsWithBadCFGs(0), NumCFGBlocks(0), + MaxCFGBlocksPerFunction(0), NumUninitAnalysisFunctions(0), + NumUninitAnalysisVariables(0), MaxUninitAnalysisVariablesPerFunction(0), + NumUninitAnalysisBlockVisits(0), + MaxUninitAnalysisBlockVisitsPerFunction(0) { using namespace diag; DiagnosticsEngine &D = S.getDiagnostics(); DefaultPolicy.enableCheckUnreachable = - isEnabled(D, warn_unreachable) || - isEnabled(D, warn_unreachable_break) || - isEnabled(D, warn_unreachable_return) || - isEnabled(D, warn_unreachable_loop_increment); + isEnabled(D, warn_unreachable) || isEnabled(D, warn_unreachable_break) || + isEnabled(D, warn_unreachable_return) || + isEnabled(D, warn_unreachable_loop_increment); - DefaultPolicy.enableThreadSafetyAnalysis = - isEnabled(D, warn_double_lock); + DefaultPolicy.enableThreadSafetyAnalysis = isEnabled(D, warn_double_lock); DefaultPolicy.enableConsumedAnalysis = - isEnabled(D, warn_use_in_invalid_state); + isEnabled(D, warn_use_in_invalid_state); } +// We need this here for unique_ptr with forward declared class. +sema::AnalysisBasedWarnings::~AnalysisBasedWarnings() = default; + static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) { for (const auto &D : fscope->PossiblyUnreachableDiags) S.Diag(D.Loc, D.PD); } -void clang::sema:: -AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, - sema::FunctionScopeInfo *fscope, - const Decl *D, QualType BlockType) { +void clang::sema::AnalysisBasedWarnings::IssueWarnings( + sema::AnalysisBasedWarnings::Policy P, sema::FunctionScopeInfo *fscope, + const Decl *D, QualType BlockType) { // We avoid doing analysis-based warnings when there are errors for // two reasons: @@ -2346,7 +2406,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, if (S.getLangOpts().ObjC && shouldAnalyzeCalledOnceParameters(Diags, D->getBeginLoc())) { if (AC.getCFG()) { - CalledOnceCheckReporter Reporter(S); + CalledOnceCheckReporter Reporter(S, IPData->CalledOnceData); checkCalledOnceParameters( AC, Reporter, shouldAnalyzeCalledOnceConventions(Diags, D->getBeginLoc())); diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index da42db3e8f7b..a2b55c0fec29 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -625,7 +625,8 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class // specifiers are not supported." if (S.getLangOpts().OpenCL && - !S.getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers")) { + !S.getOpenCLOptions().isAvailableOption( + "cl_clang_storage_class_specifiers", S.getLangOpts())) { switch (SC) { case SCS_extern: case SCS_private_extern: diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 252008cda15d..3a993e24b134 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// #include "clang/Sema/MultiplexExternalSemaSource.h" -#include "clang/AST/DeclContextInternals.h" #include "clang/Sema/Lookup.h" using namespace clang; diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td index 05dd6a1bd8f8..2ea70ae3234d 100644 --- a/clang/lib/Sema/OpenCLBuiltins.td +++ b/clang/lib/Sema/OpenCLBuiltins.td @@ -579,8 +579,9 @@ foreach name = ["half_divide", "half_powr", foreach name = ["abs"] in { def : Builtin; } -foreach name = ["clz", "popcount"] in { - def : Builtin; +def : Builtin<"clz", [AIGenTypeN, AIGenTypeN], Attr.Const>; +let MinVersion = CL12 in { + def : Builtin<"popcount", [AIGenTypeN, AIGenTypeN], Attr.Const>; } let MinVersion = CL20 in { foreach name = ["ctz"] in { @@ -1043,6 +1044,7 @@ let Extension = FuncExtKhrInt64ExtendedAtomics in { } // OpenCL v1.1 s6.11.1, v1.2 s6.12.11 - Atomic Functions foreach AS = [GlobalAS, LocalAS] in { + def : Builtin<"atomic_xchg", [Float, PointerType, AS>, Float]>; foreach Type = [Int, UInt] in { foreach name = ["atomic_add", "atomic_sub", "atomic_xchg", "atomic_min", "atomic_max", "atomic_and", @@ -1099,7 +1101,6 @@ let MinVersion = CL20 in { foreach TypePair = [[AtomicInt, Int, Int], [AtomicUInt, UInt, UInt], [AtomicLong, Long, Long], [AtomicULong, ULong, ULong], - [AtomicIntPtr, IntPtr, PtrDiff], [AtomicUIntPtr, UIntPtr, PtrDiff]] in { foreach ModOp = ["add", "sub"] in { def : Builtin<"atomic_fetch_" # ModOp, @@ -1111,9 +1112,7 @@ let MinVersion = CL20 in { } } foreach TypePair = [[AtomicInt, Int, Int], [AtomicUInt, UInt, UInt], - [AtomicLong, Long, Long], [AtomicULong, ULong, ULong], - [AtomicIntPtr, IntPtr, IntPtr], - [AtomicUIntPtr, UIntPtr, UIntPtr]] in { + [AtomicLong, Long, Long], [AtomicULong, ULong, ULong]] in { foreach ModOp = ["or", "xor", "and", "min", "max"] in { def : Builtin<"atomic_fetch_" # ModOp, [TypePair[1], PointerType, GenericAS>, TypePair[2]]>; diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp index 3ef8498baffd..1ac7ed1afc4e 100644 --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -159,6 +159,10 @@ bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const { return getInfo().diagAppertainsToDecl(S, *this, D); } +bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Stmt *St) const { + return getInfo().diagAppertainsToStmt(S, *this, St); +} + bool ParsedAttr::appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const { return checkAttributeMatchRuleAppliesTo(D, MatchRule); @@ -204,3 +208,35 @@ bool ParsedAttr::hasVariadicArg() const { // whether it's truly variadic or not. return getInfo().OptArgs == 15; } + +static unsigned getNumAttributeArgs(const ParsedAttr &AL) { + // FIXME: Include the type in the argument list. + return AL.getNumArgs() + AL.hasParsedType(); +} + +template +static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL, + unsigned Num, unsigned Diag, + Compare Comp) { + if (Comp(getNumAttributeArgs(AL), Num)) { + S.Diag(AL.getLoc(), Diag) << AL << Num; + return false; + } + return true; +} + +bool ParsedAttr::checkExactlyNumArgs(Sema &S, unsigned Num) const { + return checkAttributeNumArgsImpl(S, *this, Num, + diag::err_attribute_wrong_number_arguments, + std::not_equal_to()); +} +bool ParsedAttr::checkAtLeastNumArgs(Sema &S, unsigned Num) const { + return checkAttributeNumArgsImpl(S, *this, Num, + diag::err_attribute_too_few_arguments, + std::less()); +} +bool ParsedAttr::checkAtMostNumArgs(Sema &S, unsigned Num) const { + return checkAttributeNumArgsImpl(S, *this, Num, + diag::err_attribute_too_many_arguments, + std::greater()); +} diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 181a56fb0851..2c99a35e700b 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -299,7 +299,6 @@ void Sema::Initialize() { if (getLangOpts().OpenCL) { getOpenCLOptions().addSupport( Context.getTargetInfo().getSupportedOpenCLOpts(), getLangOpts()); - getOpenCLOptions().enableSupportedCore(getLangOpts()); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) { @@ -309,25 +308,13 @@ void Sema::Initialize() { addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); addImplicitTypedef("atomic_uint", Context.getAtomicType(Context.UnsignedIntTy)); - auto AtomicLongT = Context.getAtomicType(Context.LongTy); - addImplicitTypedef("atomic_long", AtomicLongT); - auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); - addImplicitTypedef("atomic_ulong", AtomicULongT); addImplicitTypedef("atomic_float", Context.getAtomicType(Context.FloatTy)); - auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); - addImplicitTypedef("atomic_double", AtomicDoubleT); // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide. addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy)); - auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); - addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); - auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); - addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); auto AtomicSizeT = Context.getAtomicType(Context.getSizeType()); addImplicitTypedef("atomic_size_t", AtomicSizeT); - auto AtomicPtrDiffT = Context.getAtomicType(Context.getPointerDiffType()); - addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); // OpenCL v2.0 s6.13.11.6: // - The atomic_long and atomic_ulong types are supported if the @@ -341,20 +328,42 @@ void Sema::Initialize() { // atomic_ptrdiff_t are supported if the cl_khr_int64_base_atomics and // cl_khr_int64_extended_atomics extensions are supported. std::vector Atomic64BitTypes; - Atomic64BitTypes.push_back(AtomicLongT); - Atomic64BitTypes.push_back(AtomicULongT); - Atomic64BitTypes.push_back(AtomicDoubleT); - if (Context.getTypeSize(AtomicSizeT) == 64) { - Atomic64BitTypes.push_back(AtomicSizeT); - Atomic64BitTypes.push_back(AtomicIntPtrT); - Atomic64BitTypes.push_back(AtomicUIntPtrT); - Atomic64BitTypes.push_back(AtomicPtrDiffT); + if (getOpenCLOptions().isSupported("cl_khr_int64_base_atomics", + getLangOpts()) && + getOpenCLOptions().isSupported("cl_khr_int64_extended_atomics", + getLangOpts())) { + if (getOpenCLOptions().isSupported("cl_khr_fp64", getLangOpts())) { + auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); + addImplicitTypedef("atomic_double", AtomicDoubleT); + setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64"); + Atomic64BitTypes.push_back(AtomicDoubleT); + } + auto AtomicLongT = Context.getAtomicType(Context.LongTy); + auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); + auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); + auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); + auto AtomicPtrDiffT = + Context.getAtomicType(Context.getPointerDiffType()); + + addImplicitTypedef("atomic_long", AtomicLongT); + addImplicitTypedef("atomic_ulong", AtomicULongT); + addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); + addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); + addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); + + Atomic64BitTypes.push_back(AtomicLongT); + Atomic64BitTypes.push_back(AtomicULongT); + if (Context.getTypeSize(AtomicSizeT) == 64) { + Atomic64BitTypes.push_back(AtomicSizeT); + Atomic64BitTypes.push_back(AtomicIntPtrT); + Atomic64BitTypes.push_back(AtomicUIntPtrT); + Atomic64BitTypes.push_back(AtomicPtrDiffT); + } } + for (auto &I : Atomic64BitTypes) setOpenCLExtensionForType(I, "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"); - - setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64"); } setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64"); @@ -362,9 +371,11 @@ void Sema::Initialize() { #define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \ setOpenCLExtensionForType(Context.Id, Ext); #include "clang/Basic/OpenCLImageTypes.def" -#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ - addImplicitTypedef(#ExtType, Context.Id##Ty); \ - setOpenCLExtensionForType(Context.Id##Ty, #Ext); +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + if (getOpenCLOptions().isSupported(#Ext, getLangOpts())) { \ + addImplicitTypedef(#ExtType, Context.Id##Ty); \ + setOpenCLExtensionForType(Context.Id##Ty, #Ext); \ + } #include "clang/Basic/OpenCLExtensionTypes.def" } @@ -2511,7 +2522,7 @@ bool Sema::isOpenCLDisabledDecl(Decl *FD) { if (Loc == OpenCLDeclExtMap.end()) return false; for (auto &I : Loc->second) { - if (!getOpenCLOptions().isEnabled(I)) + if (!getOpenCLOptions().isAvailableOption(I, getLangOpts())) return true; } return false; @@ -2527,7 +2538,8 @@ bool Sema::checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, return false; bool Disabled = false; for (auto &I : Loc->second) { - if (I != CurrOpenCLExtension && !getOpenCLOptions().isEnabled(I)) { + if (I != CurrOpenCLExtension && + !getOpenCLOptions().isAvailableOption(I, getLangOpts())) { Diag(DiagLoc, diag::err_opencl_requires_extension) << Selector << DiagInfo << I << SrcRange; Disabled = true; diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 9df2b7f84b57..2c37ccee1616 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -1188,3 +1188,51 @@ void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) { if (Stack->empty()) FreeVisContext(); } + +template +static bool checkCommonAttributeFeatures(Sema& S, const Ty *Node, + const ParsedAttr& A) { + // Several attributes carry different semantics than the parsing requires, so + // those are opted out of the common argument checks. + // + // We also bail on unknown and ignored attributes because those are handled + // as part of the target-specific handling logic. + if (A.getKind() == ParsedAttr::UnknownAttribute) + return false; + // Check whether the attribute requires specific language extensions to be + // enabled. + if (!A.diagnoseLangOpts(S)) + return true; + // Check whether the attribute appertains to the given subject. + if (!A.diagnoseAppertainsTo(S, Node)) + return true; + // Check whether the attribute exists in the target architecture. + if (S.CheckAttrTarget(A)) + return true; + + if (A.hasCustomParsing()) + return false; + + if (A.getMinArgs() == A.getMaxArgs()) { + // If there are no optional arguments, then checking for the argument count + // is trivial. + if (!A.checkExactlyNumArgs(S, A.getMinArgs())) + return true; + } else { + // There are optional arguments, so checking is slightly more involved. + if (A.getMinArgs() && !A.checkAtLeastNumArgs(S, A.getMinArgs())) + return true; + else if (!A.hasVariadicArg() && A.getMaxArgs() && + !A.checkAtMostNumArgs(S, A.getMaxArgs())) + return true; + } + + return false; +} + +bool Sema::checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A) { + return ::checkCommonAttributeFeatures(*this, D, A); +} +bool Sema::checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A) { + return ::checkCommonAttributeFeatures(*this, S, A); +} diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 671820afd485..719cbf46bd5c 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/SemaInternal.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTStructuralEquivalence.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" @@ -23,6 +23,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" +#include "clang/Sema/SemaInternal.h" #include "llvm/ADT/SmallVector.h" #include using namespace clang; @@ -1035,6 +1036,90 @@ static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, << FixItHint::CreateReplacement(BeginLoc, "static_cast"); } +static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType, + ASTContext &Context) { + if (SrcType->isPointerType() && DestType->isPointerType()) + return true; + + // Allow integral type mismatch if their size are equal. + if (SrcType->isIntegralType(Context) && DestType->isIntegralType(Context)) + if (Context.getTypeInfoInChars(SrcType).Width == + Context.getTypeInfoInChars(DestType).Width) + return true; + + return Context.hasSameUnqualifiedType(SrcType, DestType); +} + +static bool checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, + QualType DestType) { + if (Self.Diags.isIgnored(diag::warn_cast_function_type, + SrcExpr.get()->getExprLoc())) + return true; + + QualType SrcType = SrcExpr.get()->getType(); + const FunctionType *SrcFTy = nullptr; + const FunctionType *DstFTy = nullptr; + if (((SrcType->isBlockPointerType() || SrcType->isFunctionPointerType()) && + DestType->isFunctionPointerType()) || + (SrcType->isMemberFunctionPointerType() && + DestType->isMemberFunctionPointerType())) { + SrcFTy = SrcType->getPointeeType()->castAs(); + DstFTy = DestType->getPointeeType()->castAs(); + } else if (SrcType->isFunctionType() && DestType->isFunctionReferenceType()) { + SrcFTy = SrcType->castAs(); + DstFTy = DestType.getNonReferenceType()->castAs(); + } else { + return true; + } + assert(SrcFTy && DstFTy); + + auto IsVoidVoid = [](const FunctionType *T) { + if (!T->getReturnType()->isVoidType()) + return false; + if (const auto *PT = T->getAs()) + return !PT->isVariadic() && PT->getNumParams() == 0; + return false; + }; + + // Skip if either function type is void(*)(void) + if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy)) + return true; + + // Check return type. + if (!argTypeIsABIEquivalent(SrcFTy->getReturnType(), DstFTy->getReturnType(), + Self.Context)) + return false; + + // Check if either has unspecified number of parameters + if (SrcFTy->isFunctionNoProtoType() || DstFTy->isFunctionNoProtoType()) + return true; + + // Check parameter types. + + const auto *SrcFPTy = cast(SrcFTy); + const auto *DstFPTy = cast(DstFTy); + + // In a cast involving function types with a variable argument list only the + // types of initial arguments that are provided are considered. + unsigned NumParams = SrcFPTy->getNumParams(); + unsigned DstNumParams = DstFPTy->getNumParams(); + if (NumParams > DstNumParams) { + if (!DstFPTy->isVariadic()) + return false; + NumParams = DstNumParams; + } else if (NumParams < DstNumParams) { + if (!SrcFPTy->isVariadic()) + return false; + } + + for (unsigned i = 0; i < NumParams; ++i) + if (!argTypeIsABIEquivalent(SrcFPTy->getParamType(i), + DstFPTy->getParamType(i), Self.Context)) + return false; + + return true; +} + /// CheckReinterpretCast - Check that a reinterpret_cast\(SrcExpr) is /// valid. /// Refer to C++ 5.2.10 for details. reinterpret_cast is typically used in code @@ -1072,6 +1157,10 @@ void CastOperation::CheckReinterpretCast() { if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) checkObjCConversion(Sema::CCK_OtherCast); DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange); + + if (!checkCastFunctionType(Self, SrcExpr, DestType)) + Self.Diag(OpRange.getBegin(), diag::warn_cast_function_type) + << SrcExpr.get()->getType() << DestType << OpRange; } else { SrcExpr = ExprError(); } @@ -2645,6 +2734,11 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, if (isValidCast(tcr)) { if (Kind == CK_BitCast) checkCastAlign(); + + if (!checkCastFunctionType(Self, SrcExpr, DestType)) + Self.Diag(OpRange.getBegin(), diag::warn_cast_function_type) + << SrcExpr.get()->getType() << DestType << OpRange; + } else { SrcExpr = ExprError(); } @@ -2916,8 +3010,8 @@ void CastOperation::CheckCStyleCast() { } } - if (Self.getLangOpts().OpenCL && - !Self.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().isAvailableOption( + "cl_khr_fp16", Self.getLangOpts())) { if (DestType->isHalfType()) { Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half) << DestType << SrcExpr.get()->getSourceRange(); @@ -2957,6 +3051,10 @@ void CastOperation::CheckCStyleCast() { } } + if (!checkCastFunctionType(Self, SrcExpr, DestType)) + Self.Diag(OpRange.getBegin(), diag::warn_cast_function_type) + << SrcType << DestType << OpRange; + DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType); DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange); DiagnoseBadFunctionCast(Self, SrcExpr, DestType); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 92f8d11d54fe..305fcd574a37 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -837,7 +837,8 @@ static bool checkOpenCLBlockArgs(Sema &S, Expr *BlockArg) { } static bool checkOpenCLSubgroupExt(Sema &S, CallExpr *Call) { - if (!S.getOpenCLOptions().isEnabled("cl_khr_subgroups")) { + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_subgroups", + S.getLangOpts())) { S.Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension) << 1 << Call->getDirectCallee() << "cl_khr_subgroups"; return true; @@ -1965,6 +1966,26 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_matrix_column_major_store: return SemaBuiltinMatrixColumnMajorStore(TheCall, TheCallResult); + + case Builtin::BI__builtin_get_device_side_mangled_name: { + auto Check = [](CallExpr *TheCall) { + if (TheCall->getNumArgs() != 1) + return false; + auto *DRE = dyn_cast(TheCall->getArg(0)->IgnoreImpCasts()); + if (!DRE) + return false; + auto *D = DRE->getDecl(); + if (!isa(D) && !isa(D)) + return false; + return D->hasAttr() || D->hasAttr() || + D->hasAttr() || D->hasAttr(); + }; + if (!Check(TheCall)) { + Diag(TheCall->getBeginLoc(), + diag::err_hip_invalid_args_builtin_mangled_name); + return ExprError(); + } + } } // Since the target specific builtins for each arch overlap, only check those @@ -4491,7 +4512,8 @@ void Sema::CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl, // Find expected alignment, and the actual alignment of the passed object. // getTypeAlignInChars requires complete types - if (ParamTy->isIncompleteType() || ArgTy->isIncompleteType()) + if (ParamTy->isIncompleteType() || ArgTy->isIncompleteType() || + ParamTy->isUndeducedType() || ArgTy->isUndeducedType()) return; CharUnits ParamAlign = Context.getTypeAlignInChars(ParamTy); @@ -4503,7 +4525,7 @@ void Sema::CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl, Diag(Loc, diag::warn_param_mismatched_alignment) << (int)ArgAlign.getQuantity() << (int)ParamAlign.getQuantity() << ParamName << FDecl; -}; +} /// Handles the checks for format strings, non-POD arguments to vararg /// functions, NULL arguments passed to non-NULL parameters, and diagnose_if @@ -8730,8 +8752,11 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, } else if (const CharacterLiteral *CL = dyn_cast(E)) { // Special case for 'a', which has type 'int' in C. // Note, however, that we do /not/ want to treat multibyte constants like - // 'MooV' as characters! This form is deprecated but still exists. - if (ExprTy == S.Context.IntTy) + // 'MooV' as characters! This form is deprecated but still exists. In + // addition, don't treat expressions as of type 'char' if one byte length + // modifier is provided. + if (ExprTy == S.Context.IntTy && + FS.getLengthModifier().getKind() != LengthModifier::AsChar) if (llvm::isUIntN(S.Context.getCharWidth(), CL->getValue())) ExprTy = S.Context.CharTy; } diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 2feb02bbe4ed..dc7a67e92827 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -381,6 +381,8 @@ class ResultBuilder { } // namespace void PreferredTypeBuilder::enterReturn(Sema &S, SourceLocation Tok) { + if (!Enabled) + return; if (isa(S.CurContext)) { if (sema::BlockScopeInfo *BSI = S.getCurBlock()) { ComputeType = nullptr; @@ -399,6 +401,8 @@ void PreferredTypeBuilder::enterReturn(Sema &S, SourceLocation Tok) { } void PreferredTypeBuilder::enterVariableInit(SourceLocation Tok, Decl *D) { + if (!Enabled) + return; auto *VD = llvm::dyn_cast_or_null(D); ComputeType = nullptr; Type = VD ? VD->getType() : QualType(); @@ -410,6 +414,8 @@ static QualType getDesignatedType(QualType BaseType, const Designation &Desig); void PreferredTypeBuilder::enterDesignatedInitializer(SourceLocation Tok, QualType BaseType, const Designation &D) { + if (!Enabled) + return; ComputeType = nullptr; Type = getDesignatedType(BaseType, D); ExpectedLoc = Tok; @@ -417,6 +423,8 @@ void PreferredTypeBuilder::enterDesignatedInitializer(SourceLocation Tok, void PreferredTypeBuilder::enterFunctionArgument( SourceLocation Tok, llvm::function_ref ComputeType) { + if (!Enabled) + return; this->ComputeType = ComputeType; Type = QualType(); ExpectedLoc = Tok; @@ -424,6 +432,8 @@ void PreferredTypeBuilder::enterFunctionArgument( void PreferredTypeBuilder::enterParenExpr(SourceLocation Tok, SourceLocation LParLoc) { + if (!Enabled) + return; // expected type for parenthesized expression does not change. if (ExpectedLoc == LParLoc) ExpectedLoc = Tok; @@ -541,6 +551,8 @@ static QualType getPreferredTypeOfUnaryArg(Sema &S, QualType ContextType, void PreferredTypeBuilder::enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, tok::TokenKind Op) { + if (!Enabled) + return; ComputeType = nullptr; Type = getPreferredTypeOfBinaryRHS(S, LHS, Op); ExpectedLoc = Tok; @@ -548,7 +560,7 @@ void PreferredTypeBuilder::enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, void PreferredTypeBuilder::enterMemAccess(Sema &S, SourceLocation Tok, Expr *Base) { - if (!Base) + if (!Enabled || !Base) return; // Do we have expected type for Base? if (ExpectedLoc != Base->getBeginLoc()) @@ -561,6 +573,8 @@ void PreferredTypeBuilder::enterMemAccess(Sema &S, SourceLocation Tok, void PreferredTypeBuilder::enterUnary(Sema &S, SourceLocation Tok, tok::TokenKind OpKind, SourceLocation OpLoc) { + if (!Enabled) + return; ComputeType = nullptr; Type = getPreferredTypeOfUnaryArg(S, this->get(OpLoc), OpKind); ExpectedLoc = Tok; @@ -568,6 +582,8 @@ void PreferredTypeBuilder::enterUnary(Sema &S, SourceLocation Tok, void PreferredTypeBuilder::enterSubscript(Sema &S, SourceLocation Tok, Expr *LHS) { + if (!Enabled) + return; ComputeType = nullptr; Type = S.getASTContext().IntTy; ExpectedLoc = Tok; @@ -575,12 +591,16 @@ void PreferredTypeBuilder::enterSubscript(Sema &S, SourceLocation Tok, void PreferredTypeBuilder::enterTypeCast(SourceLocation Tok, QualType CastType) { + if (!Enabled) + return; ComputeType = nullptr; Type = !CastType.isNull() ? CastType.getCanonicalType() : QualType(); ExpectedLoc = Tok; } void PreferredTypeBuilder::enterCondition(Sema &S, SourceLocation Tok) { + if (!Enabled) + return; ComputeType = nullptr; Type = S.getASTContext().BoolTy; ExpectedLoc = Tok; @@ -5691,8 +5711,9 @@ ProduceSignatureHelp(Sema &SemaRef, Scope *S, unsigned CurrentArg, SourceLocation OpenParLoc) { if (Candidates.empty()) return QualType(); - SemaRef.CodeCompleter->ProcessOverloadCandidates( - SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc); + if (SemaRef.getPreprocessor().isCodeCompletionReached()) + SemaRef.CodeCompleter->ProcessOverloadCandidates( + SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc); return getParamType(SemaRef, Candidates, CurrentArg); } diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 1ff7b1cdd515..592bf5633ea5 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -439,18 +439,19 @@ static void diagnoseUnsatisfiedRequirement(Sema &S, case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: { ConceptSpecializationExpr *ConstraintExpr = Req->getReturnTypeRequirementSubstitutedConstraintExpr(); - if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) + if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) { // A simple case - expr type is the type being constrained and the concept // was not provided arguments. - S.Diag(ConstraintExpr->getBeginLoc(), + Expr *e = Req->getExpr(); + S.Diag(e->getBeginLoc(), diag::note_expr_requirement_constraints_not_satisfied_simple) - << (int)First << S.BuildDecltypeType(Req->getExpr(), - Req->getExpr()->getBeginLoc()) + << (int)First << S.getDecltypeForParenthesizedExpr(e) << ConstraintExpr->getNamedConcept(); - else + } else { S.Diag(ConstraintExpr->getBeginLoc(), diag::note_expr_requirement_constraints_not_satisfied) << (int)First << ConstraintExpr; + } S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction()); break; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c3502e0d295c..b117d73a9b60 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5211,7 +5211,8 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // trivial in almost all cases, except if a union member has an in-class // initializer: // union { int n = 0; }; - ActOnUninitializedDecl(Anon); + if (!Invalid) + ActOnUninitializedDecl(Anon); } Anon->setImplicit(); @@ -6750,7 +6751,8 @@ static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D, } // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. - if (!Se.getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + if (!Se.getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + Se.getLangOpts())) { QualType NR = R.getCanonicalType(); while (NR->isPointerType() || NR->isMemberFunctionPointerType() || NR->isReferenceType()) { @@ -6765,7 +6767,8 @@ static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D, } } - if (!Se.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (!Se.getOpenCLOptions().isAvailableOption("cl_khr_fp16", + Se.getLangOpts())) { // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and // half array type (unless the cl_khr_fp16 extension is enabled). if (Se.Context.getBaseElementType(R)->isHalfType()) { @@ -7888,7 +7891,8 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { // OpenCL v1.2 s6.8 - The static qualifier is valid only in program // scope. if (getLangOpts().OpenCLVersion == 120 && - !getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers") && + !getOpenCLOptions().isAvailableOption("cl_clang_storage_class_specifiers", + getLangOpts()) && NewVD->isStaticLocal()) { Diag(NewVD->getLocation(), diag::err_static_function_scope); NewVD->setInvalidDecl(); @@ -8660,7 +8664,8 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) { // OpenCL extension spec v1.2 s9.5: // This extension adds support for half scalar and vector types as built-in // types that can be used for arithmetic operations, conversions etc. - if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16") && PT->isHalfType()) + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", S.getLangOpts()) && + PT->isHalfType()) return InvalidKernelParam; if (PT->isRecordType()) @@ -11169,6 +11174,25 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { } } +static bool isDefaultStdCall(FunctionDecl *FD, Sema &S) { + + // Default calling convention for main and wmain is __cdecl + if (FD->getName() == "main" || FD->getName() == "wmain") + return false; + + // Default calling convention for MinGW is __cdecl + const llvm::Triple &T = S.Context.getTargetInfo().getTriple(); + if (T.isWindowsGNUEnvironment()) + return false; + + // Default calling convention for WinMain, wWinMain and DllMain + // is __stdcall on 32 bit Windows + if (T.isOSWindows() && T.getArch() == llvm::Triple::x86) + return true; + + return false; +} + void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) { QualType T = FD->getType(); assert(T->isFunctionType() && "function decl is not of function type"); @@ -11183,6 +11207,21 @@ void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) { if (FD->getName() != "DllMain") FD->setHasImplicitReturnZero(true); + // Explicity specified calling conventions are applied to MSVC entry points + if (!hasExplicitCallingConv(T)) { + if (isDefaultStdCall(FD, *this)) { + if (FT->getCallConv() != CC_X86StdCall) { + FT = Context.adjustFunctionType( + FT, FT->getExtInfo().withCallingConv(CC_X86StdCall)); + FD->setType(QualType(FT, 0)); + } + } else if (FT->getCallConv() != CC_C) { + FT = Context.adjustFunctionType(FT, + FT->getExtInfo().withCallingConv(CC_C)); + FD->setType(QualType(FT, 0)); + } + } + if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) { Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD; FD->setInvalidDecl(); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4376342185fb..b39460d33214 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -154,7 +154,8 @@ static bool isInstanceMethod(const Decl *D) { return false; } -static inline bool isNSStringType(QualType T, ASTContext &Ctx) { +static inline bool isNSStringType(QualType T, ASTContext &Ctx, + bool AllowNSAttributedString = false) { const auto *PT = T->getAs(); if (!PT) return false; @@ -165,6 +166,9 @@ static inline bool isNSStringType(QualType T, ASTContext &Ctx) { IdentifierInfo* ClsName = Cls->getIdentifier(); + if (AllowNSAttributedString && + ClsName == &Ctx.Idents.get("NSAttributedString")) + return true; // FIXME: Should we walk the chain of classes? return ClsName == &Ctx.Idents.get("NSString") || ClsName == &Ctx.Idents.get("NSMutableString"); @@ -191,44 +195,6 @@ static unsigned getNumAttributeArgs(const ParsedAttr &AL) { return AL.getNumArgs() + AL.hasParsedType(); } -template -static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL, - unsigned Num, unsigned Diag, - Compare Comp) { - if (Comp(getNumAttributeArgs(AL), Num)) { - S.Diag(AL.getLoc(), Diag) << AL << Num; - return false; - } - - return true; -} - -/// Check if the attribute has exactly as many args as Num. May -/// output an error. -static bool checkAttributeNumArgs(Sema &S, const ParsedAttr &AL, unsigned Num) { - return checkAttributeNumArgsImpl(S, AL, Num, - diag::err_attribute_wrong_number_arguments, - std::not_equal_to()); -} - -/// Check if the attribute has at least as many args as Num. May -/// output an error. -static bool checkAttributeAtLeastNumArgs(Sema &S, const ParsedAttr &AL, - unsigned Num) { - return checkAttributeNumArgsImpl(S, AL, Num, - diag::err_attribute_too_few_arguments, - std::less()); -} - -/// Check if the attribute has at most as many args as Num. May -/// output an error. -static bool checkAttributeAtMostNumArgs(Sema &S, const ParsedAttr &AL, - unsigned Num) { - return checkAttributeNumArgsImpl(S, AL, Num, - diag::err_attribute_too_many_arguments, - std::greater()); -} - /// A helper function to provide Attribute Location for the Attr types /// AND the ParsedAttr. template @@ -424,10 +390,10 @@ appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg, std::forward(ExtraArgs)...); } -/// Add an attribute {@code AttrType} to declaration {@code D}, provided that -/// {@code PassesCheck} is true. -/// Otherwise, emit diagnostic {@code DiagID}, passing in all parameters -/// specified in {@code ExtraArgs}. +/// Add an attribute @c AttrType to declaration @c D, provided that +/// @c PassesCheck is true. +/// Otherwise, emit diagnostic @c DiagID, passing in all parameters +/// specified in @c ExtraArgs. template static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D, const AttributeCommonInfo &CI, @@ -547,16 +513,9 @@ static bool checkRecordDeclForAttr(const RecordDecl *RD) { // Else check if any base classes have the attribute. if (const auto *CRD = dyn_cast(RD)) { - CXXBasePaths BPaths(false, false); - if (CRD->lookupInBases( - [](const CXXBaseSpecifier *BS, CXXBasePath &) { - const auto &Ty = *BS->getType(); - // If it's type-dependent, we assume it could have the attribute. - if (Ty.isDependentType()) - return true; - return Ty.castAs()->getDecl()->hasAttr(); - }, - BPaths, true)) + if (!CRD->forallBases([](const CXXRecordDecl *Base) { + return !Base->hasAttr(); + })) return true; } return false; @@ -771,7 +730,7 @@ static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl &Args) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return false; // Check that this attribute only applies to lockable types. @@ -867,8 +826,7 @@ static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD, } static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1) || - !checkAttributeAtMostNumArgs(S, AL, 2)) + if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2)) return; const auto *FD = cast(D); @@ -904,7 +862,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl &Args) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return false; if (!isIntOrBool(AL.getArgAsExpr(0))) { @@ -951,7 +909,7 @@ static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return; // check that all arguments are lockable objects @@ -1193,7 +1151,7 @@ static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, } static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return; if (!checkForConsumableClass(S, cast(D), AL)) @@ -2016,7 +1974,7 @@ static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } } - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return; SmallVector CPUs; @@ -2120,7 +2078,7 @@ static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) { } bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) { - if (!checkAttributeNumArgs(*this, Attrs, 0)) { + if (!Attrs.checkExactlyNumArgs(*this, 0)) { Attrs.setInvalid(); return true; } @@ -2492,7 +2450,7 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr( } static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeNumArgs(S, AL, 1)) + if (!AL.checkExactlyNumArgs(S, 1)) return; IdentifierLoc *Platform = AL.getArgAsIdent(0); @@ -2600,10 +2558,8 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleExternalSourceSymbolAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3)) return; - assert(checkAttributeAtMostNumArgs(S, AL, 3) && - "Invalid number of arguments in an external_source_symbol attribute"); StringRef Language; if (const auto *SE = dyn_cast_or_null(AL.getArgAsExpr(0))) @@ -2873,8 +2829,10 @@ static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { QualType Ty = V->getType(); if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { const FunctionType *FT = Ty->isFunctionPointerType() - ? D->getFunctionType() - : Ty->castAs()->getPointeeType()->getAs(); + ? D->getFunctionType() + : Ty->castAs() + ->getPointeeType() + ->castAs(); if (!cast(FT)->isVariadic()) { int m = Ty->isFunctionPointerType() ? 0 : 1; S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; @@ -3327,7 +3285,7 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } Ty = getFunctionOrMethodResultType(D); - if (!isNSStringType(Ty, S.Context) && + if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) && !isCFStringType(Ty, S.Context) && (!Ty->isPointerType() || !Ty->castAs()->getPointeeType()->isCharType())) { @@ -4690,7 +4648,7 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return; std::vector DiagnosticIdentifiers; @@ -4780,7 +4738,7 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC, } unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0; - if (!checkAttributeNumArgs(*this, Attrs, ReqArgs)) { + if (!Attrs.checkExactlyNumArgs(*this, ReqArgs)) { Attrs.setInvalid(); return true; } @@ -5008,7 +4966,7 @@ bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) { if (AL.isInvalid()) return true; - if (!checkAttributeNumArgs(*this, AL, 1)) { + if (!AL.checkExactlyNumArgs(*this, 1)) { AL.setInvalid(); return true; } @@ -5097,8 +5055,7 @@ void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI, } static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1) || - !checkAttributeAtMostNumArgs(S, AL, 2)) + if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2)) return; S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0), @@ -5145,7 +5102,7 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, return; } - if (!checkAttributeNumArgs(S, AL, 1)) + if (!AL.checkExactlyNumArgs(S, 1)) return; if (!isa(D)) { @@ -5874,7 +5831,7 @@ static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D, // handleSwiftAsyncAttr already verified the type is correct, so no need to // double-check it here. const auto *FuncTy = HandlerParam->getType() - ->getAs() + ->castAs() ->getPointeeType() ->getAs(); ArrayRef BlockParams; @@ -5952,7 +5909,7 @@ static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL) { switch (ConvKind) { case SwiftAsyncErrorAttr::ZeroArgument: case SwiftAsyncErrorAttr::NonZeroArgument: { - if (!checkAttributeNumArgs(S, AL, 2)) + if (!AL.checkExactlyNumArgs(S, 2)) return; Expr *IdxExpr = AL.getArgAsExpr(1); @@ -5962,7 +5919,7 @@ static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL) { } case SwiftAsyncErrorAttr::NonNullError: case SwiftAsyncErrorAttr::None: { - if (!checkAttributeNumArgs(S, AL, 1)) + if (!AL.checkExactlyNumArgs(S, 1)) return; break; } @@ -6288,7 +6245,7 @@ static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleSwiftNewType(Sema &S, Decl *D, const ParsedAttr &AL) { // Make sure that there is an identifier as the annotation's single argument. - if (!checkAttributeNumArgs(S, AL, 1)) + if (!AL.checkExactlyNumArgs(S, 1)) return; if (!AL.isArgIdent(0)) { @@ -6330,11 +6287,11 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) { ParamIdx Idx; if (Kind == SwiftAsyncAttr::None) { // If this is 'none', then there shouldn't be any additional arguments. - if (!checkAttributeNumArgs(S, AL, 1)) + if (!AL.checkExactlyNumArgs(S, 1)) return; } else { // Non-none swift_async requires a completion handler index argument. - if (!checkAttributeNumArgs(S, AL, 2)) + if (!AL.checkExactlyNumArgs(S, 2)) return; Expr *HandlerIdx = AL.getArgAsExpr(1); @@ -6351,8 +6308,8 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } QualType BlockTy = - CompletionBlockType->getAs()->getPointeeType(); - if (!BlockTy->getAs()->getReturnType()->isVoidType()) { + CompletionBlockType->castAs()->getPointeeType(); + if (!BlockTy->castAs()->getReturnType()->isVoidType()) { S.Diag(CompletionBlock->getLocation(), diag::err_swift_async_bad_block_type) << CompletionBlock->getType(); @@ -6498,7 +6455,7 @@ static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } if (AL.getNumArgs() == 0) Tags.push_back(NS->getName()); - } else if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + } else if (!AL.checkAtLeastNumArgs(S, 1)) return; // Store tags sorted and without duplicates. @@ -6556,7 +6513,7 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } // The attribute takes one integer argument. - if (!checkAttributeNumArgs(S, AL, 1)) + if (!AL.checkExactlyNumArgs(S, 1)) return; if (!AL.isArgExpr(0)) { @@ -6642,7 +6599,7 @@ static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleM68kInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeNumArgs(S, AL, 1)) + if (!AL.checkExactlyNumArgs(S, 1)) return; if (!AL.isArgExpr(0)) { @@ -6745,7 +6702,7 @@ static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - if (!checkAttributeNumArgs(S, AL, 0)) + if (!AL.checkExactlyNumArgs(S, 0)) return; handleSimpleAttribute(S, D, AL); @@ -6758,7 +6715,7 @@ static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - if (!checkAttributeNumArgs(S, AL, 0)) + if (!AL.checkExactlyNumArgs(S, 0)) return; handleSimpleAttribute(S, D, AL); @@ -6889,7 +6846,7 @@ static void handleRISCVInterruptAttr(Sema &S, Decl *D, } // Check the attribute argument. Argument is optional. - if (!checkAttributeAtMostNumArgs(S, AL, 1)) + if (!AL.checkAtMostNumArgs(S, 1)) return; StringRef Str; @@ -7062,8 +7019,7 @@ void Sema::addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, } static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1) || - !checkAttributeAtMostNumArgs(S, AL, 2)) + if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2)) return; Expr *MinExpr = AL.getArgAsExpr(0); @@ -7286,7 +7242,7 @@ static void handleReleaseCapabilityAttr(Sema &S, Decl *D, static void handleRequiresCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return; // check that all arguments are lockable objects @@ -7320,7 +7276,7 @@ static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // Only support a single optional message for Declspec and CXX11. if (AL.isDeclspecAttribute() || AL.isCXX11Attribute()) - checkAttributeAtMostNumArgs(S, AL, 1); + AL.checkAtMostNumArgs(S, 1); else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) && !S.checkStringLiteralArgumentAttr(AL, 1, Replacement)) return; @@ -7338,7 +7294,7 @@ static bool isGlobalVar(const Decl *D) { } static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!checkAttributeAtLeastNumArgs(S, AL, 1)) + if (!AL.checkAtLeastNumArgs(S, 1)) return; std::vector Sanitizers; @@ -7408,49 +7364,6 @@ static void handleOpenCLNoSVMAttr(Sema &S, Decl *D, const ParsedAttr &AL) { << "2.0"; } -/// Handles semantic checking for features that are common to all attributes, -/// such as checking whether a parameter was properly specified, or the correct -/// number of arguments were passed, etc. -static bool handleCommonAttributeFeatures(Sema &S, Decl *D, - const ParsedAttr &AL) { - // Several attributes carry different semantics than the parsing requires, so - // those are opted out of the common argument checks. - // - // We also bail on unknown and ignored attributes because those are handled - // as part of the target-specific handling logic. - if (AL.getKind() == ParsedAttr::UnknownAttribute) - return false; - // Check whether the attribute requires specific language extensions to be - // enabled. - if (!AL.diagnoseLangOpts(S)) - return true; - // Check whether the attribute appertains to the given subject. - if (!AL.diagnoseAppertainsTo(S, D)) - return true; - if (AL.hasCustomParsing()) - return false; - - if (AL.getMinArgs() == AL.getMaxArgs()) { - // If there are no optional arguments, then checking for the argument count - // is trivial. - if (!checkAttributeNumArgs(S, AL, AL.getMinArgs())) - return true; - } else { - // There are optional arguments, so checking is slightly more involved. - if (AL.getMinArgs() && - !checkAttributeAtLeastNumArgs(S, AL, AL.getMinArgs())) - return true; - else if (!AL.hasVariadicArg() && AL.getMaxArgs() && - !checkAttributeAtMostNumArgs(S, AL, AL.getMaxArgs())) - return true; - } - - if (S.CheckAttrTarget(AL)) - return true; - - return false; -} - static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (D->isInvalidDecl()) return; @@ -7804,7 +7717,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, return; } - if (handleCommonAttributeFeatures(S, D, AL)) + if (S.checkCommonAttributeFeatures(D, AL)) return; switch (AL.getKind()) { @@ -7816,6 +7729,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, assert(AL.isTypeAttr() && "Non-type attribute not handled"); break; } + // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a + // statement attribute is not written on a declaration, but this code is + // needed for attributes in Attr.td that do not list any subjects. S.Diag(AL.getLoc(), diag::err_stmt_attribute_invalid_on_decl) << AL << D->getLocation(); break; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 940ef796ce5e..f54dd4cb6f43 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -254,8 +254,7 @@ void Sema::ImplicitExceptionSpecification::CalledStmt(Stmt *S) { ComputedEST = EST_None; } -ExprResult Sema::ConvertParamDefaultArgument(const ParmVarDecl *Param, - Expr *Arg, +ExprResult Sema::ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *Arg, SourceLocation EqualLoc) { if (RequireCompleteType(Param->getLocation(), Param->getType(), diag::err_typecheck_decl_incomplete_type)) @@ -4130,13 +4129,9 @@ ValueDecl *Sema::tryLookupCtorInitMemberDecl(CXXRecordDecl *ClassDecl, IdentifierInfo *MemberOrBase) { if (SS.getScopeRep() || TemplateTypeTy) return nullptr; - DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase); - if (Result.empty()) - return nullptr; - ValueDecl *Member; - if ((Member = dyn_cast(Result.front())) || - (Member = dyn_cast(Result.front()))) - return Member; + for (auto *D : ClassDecl->lookup(MemberOrBase)) + if (isa(D) || isa(D)) + return cast(D); return nullptr; } @@ -5239,6 +5234,20 @@ static const void *GetKeyForMember(ASTContext &Context, return Member->getAnyMember()->getCanonicalDecl(); } +static void AddInitializerToDiag(const Sema::SemaDiagnosticBuilder &Diag, + const CXXCtorInitializer *Previous, + const CXXCtorInitializer *Current) { + if (Previous->isAnyMemberInitializer()) + Diag << 0 << Previous->getAnyMember(); + else + Diag << 1 << Previous->getTypeSourceInfo()->getType(); + + if (Current->isAnyMemberInitializer()) + Diag << 0 << Current->getAnyMember(); + else + Diag << 1 << Current->getTypeSourceInfo()->getType(); +} + static void DiagnoseBaseOrMemInitializerOrder( Sema &SemaRef, const CXXConstructorDecl *Constructor, ArrayRef Inits) { @@ -5288,10 +5297,15 @@ static void DiagnoseBaseOrMemInitializerOrder( unsigned NumIdealInits = IdealInitKeys.size(); unsigned IdealIndex = 0; - CXXCtorInitializer *PrevInit = nullptr; + // Track initializers that are in an incorrect order for either a warning or + // note if multiple ones occur. + SmallVector WarnIndexes; + // Correlates the index of an initializer in the init-list to the index of + // the field/base in the class. + SmallVector, 32> CorrelatedInitOrder; + for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) { - CXXCtorInitializer *Init = Inits[InitIndex]; - const void *InitKey = GetKeyForMember(SemaRef.Context, Init); + const void *InitKey = GetKeyForMember(SemaRef.Context, Inits[InitIndex]); // Scan forward to try to find this initializer in the idealized // initializers list. @@ -5302,20 +5316,8 @@ static void DiagnoseBaseOrMemInitializerOrder( // If we didn't find this initializer, it must be because we // scanned past it on a previous iteration. That can only // happen if we're out of order; emit a warning. - if (IdealIndex == NumIdealInits && PrevInit) { - Sema::SemaDiagnosticBuilder D = - SemaRef.Diag(PrevInit->getSourceLocation(), - diag::warn_initializer_out_of_order); - - if (PrevInit->isAnyMemberInitializer()) - D << 0 << PrevInit->getAnyMember()->getDeclName(); - else - D << 1 << PrevInit->getTypeSourceInfo()->getType(); - - if (Init->isAnyMemberInitializer()) - D << 0 << Init->getAnyMember()->getDeclName(); - else - D << 1 << Init->getTypeSourceInfo()->getType(); + if (IdealIndex == NumIdealInits && InitIndex) { + WarnIndexes.push_back(InitIndex); // Move back to the initializer's location in the ideal list. for (IdealIndex = 0; IdealIndex != NumIdealInits; ++IdealIndex) @@ -5325,8 +5327,54 @@ static void DiagnoseBaseOrMemInitializerOrder( assert(IdealIndex < NumIdealInits && "initializer not found in initializer list"); } + CorrelatedInitOrder.emplace_back(IdealIndex, InitIndex); + } - PrevInit = Init; + if (WarnIndexes.empty()) + return; + + // Sort based on the ideal order, first in the pair. + llvm::sort(CorrelatedInitOrder, + [](auto &LHS, auto &RHS) { return LHS.first < RHS.first; }); + + // Introduce a new scope as SemaDiagnosticBuilder needs to be destroyed to + // emit the diagnostic before we can try adding notes. + { + Sema::SemaDiagnosticBuilder D = SemaRef.Diag( + Inits[WarnIndexes.front() - 1]->getSourceLocation(), + WarnIndexes.size() == 1 ? diag::warn_initializer_out_of_order + : diag::warn_some_initializers_out_of_order); + + for (unsigned I = 0; I < CorrelatedInitOrder.size(); ++I) { + if (CorrelatedInitOrder[I].second == I) + continue; + // Ideally we would be using InsertFromRange here, but clang doesn't + // appear to handle InsertFromRange correctly when the source range is + // modified by another fix-it. + D << FixItHint::CreateReplacement( + Inits[I]->getSourceRange(), + Lexer::getSourceText( + CharSourceRange::getTokenRange( + Inits[CorrelatedInitOrder[I].second]->getSourceRange()), + SemaRef.getSourceManager(), SemaRef.getLangOpts())); + } + + // If there is only 1 item out of order, the warning expects the name and + // type of each being added to it. + if (WarnIndexes.size() == 1) { + AddInitializerToDiag(D, Inits[WarnIndexes.front() - 1], + Inits[WarnIndexes.front()]); + return; + } + } + // More than 1 item to warn, create notes letting the user know which ones + // are bad. + for (unsigned WarnIndex : WarnIndexes) { + const clang::CXXCtorInitializer *PrevInit = Inits[WarnIndex - 1]; + auto D = SemaRef.Diag(PrevInit->getSourceLocation(), + diag::note_initializer_out_of_order); + AddInitializerToDiag(D, PrevInit, Inits[WarnIndex]); + D << PrevInit->getSourceRange(); } } @@ -5394,7 +5442,7 @@ bool CheckRedundantUnionInit(Sema &S, return false; } -} +} // namespace /// ActOnMemInitializers - Handle the member initializers for a constructor. void Sema::ActOnMemInitializers(Decl *ConstructorDecl, @@ -7632,7 +7680,7 @@ class DefaultedComparisonAnalyzer private: Subobject getCompleteObject() { - return Subobject{Subobject::CompleteObject, nullptr, FD->getLocation()}; + return Subobject{Subobject::CompleteObject, RD, FD->getLocation()}; } Subobject getBase(CXXBaseSpecifier *Base) { @@ -9672,9 +9720,9 @@ struct FindHiddenVirtualMethod { bool foundSameNameMethod = false; SmallVector overloadedMethods; - for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - NamedDecl *D = Path.Decls.front(); + for (Path.Decls = BaseRecord->lookup(Name).begin(); + Path.Decls != DeclContext::lookup_iterator(); ++Path.Decls) { + NamedDecl *D = *Path.Decls; if (CXXMethodDecl *MD = dyn_cast(D)) { MD = MD->getCanonicalDecl(); foundSameNameMethod = true; diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 3ada5729c27a..12f47cb0630d 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1486,6 +1486,8 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OMPTeamsDistributeParallelForDirectiveClass: case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: case Stmt::OMPTeamsDistributeSimdDirectiveClass: + case Stmt::OMPInteropDirectiveClass: + case Stmt::OMPDispatchDirectiveClass: case Stmt::ReturnStmtClass: case Stmt::SEHExceptStmtClass: case Stmt::SEHFinallyStmtClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f39c73e206ce..ae1260b6e91e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -46,6 +46,7 @@ #include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/SaveAndRestore.h" using namespace clang; @@ -657,7 +658,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { return E; // OpenCL usually rejects direct accesses to values of 'half' type. - if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") && + if (getLangOpts().OpenCL && + !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) && T->isHalfType()) { Diag(E->getExprLoc(), diag::err_opencl_half_load_store) << 0 << T; @@ -829,10 +831,10 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { if (BTy && (BTy->getKind() == BuiltinType::Half || BTy->getKind() == BuiltinType::Float)) { if (getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("cl_khr_fp64")) { - if (BTy->getKind() == BuiltinType::Half) { - E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); - } + !getOpenCLOptions().isAvailableOption("cl_khr_fp64", getLangOpts())) { + if (BTy->getKind() == BuiltinType::Half) { + E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); + } } else { E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); } @@ -3819,7 +3821,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } else if (Literal.isFloatingLiteral()) { QualType Ty; if (Literal.isHalf){ - if (getOpenCLOptions().isEnabled("cl_khr_fp16")) + if (getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts())) Ty = Context.HalfTy; else { Diag(Tok.getLocation(), diag::err_half_const_requires_fp16); @@ -3843,8 +3845,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { if (Ty->castAs()->getKind() != BuiltinType::Float) { Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get(); } - } else if (getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("cl_khr_fp64")) { + } else if (getLangOpts().OpenCL && !getOpenCLOptions().isAvailableOption( + "cl_khr_fp64", getLangOpts())) { // Impose single-precision float type when cl_khr_fp64 is not enabled. Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64); Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get(); @@ -3865,6 +3867,14 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Diag(Tok.getLocation(), diag::ext_c99_longlong); } + // 'z/uz' literals are a C++2b feature. + if (Literal.isSizeT) + Diag(Tok.getLocation(), getLangOpts().CPlusPlus + ? getLangOpts().CPlusPlus2b + ? diag::warn_cxx20_compat_size_t_suffix + : diag::ext_cxx2b_size_t_suffix + : diag::err_cxx2b_size_t_suffix); + // Get the value in the widest-possible width. unsigned MaxWidth = Context.getTargetInfo().getIntMaxTWidth(); llvm::APInt ResultVal(MaxWidth, 0); @@ -3899,7 +3909,26 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } } - if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) { + // Check C++2b size_t literals. + if (Literal.isSizeT) { + assert(!Literal.MicrosoftInteger && + "size_t literals can't be Microsoft literals"); + unsigned SizeTSize = Context.getTargetInfo().getTypeWidth( + Context.getTargetInfo().getSizeType()); + + // Does it fit in size_t? + if (ResultVal.isIntN(SizeTSize)) { + // Does it fit in ssize_t? + if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0) + Ty = Context.getSignedSizeType(); + else if (AllowUnsigned) + Ty = Context.getSizeType(); + Width = SizeTSize; + } + } + + if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong && + !Literal.isSizeT) { // Are int/unsigned possibilities? unsigned IntSize = Context.getTargetInfo().getIntWidth(); @@ -3915,7 +3944,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } // Are long/unsigned long possibilities? - if (Ty.isNull() && !Literal.isLongLong) { + if (Ty.isNull() && !Literal.isLongLong && !Literal.isSizeT) { unsigned LongSize = Context.getTargetInfo().getLongWidth(); // Does it fit in a unsigned long? @@ -3946,7 +3975,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } // Check long long if needed. - if (Ty.isNull()) { + if (Ty.isNull() && !Literal.isSizeT) { unsigned LongLongSize = Context.getTargetInfo().getLongLongWidth(); // Does it fit in a unsigned long long? @@ -3963,10 +3992,16 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } } - // If we still couldn't decide a type, we probably have something that - // does not fit in a signed long long, but has no U suffix. + // If we still couldn't decide a type, we either have 'size_t' literal + // that is out of range, or a decimal literal that does not fit in a + // signed long long and has no U suffix. if (Ty.isNull()) { - Diag(Tok.getLocation(), diag::ext_integer_literal_too_large_for_signed); + if (Literal.isSizeT) + Diag(Tok.getLocation(), diag::err_size_t_literal_too_large) + << Literal.isUnsigned; + else + Diag(Tok.getLocation(), + diag::ext_integer_literal_too_large_for_signed); Ty = Context.UnsignedLongLongTy; Width = Context.getTargetInfo().getLongLongWidth(); } @@ -6495,24 +6530,30 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, ExecConfig, IsExecConfig); } -/// ActOnAsTypeExpr - create a new asType (bitcast) from the arguments. +/// Parse a __builtin_astype expression. /// /// __builtin_astype( value, dst type ) /// ExprResult Sema::ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc) { + QualType DstTy = GetTypeFromParser(ParsedDestTy); + return BuildAsTypeExpr(E, DstTy, BuiltinLoc, RParenLoc); +} + +/// Create a new AsTypeExpr node (bitcast) from the arguments. +ExprResult Sema::BuildAsTypeExpr(Expr *E, QualType DestTy, + SourceLocation BuiltinLoc, + SourceLocation RParenLoc) { ExprValueKind VK = VK_RValue; ExprObjectKind OK = OK_Ordinary; - QualType DstTy = GetTypeFromParser(ParsedDestTy); QualType SrcTy = E->getType(); - if (Context.getTypeSize(DstTy) != Context.getTypeSize(SrcTy)) - return ExprError(Diag(BuiltinLoc, - diag::err_invalid_astype_of_different_size) - << DstTy - << SrcTy - << E->getSourceRange()); - return new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc, RParenLoc); + if (!SrcTy->isDependentType() && + Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)) + return ExprError( + Diag(BuiltinLoc, diag::err_invalid_astype_of_different_size) + << DestTy << SrcTy << E->getSourceRange()); + return new (Context) AsTypeExpr(E, DestTy, VK, OK, BuiltinLoc, RParenLoc); } /// ActOnConvertVectorExpr - create a new convert-vector expression from the @@ -10218,16 +10259,21 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, bool IsCompAssign, bool IsDiv) { checkArithmeticNull(*this, LHS, RHS, Loc, /*IsCompare=*/false); - if (LHS.get()->getType()->isVectorType() || - RHS.get()->getType()->isVectorType()) + QualType LHSTy = LHS.get()->getType(); + QualType RHSTy = RHS.get()->getType(); + if (LHSTy->isVectorType() || RHSTy->isVectorType()) return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, /*AllowBothBool*/ getLangOpts().AltiVec, /*AllowBoolConversions*/ false, /*AllowBooleanOperation*/ false, /*ReportInvalid*/ true); - if (!IsDiv && (LHS.get()->getType()->isConstantMatrixType() || - RHS.get()->getType()->isConstantMatrixType())) + if (!IsDiv && + (LHSTy->isConstantMatrixType() || RHSTy->isConstantMatrixType())) return CheckMatrixMultiplyOperands(LHS, RHS, Loc, IsCompAssign); + // For division, only matrix-by-scalar is supported. Other combinations with + // matrix types are invalid. + if (IsDiv && LHSTy->isConstantMatrixType() && RHSTy->isArithmeticType()) + return CheckMatrixElementwiseOperands(LHS, RHS, Loc, IsCompAssign); QualType compType = UsualArithmeticConversions( LHS, RHS, Loc, IsCompAssign ? ACK_CompAssign : ACK_Arithmetic); @@ -12989,8 +13035,9 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, // OpenCL v1.2 s6.1.1.1 p2: // The half data type can only be used to declare a pointer to a buffer that // contains half values - if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") && - LHSType->isHalfType()) { + if (getLangOpts().OpenCL && + !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) && + LHSType->isHalfType()) { Diag(Loc, diag::err_opencl_half_load_store) << 1 << LHSType.getUnqualifiedType(); return QualType(); @@ -17492,6 +17539,107 @@ static bool captureInLambda(LambdaScopeInfo *LSI, return !Invalid; } +static bool canCaptureVariableByCopy(VarDecl *Var, const ASTContext &Context) { + // Offer a Copy fix even if the type is dependent. + if (Var->getType()->isDependentType()) + return true; + QualType T = Var->getType().getNonReferenceType(); + if (T.isTriviallyCopyableType(Context)) + return true; + if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) { + + if (!(RD = RD->getDefinition())) + return false; + if (RD->hasSimpleCopyConstructor()) + return true; + if (RD->hasUserDeclaredCopyConstructor()) + for (CXXConstructorDecl *Ctor : RD->ctors()) + if (Ctor->isCopyConstructor()) + return !Ctor->isDeleted(); + } + return false; +} + +/// Create up to 4 fix-its for explicit reference and value capture of \p Var or +/// default capture. Fixes may be omitted if they aren't allowed by the +/// standard, for example we can't emit a default copy capture fix-it if we +/// already explicitly copy capture capture another variable. +static void buildLambdaCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI, + VarDecl *Var) { + assert(LSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None); + // Don't offer Capture by copy of default capture by copy fixes if Var is + // known not to be copy constructible. + bool ShouldOfferCopyFix = canCaptureVariableByCopy(Var, Sema.getASTContext()); + + SmallString<32> FixBuffer; + StringRef Separator = LSI->NumExplicitCaptures > 0 ? ", " : ""; + if (Var->getDeclName().isIdentifier() && !Var->getName().empty()) { + SourceLocation VarInsertLoc = LSI->IntroducerRange.getEnd(); + if (ShouldOfferCopyFix) { + // Offer fixes to insert an explicit capture for the variable. + // [] -> [VarName] + // [OtherCapture] -> [OtherCapture, VarName] + FixBuffer.assign({Separator, Var->getName()}); + Sema.Diag(VarInsertLoc, diag::note_lambda_variable_capture_fixit) + << Var << /*value*/ 0 + << FixItHint::CreateInsertion(VarInsertLoc, FixBuffer); + } + // As above but capture by reference. + FixBuffer.assign({Separator, "&", Var->getName()}); + Sema.Diag(VarInsertLoc, diag::note_lambda_variable_capture_fixit) + << Var << /*reference*/ 1 + << FixItHint::CreateInsertion(VarInsertLoc, FixBuffer); + } + + // Only try to offer default capture if there are no captures excluding this + // and init captures. + // [this]: OK. + // [X = Y]: OK. + // [&A, &B]: Don't offer. + // [A, B]: Don't offer. + if (llvm::any_of(LSI->Captures, [](Capture &C) { + return !C.isThisCapture() && !C.isInitCapture(); + })) + return; + + // The default capture specifiers, '=' or '&', must appear first in the + // capture body. + SourceLocation DefaultInsertLoc = + LSI->IntroducerRange.getBegin().getLocWithOffset(1); + + if (ShouldOfferCopyFix) { + bool CanDefaultCopyCapture = true; + // [=, *this] OK since c++17 + // [=, this] OK since c++20 + if (LSI->isCXXThisCaptured() && !Sema.getLangOpts().CPlusPlus20) + CanDefaultCopyCapture = Sema.getLangOpts().CPlusPlus17 + ? LSI->getCXXThisCapture().isCopyCapture() + : false; + // We can't use default capture by copy if any captures already specified + // capture by copy. + if (CanDefaultCopyCapture && llvm::none_of(LSI->Captures, [](Capture &C) { + return !C.isThisCapture() && !C.isInitCapture() && C.isCopyCapture(); + })) { + FixBuffer.assign({"=", Separator}); + Sema.Diag(DefaultInsertLoc, diag::note_lambda_default_capture_fixit) + << /*value*/ 0 + << FixItHint::CreateInsertion(DefaultInsertLoc, FixBuffer); + } + } + + // We can't use default capture by reference if any captures already specified + // capture by reference. + if (llvm::none_of(LSI->Captures, [](Capture &C) { + return !C.isInitCapture() && C.isReferenceCapture() && + !C.isThisCapture(); + })) { + FixBuffer.assign({"&", Separator}); + Sema.Diag(DefaultInsertLoc, diag::note_lambda_default_capture_fixit) + << /*reference*/ 1 + << FixItHint::CreateInsertion(DefaultInsertLoc, FixBuffer); + } +} + bool Sema::tryCaptureVariable( VarDecl *Var, SourceLocation ExprLoc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, @@ -17581,6 +17729,7 @@ bool Sema::tryCaptureVariable( Diag(ExprLoc, diag::err_lambda_impcap) << Var; Diag(Var->getLocation(), diag::note_previous_decl) << Var; Diag(LSI->Lambda->getBeginLoc(), diag::note_lambda_decl); + buildLambdaCaptureFixit(*this, LSI, Var); } else diagnoseUncapturableValueReference(*this, ExprLoc, Var, DC); } @@ -17659,9 +17808,11 @@ bool Sema::tryCaptureVariable( if (BuildAndDiagnose) { Diag(ExprLoc, diag::err_lambda_impcap) << Var; Diag(Var->getLocation(), diag::note_previous_decl) << Var; - if (cast(CSI)->Lambda) - Diag(cast(CSI)->Lambda->getBeginLoc(), - diag::note_lambda_decl); + auto *LSI = cast(CSI); + if (LSI->Lambda) { + Diag(LSI->Lambda->getBeginLoc(), diag::note_lambda_decl); + buildLambdaCaptureFixit(*this, LSI, Var); + } // FIXME: If we error out because an outer lambda can not implicitly // capture a variable that an inner lambda explicitly captures, we // should have the inner lambda do the explicit capture - because diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4dd806fdff69..dfaa66ec9575 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1226,6 +1226,18 @@ Sema::CXXThisScopeRAII::~CXXThisScopeRAII() { } } +static void buildLambdaThisCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI) { + SourceLocation DiagLoc = LSI->IntroducerRange.getEnd(); + assert(!LSI->isCXXThisCaptured()); + // [=, this] {}; // until C++20: Error: this when = is the default + if (LSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval && + !Sema.getLangOpts().CPlusPlus20) + return; + Sema.Diag(DiagLoc, diag::note_lambda_this_capture_fixit) + << FixItHint::CreateInsertion( + DiagLoc, LSI->NumExplicitCaptures > 0 ? ", this" : "this"); +} + bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit, bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt, const bool ByCopy) { @@ -1274,9 +1286,12 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit, LambdaScopeInfo *LSI = dyn_cast(CSI); if (LSI && isGenericLambdaCallOperatorSpecialization(LSI->CallOperator)) { // This context can't implicitly capture 'this'; fail out. - if (BuildAndDiagnose) + if (BuildAndDiagnose) { Diag(Loc, diag::err_this_capture) << (Explicit && idx == MaxFunctionScopesIndex); + if (!Explicit) + buildLambdaThisCaptureFixit(*this, LSI); + } return true; } if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref || @@ -1296,6 +1311,9 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit, if (BuildAndDiagnose) Diag(Loc, diag::err_this_capture) << (Explicit && idx == MaxFunctionScopesIndex); + + if (!Explicit) + buildLambdaThisCaptureFixit(*this, LSI); return true; } break; @@ -4856,9 +4874,11 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, case UTT_IsSigned: // Enum types should always return false. // Floating points should always return true. - return !T->isEnumeralType() && (T->isFloatingType() || T->isSignedIntegerType()); + return T->isFloatingType() || + (T->isSignedIntegerType() && !T->isEnumeralType()); case UTT_IsUnsigned: - return T->isUnsignedIntegerType(); + // Enum types should always return false. + return T->isUnsignedIntegerType() && !T->isEnumeralType(); // Type trait expressions which query classes regarding their construction, // destruction, and copying. Rather than being based directly on the @@ -8645,7 +8665,7 @@ Sema::BuildExprRequirement( TemplateParameterList *TPL = ReturnTypeRequirement.getTypeConstraintTemplateParameterList(); QualType MatchedType = - BuildDecltypeType(E, E->getBeginLoc()).getCanonicalType(); + getDecltypeForParenthesizedExpr(E).getCanonicalType(); llvm::SmallVector Args; Args.push_back(TemplateArgument(MatchedType)); TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 2f4e134181ce..ec7e4722ea4e 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -24,6 +24,7 @@ #include "clang/Sema/Lookup.h" #include "clang/Sema/SemaInternal.h" #include "llvm/ADT/APInt.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -3281,10 +3282,7 @@ InitializedEntity::InitializeBase(ASTContext &Context, InitializedEntity Result; Result.Kind = EK_Base; Result.Parent = Parent; - Result.Base = reinterpret_cast(Base); - if (IsInheritedVirtualBase) - Result.Base |= 0x01; - + Result.Base = {Base, IsInheritedVirtualBase}; Result.Type = Base->getType(); return Result; } @@ -3293,7 +3291,7 @@ DeclarationName InitializedEntity::getName() const { switch (getKind()) { case EK_Parameter: case EK_Parameter_CF_Audited: { - ParmVarDecl *D = reinterpret_cast(Parameter & ~0x1); + ParmVarDecl *D = Parameter.getPointer(); return (D ? D->getDeclName() : DeclarationName()); } @@ -3336,7 +3334,7 @@ ValueDecl *InitializedEntity::getDecl() const { case EK_Parameter: case EK_Parameter_CF_Audited: - return reinterpret_cast(Parameter & ~0x1); + return Parameter.getPointer(); case EK_Result: case EK_StmtExprResult: @@ -5607,8 +5605,8 @@ static bool TryOCLZeroOpaqueTypeInitialization(Sema &S, // We should allow zero initialization for all types defined in the // cl_intel_device_side_avc_motion_estimation extension, except // intel_sub_group_avc_mce_payload_t and intel_sub_group_avc_mce_result_t. - if (S.getOpenCLOptions().isEnabled( - "cl_intel_device_side_avc_motion_estimation") && + if (S.getOpenCLOptions().isAvailableOption( + "cl_intel_device_side_avc_motion_estimation", S.getLangOpts()) && DestType->isOCLIntelSubgroupAVCType()) { if (DestType->isOCLIntelSubgroupAVCMcePayloadType() || DestType->isOCLIntelSubgroupAVCMceResultType()) @@ -8795,8 +8793,8 @@ ExprResult InitializationSequence::Perform(Sema &S, unsigned AddressingMode = (0x0E & SamplerValue) >> 1; unsigned FilterMode = (0x30 & SamplerValue) >> 4; if (FilterMode != 1 && FilterMode != 2 && - !S.getOpenCLOptions().isEnabled( - "cl_intel_device_side_avc_motion_estimation")) + !S.getOpenCLOptions().isAvailableOption( + "cl_intel_device_side_avc_motion_estimation", S.getLangOpts())) S.Diag(Kind.getLocation(), diag::warn_sampler_initializer_invalid_bits) << "Filter Mode"; diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 4da81bb44d5b..fef96b2eb11f 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -638,8 +638,8 @@ void LookupResult::resolveKind() { void LookupResult::addDeclsFromBasePaths(const CXXBasePaths &P) { CXXBasePaths::const_paths_iterator I, E; for (I = P.begin(), E = P.end(); I != E; ++I) - for (DeclContext::lookup_iterator DI = I->Decls.begin(), - DE = I->Decls.end(); DI != DE; ++DI) + for (DeclContext::lookup_iterator DI = I->Decls, DE = DI.end(); DI != DE; + ++DI) addDecl(*DI); } @@ -755,7 +755,8 @@ static void GetOpenCLBuiltinFctOverloads( ASTContext &Context, unsigned GenTypeMaxCnt, std::vector &FunctionList, SmallVector &RetTypes, SmallVector, 5> &ArgTypes) { - FunctionProtoType::ExtProtoInfo PI; + FunctionProtoType::ExtProtoInfo PI( + Context.getDefaultCallingConvention(false, false, true)); PI.Variadic = false; // Create FunctionTypes for each (gen)type. @@ -2229,9 +2230,9 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, CXXRecordDecl *BaseRecord = Specifier->getType()->getAsCXXRecordDecl(); // Drop leading non-matching lookup results from the declaration list so // we don't need to consider them again below. - for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) + for (Path.Decls = BaseRecord->lookup(Name).begin(); + Path.Decls != Path.Decls.end(); ++Path.Decls) { + if ((*Path.Decls)->isInIdentifierNamespace(IDNS)) return true; } return false; @@ -2255,9 +2256,9 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, AccessSpecifier SubobjectAccess = AS_none; // Check whether the given lookup result contains only static members. - auto HasOnlyStaticMembers = [&](DeclContextLookupResult Result) { - for (NamedDecl *ND : Result) - if (ND->isInIdentifierNamespace(IDNS) && ND->isCXXInstanceMember()) + auto HasOnlyStaticMembers = [&](DeclContext::lookup_iterator Result) { + for (DeclContext::lookup_iterator I = Result, E = I.end(); I != E; ++I) + if ((*I)->isInIdentifierNamespace(IDNS) && (*I)->isCXXInstanceMember()) return false; return true; }; @@ -2266,8 +2267,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, // Determine whether two sets of members contain the same members, as // required by C++ [class.member.lookup]p6. - auto HasSameDeclarations = [&](DeclContextLookupResult A, - DeclContextLookupResult B) { + auto HasSameDeclarations = [&](DeclContext::lookup_iterator A, + DeclContext::lookup_iterator B) { using Iterator = DeclContextLookupResult::iterator; using Result = const void *; @@ -2304,7 +2305,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, // We'll often find the declarations are in the same order. Handle this // case (and the special case of only one declaration) efficiently. - Iterator AIt = A.begin(), BIt = B.begin(), AEnd = A.end(), BEnd = B.end(); + Iterator AIt = A, BIt = B, AEnd, BEnd; while (true) { Result AResult = Next(AIt, AEnd); Result BResult = Next(BIt, BEnd); @@ -2387,10 +2388,11 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, // Lookup in a base class succeeded; return these results. - for (auto *D : Paths.front().Decls) { + for (DeclContext::lookup_iterator I = Paths.front().Decls, E = I.end(); + I != E; ++I) { AccessSpecifier AS = CXXRecordDecl::MergeAccess(SubobjectAccess, - D->getAccess()); - if (NamedDecl *ND = R.getAcceptableDecl(D)) + (*I)->getAccess()); + if (NamedDecl *ND = R.getAcceptableDecl(*I)) R.addDecl(ND, AS); } R.resolveKind(); @@ -2533,7 +2535,7 @@ void Sema::DiagnoseAmbiguousLookup(LookupResult &Result) { << Name << SubobjectType << getAmbiguousPathsDisplayString(*Paths) << LookupRange; - DeclContext::lookup_iterator Found = Paths->front().Decls.begin(); + DeclContext::lookup_iterator Found = Paths->front().Decls; while (isa(*Found) && cast(*Found)->isStatic()) ++Found; @@ -2551,7 +2553,7 @@ void Sema::DiagnoseAmbiguousLookup(LookupResult &Result) { for (CXXBasePaths::paths_iterator Path = Paths->begin(), PathEnd = Paths->end(); Path != PathEnd; ++Path) { - const NamedDecl *D = Path->Decls.front(); + const NamedDecl *D = *Path->Decls; if (!D->isInIdentifierNamespace(Result.getIdentifierNamespace())) continue; if (DeclsPrinted.insert(D).second) { diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index fdc30fe6f657..db999270219c 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -112,12 +112,10 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, return; // Look for a property with the same name. - DeclContext::lookup_result R = Proto->lookup(Prop->getDeclName()); - for (unsigned I = 0, N = R.size(); I != N; ++I) { - if (ObjCPropertyDecl *ProtoProp = dyn_cast(R[I])) { - S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); - return; - } + if (ObjCPropertyDecl *ProtoProp = + Proto->lookup(Prop->getDeclName()).find_first()) { + S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); + return; } // Check this property against any protocols we inherit. @@ -233,18 +231,13 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, bool FoundInSuper = false; ObjCInterfaceDecl *CurrentInterfaceDecl = IFace; while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) { - DeclContext::lookup_result R = Super->lookup(Res->getDeclName()); - for (unsigned I = 0, N = R.size(); I != N; ++I) { - if (ObjCPropertyDecl *SuperProp = dyn_cast(R[I])) { - DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false); - FoundInSuper = true; - break; - } - } - if (FoundInSuper) + if (ObjCPropertyDecl *SuperProp = + Super->lookup(Res->getDeclName()).find_first()) { + DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false); + FoundInSuper = true; break; - else - CurrentInterfaceDecl = Super; + } + CurrentInterfaceDecl = Super; } if (FoundInSuper) { @@ -1149,14 +1142,13 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // redeclared 'readwrite', then no warning is to be issued. for (auto *Ext : IDecl->known_extensions()) { DeclContext::lookup_result R = Ext->lookup(property->getDeclName()); - if (!R.empty()) - if (ObjCPropertyDecl *ExtProp = dyn_cast(R[0])) { - PIkind = ExtProp->getPropertyAttributesAsWritten(); - if (PIkind & ObjCPropertyAttribute::kind_readwrite) { - ReadWriteProperty = true; - break; - } + if (auto *ExtProp = R.find_first()) { + PIkind = ExtProp->getPropertyAttributesAsWritten(); + if (PIkind & ObjCPropertyAttribute::kind_readwrite) { + ReadWriteProperty = true; + break; } + } } if (!ReadWriteProperty) { diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 2da772d3f41a..48fe19e50ee7 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3979,7 +3979,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_distribute: case OMPD_distribute_simd: case OMPD_ordered: - case OMPD_target_data: { + case OMPD_target_data: + case OMPD_dispatch: { Sema::CapturedParamNameType Params[] = { std::make_pair(StringRef(), QualType()) // __context with shared vars }; @@ -6115,6 +6116,15 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( if (LangOpts.OpenMP >= 50) AllowedNameModifiers.push_back(OMPD_simd); break; + case OMPD_interop: + assert(AStmt == nullptr && + "No associated statement allowed for 'omp interop' directive"); + Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); + break; + case OMPD_dispatch: + Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, + EndLoc); + break; case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_threadprivate: @@ -9753,6 +9763,64 @@ StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, DSAStack->isCancelRegion()); } +static Expr *getDirectCallExpr(Expr *E) { + E = E->IgnoreParenCasts()->IgnoreImplicit(); + if (auto *CE = dyn_cast(E)) + if (CE->getDirectCallee()) + return E; + return nullptr; +} + +StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc) { + if (!AStmt) + return StmtError(); + + Stmt *S = cast(AStmt)->getCapturedStmt(); + + // 5.1 OpenMP + // expression-stmt : an expression statement with one of the following forms: + // expression = target-call ( [expression-list] ); + // target-call ( [expression-list] ); + + SourceLocation TargetCallLoc; + + if (!CurContext->isDependentContext()) { + Expr *TargetCall = nullptr; + + auto *E = dyn_cast(S); + if (!E) { + Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); + return StmtError(); + } + + E = E->IgnoreParenCasts()->IgnoreImplicit(); + + if (auto *BO = dyn_cast(E)) { + if (BO->getOpcode() == BO_Assign) + TargetCall = getDirectCallExpr(BO->getRHS()); + } else { + if (auto *COCE = dyn_cast(E)) + if (COCE->getOperator() == OO_Equal) + TargetCall = getDirectCallExpr(COCE->getArg(1)); + if (!TargetCall) + TargetCall = getDirectCallExpr(E); + } + if (!TargetCall) { + Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); + return StmtError(); + } + TargetCallLoc = TargetCall->getExprLoc(); + } + + setFunctionHasBranchProtectedScope(); + + return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, + TargetCallLoc); +} + StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, @@ -13344,9 +13412,11 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_target_parallel_for_simd: case OMPD_target_teams_distribute_parallel_for: case OMPD_target_teams_distribute_parallel_for_simd: + case OMPD_dispatch: CaptureRegion = OMPD_task; break; case OMPD_target_data: + case OMPD_interop: // Do not capture device-clause expressions. break; case OMPD_teams_distribute_parallel_for: @@ -14435,7 +14505,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); break; case OMPC_destroy: - Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); + Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, + /*LParenLoc=*/SourceLocation(), + /*VarLoc=*/SourceLocation(), EndLoc); break; case OMPC_if: case OMPC_final: @@ -14593,9 +14665,187 @@ OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); } -OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, +StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc) { + + // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] + // At least one action-clause must appear on a directive. + if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { + StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; + Diag(StartLoc, diag::err_omp_no_clause_for_directive) + << Expected << getOpenMPDirectiveName(OMPD_interop); + return StmtError(); + } + + // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] + // A depend clause can only appear on the directive if a targetsync + // interop-type is present or the interop-var was initialized with + // the targetsync interop-type. + + // If there is any 'init' clause diagnose if there is no 'init' clause with + // interop-type of 'targetsync'. Cases involving other directives cannot be + // diagnosed. + const OMPDependClause *DependClause = nullptr; + bool HasInitClause = false; + bool IsTargetSync = false; + for (const OMPClause *C : Clauses) { + if (IsTargetSync) + break; + if (const auto *InitClause = dyn_cast(C)) { + HasInitClause = true; + if (InitClause->getIsTargetSync()) + IsTargetSync = true; + } else if (const auto *DC = dyn_cast(C)) { + DependClause = DC; + } + } + if (DependClause && HasInitClause && !IsTargetSync) { + Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); + return StmtError(); + } + + // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] + // Each interop-var may be specified for at most one action-clause of each + // interop construct. + llvm::SmallPtrSet InteropVars; + for (const OMPClause *C : Clauses) { + OpenMPClauseKind ClauseKind = C->getClauseKind(); + const DeclRefExpr *DRE = nullptr; + SourceLocation VarLoc; + + if (ClauseKind == OMPC_init) { + const auto *IC = cast(C); + VarLoc = IC->getVarLoc(); + DRE = dyn_cast_or_null(IC->getInteropVar()); + } else if (ClauseKind == OMPC_use) { + const auto *UC = cast(C); + VarLoc = UC->getVarLoc(); + DRE = dyn_cast_or_null(UC->getInteropVar()); + } else if (ClauseKind == OMPC_destroy) { + const auto *DC = cast(C); + VarLoc = DC->getVarLoc(); + DRE = dyn_cast_or_null(DC->getInteropVar()); + } + + if (!DRE) + continue; + + if (const auto *VD = dyn_cast(DRE->getDecl())) { + if (!InteropVars.insert(VD->getCanonicalDecl()).second) { + Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD; + return StmtError(); + } + } + } + + return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); +} + +static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, + SourceLocation VarLoc, + OpenMPClauseKind Kind) { + if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() || + InteropVarExpr->isInstantiationDependent() || + InteropVarExpr->containsUnexpandedParameterPack()) + return true; + + const auto *DRE = dyn_cast(InteropVarExpr); + if (!DRE || !isa(DRE->getDecl())) { + SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0; + return false; + } + + // Interop variable should be of type omp_interop_t. + bool HasError = false; + QualType InteropType; + LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), + VarLoc, Sema::LookupOrdinaryName); + if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { + NamedDecl *ND = Result.getFoundDecl(); + if (const auto *TD = dyn_cast(ND)) { + InteropType = QualType(TD->getTypeForDecl(), 0); + } else { + HasError = true; + } + } else { + HasError = true; + } + + if (HasError) { + SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) + << "omp_interop_t"; + return false; + } + + QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); + if (!SemaRef.Context.hasSameType(InteropType, VarType)) { + SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); + return false; + } + + // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] + // The interop-var passed to init or destroy must be non-const. + if ((Kind == OMPC_init || Kind == OMPC_destroy) && + isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { + SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) + << /*non-const*/ 1; + return false; + } + return true; +} + +OMPClause * +Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef PrefExprs, + bool IsTarget, bool IsTargetSync, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation VarLoc, SourceLocation EndLoc) { + + if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) + return nullptr; + + // Check prefer_type values. These foreign-runtime-id values are either + // string literals or constant integral expressions. + for (const Expr *E : PrefExprs) { + if (E->isValueDependent() || E->isTypeDependent() || + E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) + continue; + if (E->isIntegerConstantExpr(Context)) + continue; + if (isa(E)) + continue; + Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); + return nullptr; + } + + return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget, + IsTargetSync, StartLoc, LParenLoc, VarLoc, + EndLoc); +} + +OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, + SourceLocation EndLoc) { + + if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) + return nullptr; + + return new (Context) + OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); +} + +OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, SourceLocation EndLoc) { - return new (Context) OMPDestroyClause(StartLoc, EndLoc); + if (InteropVar && + !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) + return nullptr; + + return new (Context) + OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); } OMPClause *Sema::ActOnOpenMPVarListClause( @@ -16381,8 +16631,7 @@ static bool actOnOMPReductionKindClause( } if (RHSVD->isInvalidDecl()) continue; - if (!RHSVD->hasInit() && - (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { + if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type << ReductionIdRange; bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index e25d69931538..ceba83bcd814 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3000,6 +3000,12 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) { // C99 6.8.6.2p1: A break shall appear only in or as a loop body. return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop)); } + if (S->getFlags() & Scope::ConditionVarScope) { + // We cannot 'continue;' from within a statement expression in the + // initializer of a condition variable because we would jump past the + // initialization of that variable. + return StmtError(Diag(ContinueLoc, diag::err_continue_from_cond_var_init)); + } CheckJumpOutOfSEHFinally(*this, ContinueLoc, *S); return new (Context) ContinueStmt(ContinueLoc); @@ -3086,24 +3092,30 @@ bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, if (VD->hasAttr()) return false; - // ...non-volatile... - if (VD->getType().isVolatileQualified()) - return false; - - // C++20 [class.copy.elision]p3: - // ...rvalue reference to a non-volatile... - if (VD->getType()->isRValueReferenceType() && - (!(CESK & CES_AllowRValueReferenceType) || - VD->getType().getNonReferenceType().isVolatileQualified())) + if (VDType->isObjectType()) { + // C++17 [class.copy.elision]p3: + // ...non-volatile automatic object... + if (VDType.isVolatileQualified()) + return false; + } else if (VDType->isRValueReferenceType()) { + // C++20 [class.copy.elision]p3: + // ...either a non-volatile object or an rvalue reference to a non-volatile object type... + if (!(CESK & CES_AllowRValueReferenceType)) + return false; + QualType VDReferencedType = VDType.getNonReferenceType(); + if (VDReferencedType.isVolatileQualified() || !VDReferencedType->isObjectType()) + return false; + } else { return false; + } if (CESK & CES_AllowDifferentTypes) return true; // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. - if (!VD->getType()->isDependentType() && VD->hasAttr() && - Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType())) + if (!VDType->isDependentType() && VD->hasAttr() && + Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VDType)) return false; return true; diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 86a09c42863f..cb90a03aa20e 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -26,14 +26,12 @@ using namespace sema; static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { FallThroughAttr Attr(S.Context, A); - if (!isa(St)) { + if (isa(St)) { S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_wrong_target) - << Attr.getSpelling() << St->getBeginLoc(); - if (isa(St)) { - SourceLocation L = S.getLocForEndOfToken(Range.getEnd()); - S.Diag(L, diag::note_fallthrough_insert_semi_fixit) - << FixItHint::CreateInsertion(L, ";"); - } + << A << St->getBeginLoc(); + SourceLocation L = S.getLocForEndOfToken(Range.getEnd()); + S.Diag(L, diag::note_fallthrough_insert_semi_fixit) + << FixItHint::CreateInsertion(L, ";"); return nullptr; } auto *FnScope = S.getCurFunction(); @@ -54,11 +52,6 @@ static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const ParsedAttr &A, static Attr *handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { - if (A.getNumArgs() < 1) { - S.Diag(A.getLoc(), diag::err_attribute_too_few_arguments) << A << 1; - return nullptr; - } - std::vector DiagnosticIdentifiers; for (unsigned I = 0, E = A.getNumArgs(); I != E; ++I) { StringRef RuleName; @@ -88,10 +81,10 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, PragmaNameLoc->Ident->getName()) .Default("clang loop"); - if (St->getStmtClass() != Stmt::DoStmtClass && - St->getStmtClass() != Stmt::ForStmtClass && - St->getStmtClass() != Stmt::CXXForRangeStmtClass && - St->getStmtClass() != Stmt::WhileStmtClass) { + // This could be handled automatically by adding a Subjects definition in + // Attr.td, but that would make the diagnostic behavior worse in this case + // because the user spells this attribute as a pragma. + if (!isa(St)) { std::string Pragma = "#pragma " + std::string(PragmaName); S.Diag(St->getBeginLoc(), diag::err_pragma_loop_precedes_nonloop) << Pragma; return nullptr; @@ -205,9 +198,6 @@ class CallExprFinder : public ConstEvaluatedExprVisitor { static Attr *handleNoMergeAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { NoMergeAttr NMA(S.Context, A); - if (S.CheckAttrNoArgs(A)) - return nullptr; - CallExprFinder CEF(S, St); if (!CEF.foundCallExpr()) { @@ -377,23 +367,8 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const ParsedAttr &A, // opencl_unroll_hint can have 0 arguments (compiler // determines unrolling factor) or 1 argument (the unroll factor provided // by the user). - - if (!isa(St)) { - S.Diag(A.getLoc(), diag::err_attribute_wrong_decl_type_str) - << A << "'for', 'while', and 'do' statements"; - return nullptr; - } - - unsigned NumArgs = A.getNumArgs(); - - if (NumArgs > 1) { - S.Diag(A.getLoc(), diag::err_attribute_too_many_arguments) << A << 1; - return nullptr; - } - unsigned UnrollFactor = 0; - - if (NumArgs == 1) { + if (A.getNumArgs() == 1) { Expr *E = A.getArgAsExpr(0); Optional ArgVal; @@ -404,28 +379,42 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const ParsedAttr &A, } int Val = ArgVal->getSExtValue(); - if (Val <= 0) { S.Diag(A.getRange().getBegin(), diag::err_attribute_requires_positive_integer) << A << /* positive */ 0; return nullptr; } - UnrollFactor = Val; + UnrollFactor = static_cast(Val); } - return OpenCLUnrollHintAttr::CreateImplicit(S.Context, UnrollFactor); + return ::new (S.Context) OpenCLUnrollHintAttr(S.Context, A, UnrollFactor); } static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { - switch (A.getKind()) { - case ParsedAttr::UnknownAttribute: + if (A.isInvalid() || A.getKind() == ParsedAttr::IgnoredAttribute) + return nullptr; + + // Unknown attributes are automatically warned on. Target-specific attributes + // which do not apply to the current target architecture are treated as + // though they were unknown attributes. + const TargetInfo *Aux = S.Context.getAuxTargetInfo(); + if (A.getKind() == ParsedAttr::UnknownAttribute || + !(A.existsInTarget(S.Context.getTargetInfo()) || + (S.Context.getLangOpts().SYCLIsDevice && Aux && + A.existsInTarget(*Aux)))) { S.Diag(A.getLoc(), A.isDeclspecAttribute() ? (unsigned)diag::warn_unhandled_ms_attribute_ignored : (unsigned)diag::warn_unknown_attribute_ignored) << A << A.getRange(); return nullptr; + } + + if (S.checkCommonAttributeFeatures(St, A)) + return nullptr; + + switch (A.getKind()) { case ParsedAttr::AT_FallThrough: return handleFallThroughAttr(S, St, A, Range); case ParsedAttr::AT_LoopHint: @@ -441,8 +430,9 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, case ParsedAttr::AT_Unlikely: return handleUnlikely(S, St, A, Range); default: - // if we're here, then we parsed a known attribute, but didn't recognize - // it as a statement attribute => it is declaration attribute + // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a + // declaration attribute is not written on a statement, but this code is + // needed for attributes in Attr.td that do not list any subjects. S.Diag(A.getRange().getBegin(), diag::err_decl_attribute_invalid_on_stmt) << A << St->getBeginLoc(); return nullptr; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 12880b95b9c6..7a65c2a6fe2c 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2494,6 +2494,12 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template, if (!CD || (!FTD && CD->isFunctionTemplateSpecialization())) continue; + // Cannot make a deduction guide when unparsed arguments are present. + if (std::any_of(CD->param_begin(), CD->param_end(), [](ParmVarDecl *P) { + return !P || P->hasUnparsedDefaultArg(); + })) + continue; + Transform.transformConstructor(FTD, CD); AddedAny = true; } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 6336f3b99452..ecf0c442ad46 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -455,11 +455,13 @@ static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument( const NonTypeTemplateParmDecl *NTTP, QualType NullPtrType, TemplateDeductionInfo &Info, SmallVectorImpl &Deduced) { - Expr *Value = - S.ImpCastExprToType(new (S.Context) CXXNullPtrLiteralExpr( - S.Context.NullPtrTy, NTTP->getLocation()), - NullPtrType, CK_NullToPointer) - .get(); + Expr *Value = S.ImpCastExprToType( + new (S.Context) CXXNullPtrLiteralExpr(S.Context.NullPtrTy, + NTTP->getLocation()), + NullPtrType, + NullPtrType->isMemberPointerType() ? CK_NullToMemberPointer + : CK_NullToPointer) + .get(); return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, DeducedTemplateArgument(Value), Value->getType(), Info, Deduced); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 8bd812b39de4..578a77aceeda 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3420,7 +3420,8 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, Instantiation->getTemplateInstantiationPattern(); DeclContext::lookup_result Lookup = ClassPattern->lookup(Field->getDeclName()); - FieldDecl *Pattern = cast(Lookup.front()); + FieldDecl *Pattern = Lookup.find_first(); + assert(Pattern); InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern, TemplateArgs); } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7badba198179..adfa4af91fcd 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1256,25 +1256,6 @@ getImageAccess(const ParsedAttributesView &Attrs) { return OpenCLAccessAttr::Keyword_read_only; } -static QualType ConvertConstrainedAutoDeclSpecToType(Sema &S, DeclSpec &DS, - AutoTypeKeyword AutoKW) { - assert(DS.isConstrainedAuto()); - TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); - TemplateArgumentListInfo TemplateArgsInfo; - TemplateArgsInfo.setLAngleLoc(TemplateId->LAngleLoc); - TemplateArgsInfo.setRAngleLoc(TemplateId->RAngleLoc); - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); - llvm::SmallVector TemplateArgs; - for (auto &ArgLoc : TemplateArgsInfo.arguments()) - TemplateArgs.push_back(ArgLoc.getArgument()); - return S.Context.getAutoType( - QualType(), AutoKW, false, /*IsPack=*/false, - cast(TemplateId->Template.get().getAsTemplateDecl()), - TemplateArgs); -} - /// Convert the specified declspec to the appropriate type /// object. /// \param state Specifies the declarator containing the declaration specifier @@ -1655,29 +1636,39 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { break; case DeclSpec::TST_auto: + case DeclSpec::TST_decltype_auto: { + auto AutoKW = DS.getTypeSpecType() == DeclSpec::TST_decltype_auto + ? AutoTypeKeyword::DecltypeAuto + : AutoTypeKeyword::Auto; + + ConceptDecl *TypeConstraintConcept = nullptr; + llvm::SmallVector TemplateArgs; if (DS.isConstrainedAuto()) { - Result = ConvertConstrainedAutoDeclSpecToType(S, DS, - AutoTypeKeyword::Auto); - break; + if (TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId()) { + TypeConstraintConcept = + cast(TemplateId->Template.get().getAsTemplateDecl()); + TemplateArgumentListInfo TemplateArgsInfo; + TemplateArgsInfo.setLAngleLoc(TemplateId->LAngleLoc); + TemplateArgsInfo.setRAngleLoc(TemplateId->RAngleLoc); + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), + TemplateId->NumArgs); + S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); + for (const auto &ArgLoc : TemplateArgsInfo.arguments()) + TemplateArgs.push_back(ArgLoc.getArgument()); + } else { + declarator.setInvalidType(true); + } } - Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false); + Result = S.Context.getAutoType(QualType(), AutoKW, + /*IsDependent*/ false, /*IsPack=*/false, + TypeConstraintConcept, TemplateArgs); break; + } case DeclSpec::TST_auto_type: Result = Context.getAutoType(QualType(), AutoTypeKeyword::GNUAutoType, false); break; - case DeclSpec::TST_decltype_auto: - if (DS.isConstrainedAuto()) { - Result = - ConvertConstrainedAutoDeclSpecToType(S, DS, - AutoTypeKeyword::DecltypeAuto); - break; - } - Result = Context.getAutoType(QualType(), AutoTypeKeyword::DecltypeAuto, - /*IsDependent*/ false); - break; - case DeclSpec::TST_unknown_anytype: Result = Context.UnknownAnyTy; break; @@ -2088,7 +2079,8 @@ QualType Sema::BuildPointerType(QualType T, } if (T->isFunctionType() && getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + getLangOpts())) { Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0; return QualType(); } @@ -2162,7 +2154,8 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue, return QualType(); if (T->isFunctionType() && getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + getLangOpts())) { Diag(Loc, diag::err_opencl_function_pointer) << /*reference*/ 1; return QualType(); } @@ -2897,7 +2890,8 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, } if (T->isFunctionType() && getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + getLangOpts())) { Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0; return QualType(); } @@ -5007,7 +5001,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // FIXME: This really should be in BuildFunctionType. if (T->isHalfType()) { if (S.getLangOpts().OpenCL) { - if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", + S.getLangOpts())) { S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return) << T << 0 /*pointer hint*/; D.setInvalidType(true); @@ -5032,7 +5027,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf. // We also allow here any toolchain reserved identifiers. if (FTI.isVariadic && - !S.getOpenCLOptions().isEnabled("__cl_clang_variadic_functions") && + !S.getOpenCLOptions().isAvailableOption( + "__cl_clang_variadic_functions", S.getLangOpts()) && !(D.getIdentifier() && ((D.getIdentifier()->getName() == "printf" && (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) || @@ -5227,7 +5223,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // Disallow half FP parameters. // FIXME: This really should be in BuildFunctionType. if (S.getLangOpts().OpenCL) { - if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", + S.getLangOpts())) { S.Diag(Param->getLocation(), diag::err_opencl_invalid_param) << ParamTy << 0; D.setInvalidType(); @@ -5959,6 +5956,8 @@ namespace { if (!DS.isConstrainedAuto()) return; TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); + if (!TemplateId) + return; if (DS.getTypeSpecScope().isNotEmpty()) TL.setNestedNameSpecifierLoc( DS.getTypeSpecScope().getWithLocInContext(Context)); @@ -7972,8 +7971,6 @@ static void HandleLifetimeBoundAttr(TypeProcessingState &State, CurType = State.getAttributedType( createSimpleAttr(State.getSema().Context, Attr), CurType, CurType); - } else { - Attr.diagnoseAppertainsTo(State.getSema(), nullptr); } } @@ -8836,6 +8833,29 @@ QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) { return Context.getTypeOfExprType(E); } +/// getDecltypeForParenthesizedExpr - Given an expr, will return the type for +/// that expression, as in [dcl.type.simple]p4 but without taking id-expressions +/// and class member access into account. +QualType Sema::getDecltypeForParenthesizedExpr(Expr *E) { + // C++11 [dcl.type.simple]p4: + // [...] + QualType T = E->getType(); + switch (E->getValueKind()) { + // - otherwise, if e is an xvalue, decltype(e) is T&&, where T is the + // type of e; + case VK_XValue: + return Context.getRValueReferenceType(T); + // - otherwise, if e is an lvalue, decltype(e) is T&, where T is the + // type of e; + case VK_LValue: + return Context.getLValueReferenceType(T); + // - otherwise, decltype(e) is the type of e. + case VK_RValue: + return T; + } + llvm_unreachable("Unknown value kind"); +} + /// getDecltypeForExpr - Given an expr, will return the decltype for /// that expression, according to the rules in C++11 /// [dcl.type.simple]p4 and C++11 [expr.lambda.prim]p18. @@ -8900,22 +8920,7 @@ static QualType getDecltypeForExpr(Sema &S, Expr *E) { } } - - // C++11 [dcl.type.simple]p4: - // [...] - QualType T = E->getType(); - switch (E->getValueKind()) { - // - otherwise, if e is an xvalue, decltype(e) is T&&, where T is the - // type of e; - case VK_XValue: T = S.Context.getRValueReferenceType(T); break; - // - otherwise, if e is an lvalue, decltype(e) is T&, where T is the - // type of e; - case VK_LValue: T = S.Context.getLValueReferenceType(T); break; - // - otherwise, decltype(e) is the type of e. - case VK_RValue: break; - } - - return T; + return S.getDecltypeForParenthesizedExpr(E); } QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index e9dfbe0abe2b..86a25149a23c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2170,6 +2170,44 @@ class TreeTransform { LParenLoc, EndLoc); } + /// Build a new OpenMP 'init' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPInitClause(Expr *InteropVar, ArrayRef PrefExprs, + bool IsTarget, bool IsTargetSync, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPInitClause(InteropVar, PrefExprs, IsTarget, + IsTargetSync, StartLoc, LParenLoc, + VarLoc, EndLoc); + } + + /// Build a new OpenMP 'use' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, SourceLocation EndLoc) { + return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc, + VarLoc, EndLoc); + } + + /// Build a new OpenMP 'destroy' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation VarLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPDestroyClause(InteropVar, StartLoc, LParenLoc, + VarLoc, EndLoc); + } + /// Rebuild the operand to an Objective-C \@synchronized statement. /// /// By default, performs semantic analysis to build the new statement. @@ -9020,6 +9058,27 @@ TreeTransform::TransformOMPTargetTeamsDistributeSimdDirective( return Res; } +template +StmtResult +TreeTransform::TransformOMPInteropDirective(OMPInteropDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_interop, DirName, nullptr, + D->getBeginLoc()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + +template +StmtResult +TreeTransform::TransformOMPDispatchDirective(OMPDispatchDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_dispatch, DirName, nullptr, + D->getBeginLoc()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} //===----------------------------------------------------------------------===// // OpenMP clause transformation @@ -9275,11 +9334,47 @@ TreeTransform::TransformOMPNogroupClause(OMPNogroupClause *C) { return C; } +template +OMPClause *TreeTransform::TransformOMPInitClause(OMPInitClause *C) { + ExprResult IVR = getDerived().TransformExpr(C->getInteropVar()); + if (IVR.isInvalid()) + return nullptr; + + llvm::SmallVector PrefExprs; + PrefExprs.reserve(C->varlist_size() - 1); + for (Expr *E : llvm::drop_begin(C->varlists())) { + ExprResult ER = getDerived().TransformExpr(cast(E)); + if (ER.isInvalid()) + return nullptr; + PrefExprs.push_back(ER.get()); + } + return getDerived().RebuildOMPInitClause( + IVR.get(), PrefExprs, C->getIsTarget(), C->getIsTargetSync(), + C->getBeginLoc(), C->getLParenLoc(), C->getVarLoc(), C->getEndLoc()); +} + +template +OMPClause *TreeTransform::TransformOMPUseClause(OMPUseClause *C) { + ExprResult ER = getDerived().TransformExpr(C->getInteropVar()); + if (ER.isInvalid()) + return nullptr; + return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(), + C->getLParenLoc(), C->getVarLoc(), + C->getEndLoc()); +} + template OMPClause * TreeTransform::TransformOMPDestroyClause(OMPDestroyClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; + ExprResult ER; + if (Expr *IV = C->getInteropVar()) { + ER = getDerived().TransformExpr(IV); + if (ER.isInvalid()) + return nullptr; + } + return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(), + C->getLParenLoc(), C->getVarLoc(), + C->getEndLoc()); } template @@ -13887,7 +13982,14 @@ TreeTransform::TransformBlockExpr(BlockExpr *E) { template ExprResult TreeTransform::TransformAsTypeExpr(AsTypeExpr *E) { - llvm_unreachable("Cannot transform asType expressions yet"); + ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr()); + if (SrcExpr.isInvalid()) + return ExprError(); + + QualType Type = getDerived().TransformType(E->getType()); + + return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(), + E->getRParenLoc()); } template diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index a4a0a5ced90b..a76bda15076b 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7649,9 +7649,10 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, // Load the list of declarations. SmallVector Decls; + llvm::SmallPtrSet Found; for (DeclID ID : It->second.Table.find(Name)) { NamedDecl *ND = cast(GetDecl(ID)); - if (ND->getDeclName() == Name) + if (ND->getDeclName() == Name && Found.insert(ND).second) Decls.push_back(ND); } @@ -11967,6 +11968,12 @@ OMPClause *OMPClauseReader::readClause() { case llvm::omp::OMPC_order: C = new (Context) OMPOrderClause(); break; + case llvm::omp::OMPC_init: + C = OMPInitClause::CreateEmpty(Context, Record.readInt()); + break; + case llvm::omp::OMPC_use: + C = new (Context) OMPUseClause(); + break; case llvm::omp::OMPC_destroy: C = new (Context) OMPDestroyClause(); break; @@ -12130,7 +12137,30 @@ void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {} void OMPClauseReader::VisitOMPNogroupClause(OMPNogroupClause *) {} -void OMPClauseReader::VisitOMPDestroyClause(OMPDestroyClause *) {} +void OMPClauseReader::VisitOMPInitClause(OMPInitClause *C) { + unsigned NumVars = C->varlist_size(); + SmallVector Vars; + Vars.reserve(NumVars); + for (unsigned I = 0; I != NumVars; ++I) + Vars.push_back(Record.readSubExpr()); + C->setVarRefs(Vars); + C->setIsTarget(Record.readBool()); + C->setIsTargetSync(Record.readBool()); + C->setLParenLoc(Record.readSourceLocation()); + C->setVarLoc(Record.readSourceLocation()); +} + +void OMPClauseReader::VisitOMPUseClause(OMPUseClause *C) { + C->setInteropVar(Record.readSubExpr()); + C->setLParenLoc(Record.readSourceLocation()); + C->setVarLoc(Record.readSourceLocation()); +} + +void OMPClauseReader::VisitOMPDestroyClause(OMPDestroyClause *C) { + C->setInteropVar(Record.readSubExpr()); + C->setLParenLoc(Record.readSourceLocation()); + C->setVarLoc(Record.readSourceLocation()); +} void OMPClauseReader::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {} diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 24513b70edd7..6e552e9a2441 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2588,6 +2588,17 @@ void ASTStmtReader::VisitOMPTargetTeamsDistributeSimdDirective( VisitOMPLoopDirective(D); } +void ASTStmtReader::VisitOMPInteropDirective(OMPInteropDirective *D) { + VisitStmt(D); + VisitOMPExecutableDirective(D); +} + +void ASTStmtReader::VisitOMPDispatchDirective(OMPDispatchDirective *D) { + VisitStmt(D); + VisitOMPExecutableDirective(D); + D->setTargetCallLoc(Record.readSourceLocation()); +} + //===----------------------------------------------------------------------===// // ASTReader Implementation //===----------------------------------------------------------------------===// @@ -3503,6 +3514,16 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } + case STMT_OMP_INTEROP_DIRECTIVE: + S = OMPInteropDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + + case STMT_OMP_DISPATCH_DIRECTIVE: + S = OMPDispatchDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + case EXPR_CXX_OPERATOR_CALL: S = CXXOperatorCallExpr::CreateEmpty( Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 68ea7955121d..18decd9e6bc1 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6215,7 +6215,27 @@ void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {} void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {} -void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *) {} +void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) { + Record.push_back(C->varlist_size()); + for (Expr *VE : C->varlists()) + Record.AddStmt(VE); + Record.writeBool(C->getIsTarget()); + Record.writeBool(C->getIsTargetSync()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getVarLoc()); +} + +void OMPClauseWriter::VisitOMPUseClause(OMPUseClause *C) { + Record.AddStmt(C->getInteropVar()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getVarLoc()); +} + +void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *C) { + Record.AddStmt(C->getInteropVar()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getVarLoc()); +} void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { Record.push_back(C->varlist_size()); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 2cb44bf9038b..2b8278090b05 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -13,7 +13,6 @@ #include "ASTCommon.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/Expr.h" diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 58fb11e70d14..97ecd5a773ea 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2541,6 +2541,19 @@ void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective( Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE; } +void ASTStmtWriter::VisitOMPInteropDirective(OMPInteropDirective *D) { + VisitStmt(D); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_INTEROP_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPDispatchDirective(OMPDispatchDirective *D) { + VisitStmt(D); + VisitOMPExecutableDirective(D); + Record.AddSourceLocation(D->getTargetCallLoc()); + Code = serialization::STMT_OMP_DISPATCH_DIRECTIVE; +} + //===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp index 6bc186aa2755..8c86e83608b1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -260,8 +260,8 @@ class DeadStoreObs : public LiveVariables::Observer { break; } - BR.EmitBasicReport(AC->getDecl(), Checker, BugType, "Dead store", os.str(), - L, R, Fixits); + BR.EmitBasicReport(AC->getDecl(), Checker, BugType, categories::UnusedCode, + os.str(), L, R, Fixits); } void CheckVarDecl(const VarDecl *VD, const Expr *Ex, const Expr *Val, diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp index dd014648eb6f..a47484497771 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp @@ -228,7 +228,7 @@ void IteratorRangeChecker::verifyRandomIncrOrDecr(CheckerContext &C, Value = State->getRawSVal(*ValAsLoc); } - if (Value.isUnknown()) + if (Value.isUnknownOrUndef()) return; // Incremention or decremention by 0 is never a bug. diff --git a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp index 80b705fb7392..c5437b16c688 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp @@ -89,7 +89,7 @@ void NonnullGlobalConstantsChecker::checkLocation(SVal location, bool isLoad, } /// \param V loaded lvalue. -/// \return whether {@code val} is a string-like const global. +/// \return whether @c val is a string-like const global. bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V) const { Optional RegionVal = V.getAs(); if (!RegionVal) @@ -127,7 +127,7 @@ bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V) const { return false; } -/// \return whether {@code type} is extremely unlikely to be null +/// \return whether @c type is extremely unlikely to be null bool NonnullGlobalConstantsChecker::isNonnullType(QualType Ty) const { if (Ty->isPointerType() && Ty->getPointeeType()->isCharType()) diff --git a/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp b/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp index 270b66dab020..0a8379d9ab99 100644 --- a/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp @@ -32,7 +32,21 @@ class OSObjectCStyleCastChecker : public Checker { void checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const; }; +} // namespace + +namespace clang { +namespace ast_matchers { +AST_MATCHER_P(StringLiteral, mentionsBoundType, std::string, BindingID) { + return Builder->removeBindings([this, &Node](const BoundNodesMap &Nodes) { + const auto &BN = Nodes.getNode(this->BindingID); + if (const auto *ND = BN.get()) { + return ND->getName() != Node.getString(); + } + return true; + }); } +} // end namespace ast_matchers +} // end namespace clang static void emitDiagnostics(const BoundNodes &Nodes, BugReporter &BR, @@ -63,22 +77,41 @@ static decltype(auto) hasTypePointingTo(DeclarationMatcher DeclM) { return hasType(pointerType(pointee(hasDeclaration(DeclM)))); } -void OSObjectCStyleCastChecker::checkASTCodeBody(const Decl *D, AnalysisManager &AM, +void OSObjectCStyleCastChecker::checkASTCodeBody(const Decl *D, + AnalysisManager &AM, BugReporter &BR) const { AnalysisDeclContext *ADC = AM.getAnalysisDeclContext(D); auto DynamicCastM = callExpr(callee(functionDecl(hasName("safeMetaCast")))); - - auto OSObjTypeM = hasTypePointingTo(cxxRecordDecl(isDerivedFrom("OSMetaClassBase"))); + // 'allocClassWithName' allocates an object with the given type. + // The type is actually provided as a string argument (type's name). + // This makes the following pattern possible: + // + // Foo *object = (Foo *)allocClassWithName("Foo"); + // + // While OSRequiredCast can be used here, it is still not a useful warning. + auto AllocClassWithNameM = callExpr( + callee(functionDecl(hasName("allocClassWithName"))), + // Here we want to make sure that the string argument matches the + // type in the cast expression. + hasArgument(0, stringLiteral(mentionsBoundType(WarnRecordDecl)))); + + auto OSObjTypeM = + hasTypePointingTo(cxxRecordDecl(isDerivedFrom("OSMetaClassBase"))); auto OSObjSubclassM = hasTypePointingTo( - cxxRecordDecl(isDerivedFrom("OSObject")).bind(WarnRecordDecl)); - - auto CastM = cStyleCastExpr( - allOf(hasSourceExpression(allOf(OSObjTypeM, unless(DynamicCastM))), - OSObjSubclassM)).bind(WarnAtNode); - - auto Matches = match(stmt(forEachDescendant(CastM)), *D->getBody(), AM.getASTContext()); + cxxRecordDecl(isDerivedFrom("OSObject")).bind(WarnRecordDecl)); + + auto CastM = + cStyleCastExpr( + allOf(OSObjSubclassM, + hasSourceExpression( + allOf(OSObjTypeM, + unless(anyOf(DynamicCastM, AllocClassWithNameM)))))) + .bind(WarnAtNode); + + auto Matches = + match(stmt(forEachDescendant(CastM)), *D->getBody(), AM.getASTContext()); for (BoundNodes Match : Matches) emitDiagnostics(Match, BR, ADC, this); } diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp index 7fd6e2abef4c..c8eab3288094 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp @@ -8,7 +8,7 @@ // // This file defines ObjCAutoreleaseWriteChecker which warns against writes // into autoreleased out parameters which cause crashes. -// An example of a problematic write is a write to {@code error} in the example +// An example of a problematic write is a write to @c error in the example // below: // // - (BOOL) mymethod:(NSError *__autoreleasing *)error list:(NSArray*) list { diff --git a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp index 88e80c481a5a..eb10a42b7d3d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -339,7 +339,16 @@ void PthreadLockChecker::printState(raw_ostream &Out, ProgramStateRef State, } } - // TODO: Dump destroyed mutex symbols? + DestroyRetValTy DRV = State->get(); + if (!DRV.isEmpty()) { + Out << Sep << "Mutexes in unresolved possibly destroyed state:" << NL; + for (auto I : DRV) { + I.first->dumpToStream(Out); + Out << ": "; + I.second->dumpToStream(Out); + Out << NL; + } + } } void PthreadLockChecker::AcquirePthreadLock(const CallEvent &Call, diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp index 1d903530201f..1fc3ee03d2e1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -89,7 +89,7 @@ static std::string getPrettyTypeName(QualType QT) { return QT.getAsString(); } -/// Write information about the type state change to {@code os}, +/// Write information about the type state change to @c os, /// return whether the note should be generated. static bool shouldGenerateNote(llvm::raw_string_ostream &os, const RefVal *PrevT, @@ -164,8 +164,8 @@ static bool shouldGenerateNote(llvm::raw_string_ostream &os, return true; } -/// Finds argument index of the out paramter in the call {@code S} -/// corresponding to the symbol {@code Sym}. +/// Finds argument index of the out paramter in the call @c S +/// corresponding to the symbol @c Sym. /// If none found, returns None. static Optional findArgIdxOfSymbol(ProgramStateRef CurrSt, const LocationContext *LCtx, diff --git a/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp index d9dc72ddaa21..2cf6c6ff47f1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp @@ -57,8 +57,8 @@ class RunLoopAutoreleaseLeakChecker : public Checker { } // end anonymous namespace -/// \return Whether {@code A} occurs before {@code B} in traversal of -/// {@code Parent}. +/// \return Whether @c A occurs before @c B in traversal of +/// @c Parent. /// Conceptually a very incomplete/unsound approximation of happens-before /// relationship (A is likely to be evaluated before B), /// but useful enough in this case. diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index d1c366a94fac..c8b2e3d91520 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -508,6 +508,7 @@ class StdLibraryFunctionsChecker mutable FunctionSummaryMapType FunctionSummaryMap; mutable std::unique_ptr BT_InvalidArg; + mutable bool SummariesInitialized = false; static SVal getArgSVal(const CallEvent &Call, ArgNo ArgN) { return ArgN == Ret ? Call.getReturnValue() : Call.getArgSVal(ArgN); @@ -823,7 +824,7 @@ StdLibraryFunctionsChecker::findFunctionSummary(const CallEvent &Call, void StdLibraryFunctionsChecker::initFunctionSummaries( CheckerContext &C) const { - if (!FunctionSummaryMap.empty()) + if (SummariesInitialized) return; SValBuilder &SVB = C.getSValBuilder(); @@ -841,7 +842,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( llvm::Optional operator()(StringRef Name) { IdentifierInfo &II = ACtx.Idents.get(Name); auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II); - if (LookupRes.size() == 0) + if (LookupRes.empty()) return None; // Prioritze typedef declarations. @@ -993,7 +994,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( return false; IdentifierInfo &II = ACtx.Idents.get(Name); auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II); - if (LookupRes.size() == 0) + if (LookupRes.empty()) return false; for (Decl *D : LookupRes) { if (auto *FD = dyn_cast(D)) { @@ -2485,6 +2486,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( Signature(ArgTypes{VoidPtrRestrictTy}, RetType{VoidTy}), Summary(EvalCallAsPure)); } + + SummariesInitialized = true; } void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp index 74eec81ffb3e..d231be64c2e1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp @@ -169,7 +169,7 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, if (SM.isInSystemHeader(SL) || SM.isInExternCSystemHeader(SL)) continue; - B.EmitBasicReport(D, this, "Unreachable code", "Dead code", + B.EmitBasicReport(D, this, "Unreachable code", categories::UnusedCode, "This statement is never executed", DL, SR); } } diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index bf38891b370a..b64c0798d7e2 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2738,8 +2738,8 @@ static void CompactMacroExpandedPieces(PathPieces &path, } /// Generate notes from all visitors. -/// Notes associated with {@code ErrorNode} are generated using -/// {@code getEndPath}, and the rest are generated with {@code VisitNode}. +/// Notes associated with @c ErrorNode are generated using +/// @c getEndPath, and the rest are generated with @c VisitNode. static std::unique_ptr generateVisitorsDiagnostics(PathSensitiveBugReport *R, const ExplodedNode *ErrorNode, @@ -2749,7 +2749,7 @@ generateVisitorsDiagnostics(PathSensitiveBugReport *R, PathSensitiveBugReport::VisitorList visitors; // Run visitors on all nodes starting from the node *before* the last one. - // The last node is reserved for notes generated with {@code getEndPath}. + // The last node is reserved for notes generated with @c getEndPath. const ExplodedNode *NextNode = ErrorNode->getFirstPred(); while (NextNode) { diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index bc72f4f8c1e3..fd334b0bc9c3 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1846,7 +1846,7 @@ static const MemRegion *getLocationRegionIfReference(const Expr *E, return nullptr; } -/// \return A subexpression of {@code Ex} which represents the +/// \return A subexpression of @c Ex which represents the /// expression-of-interest. static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N) { @@ -1924,6 +1924,44 @@ static const ExplodedNode* findNodeForExpression(const ExplodedNode *N, return N; } +/// Attempts to add visitors to track an RValue expression back to its point of +/// origin. Works similarly to trackExpressionValue, but accepts only RValues. +static void trackRValueExpression(const ExplodedNode *InputNode, const Expr *E, + PathSensitiveBugReport &report, + bugreporter::TrackingKind TKind, + bool EnableNullFPSuppression) { + assert(E->isRValue() && "The expression is not an rvalue!"); + const ExplodedNode *RVNode = findNodeForExpression(InputNode, E); + if (!RVNode) + return; + ProgramStateRef RVState = RVNode->getState(); + SVal V = RVState->getSValAsScalarOrLoc(E, RVNode->getLocationContext()); + const auto *BO = dyn_cast(E); + if (!BO) + return; + if (!V.isZeroConstant()) + return; + if (!BO->isMultiplicativeOp()) + return; + + SVal RHSV = RVState->getSVal(BO->getRHS(), RVNode->getLocationContext()); + SVal LHSV = RVState->getSVal(BO->getLHS(), RVNode->getLocationContext()); + + // Track both LHS and RHS of a multiplication. + if (BO->getOpcode() == BO_Mul) { + if (LHSV.isZeroConstant()) + trackExpressionValue(InputNode, BO->getLHS(), report, TKind, + EnableNullFPSuppression); + if (RHSV.isZeroConstant()) + trackExpressionValue(InputNode, BO->getRHS(), report, TKind, + EnableNullFPSuppression); + } else { // Track only the LHS of a division or a modulo. + if (LHSV.isZeroConstant()) + trackExpressionValue(InputNode, BO->getLHS(), report, TKind, + EnableNullFPSuppression); + } +} + bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode, const Expr *E, PathSensitiveBugReport &report, @@ -1942,7 +1980,7 @@ bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode, const StackFrameContext *SFC = LVNode->getStackFrame(); // We only track expressions if we believe that they are important. Chances - // are good that control dependencies to the tracking point are also improtant + // are good that control dependencies to the tracking point are also important // because of this, let's explain why we believe control reached this point. // TODO: Shouldn't we track control dependencies of every bug location, rather // than only tracked expressions? @@ -2069,6 +2107,11 @@ bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode, loc::MemRegionVal(RegionRVal), /*assumption=*/false)); } } + + if (Inner->isRValue()) + trackRValueExpression(LVNode, Inner, report, TKind, + EnableNullFPSuppression); + return true; } diff --git a/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp b/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp index b61e3075f3ba..d12c35ef156a 100644 --- a/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp +++ b/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp @@ -22,6 +22,7 @@ const char *const UnixAPI = "Unix API"; const char *const CXXObjectLifecycle = "C++ object lifecycle"; const char *const CXXMoveSemantics = "C++ move semantics"; const char *const SecurityError = "Security error"; +const char *const UnusedCode = "Unused code"; } // namespace categories } // namespace ento } // namespace clang diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index a388fc9e6e26..1498efd135d2 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1294,6 +1294,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: case Stmt::OMPTileDirectiveClass: + case Stmt::OMPInteropDirectiveClass: + case Stmt::OMPDispatchDirectiveClass: case Stmt::CapturedStmtClass: { const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); Engine.addAbortedBlock(node, currBldrCtx->getBlock()); @@ -3139,8 +3141,8 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { /// \p PreCallback: callback before break. /// \p PostCallback: callback after break. - /// \p Stop: stop iteration if returns {@code true} - /// \return Whether {@code Stop} ever returned {@code true}. + /// \p Stop: stop iteration if returns @c true + /// \return Whether @c Stop ever returned @c true. static bool traverseHiddenNodes( const ExplodedNode *N, llvm::function_ref PreCallback, diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index fe530bce4a3e..64fc32ea7554 100644 --- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -275,11 +275,11 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, << "' absolute: " << EC.message() << '\n'; return; } - if (std::error_code EC = - llvm::sys::fs::createUniqueFile(Model, FD, ResultPath)) { - llvm::errs() << "warning: could not create file in '" << Directory - << "': " << EC.message() << '\n'; - return; + if (std::error_code EC = llvm::sys::fs::createUniqueFile( + Model, FD, ResultPath, llvm::sys::fs::OF_Text)) { + llvm::errs() << "warning: could not create file in '" << Directory + << "': " << EC.message() << '\n'; + return; } } else { int i = 1; diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index 9842f3ace484..7e7fe75082bb 100644 --- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -157,8 +157,8 @@ class PlistPrinter { } // end of anonymous namespace -/// Print coverage information to output stream {@code o}. -/// May modify the used list of files {@code Fids} by inserting new ones. +/// Print coverage information to output stream @c o. +/// May modify the used list of files @c Fids by inserting new ones. static void printCoverage(const PathDiagnostic *D, unsigned InputIndentLevel, SmallVectorImpl &Fids, @@ -484,8 +484,8 @@ void PlistPrinter::ReportPopUp(raw_ostream &o, // Static function definitions. //===----------------------------------------------------------------------===// -/// Print coverage information to output stream {@code o}. -/// May modify the used list of files {@code Fids} by inserting new ones. +/// Print coverage information to output stream @c o. +/// May modify the used list of files @c Fids by inserting new ones. static void printCoverage(const PathDiagnostic *D, unsigned InputIndentLevel, SmallVectorImpl &Fids, diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp index a481bde1651b..974535952d0f 100644 --- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -19,7 +19,11 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableSet.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" +#include +#include using namespace clang; using namespace ento; @@ -97,47 +101,63 @@ class OperatorRelationsTable { return CmpOpTable[getIndexFromOp(CurrentOP)][CmpOpCount]; } }; + //===----------------------------------------------------------------------===// // RangeSet implementation //===----------------------------------------------------------------------===// -void RangeSet::IntersectInRange(BasicValueFactory &BV, Factory &F, - const llvm::APSInt &Lower, - const llvm::APSInt &Upper, - PrimRangeSet &newRanges, - PrimRangeSet::iterator &i, - PrimRangeSet::iterator &e) const { - // There are six cases for each range R in the set: - // 1. R is entirely before the intersection range. - // 2. R is entirely after the intersection range. - // 3. R contains the entire intersection range. - // 4. R starts before the intersection range and ends in the middle. - // 5. R starts in the middle of the intersection range and ends after it. - // 6. R is entirely contained in the intersection range. - // These correspond to each of the conditions below. - for (/* i = begin(), e = end() */; i != e; ++i) { - if (i->To() < Lower) { - continue; - } - if (i->From() > Upper) { - break; - } +RangeSet::ContainerType RangeSet::Factory::EmptySet{}; - if (i->Includes(Lower)) { - if (i->Includes(Upper)) { - newRanges = - F.add(newRanges, Range(BV.getValue(Lower), BV.getValue(Upper))); - break; - } else - newRanges = F.add(newRanges, Range(BV.getValue(Lower), i->To())); - } else { - if (i->Includes(Upper)) { - newRanges = F.add(newRanges, Range(i->From(), BV.getValue(Upper))); - break; - } else - newRanges = F.add(newRanges, *i); - } +RangeSet RangeSet::Factory::add(RangeSet Original, Range Element) { + ContainerType Result; + Result.reserve(Original.size() + 1); + + const_iterator Lower = llvm::lower_bound(Original, Element); + Result.insert(Result.end(), Original.begin(), Lower); + Result.push_back(Element); + Result.insert(Result.end(), Lower, Original.end()); + + return makePersistent(std::move(Result)); +} + +RangeSet RangeSet::Factory::add(RangeSet Original, const llvm::APSInt &Point) { + return add(Original, Range(Point)); +} + +RangeSet RangeSet::Factory::getRangeSet(Range From) { + ContainerType Result; + Result.push_back(From); + return makePersistent(std::move(Result)); +} + +RangeSet RangeSet::Factory::makePersistent(ContainerType &&From) { + llvm::FoldingSetNodeID ID; + void *InsertPos; + + From.Profile(ID); + ContainerType *Result = Cache.FindNodeOrInsertPos(ID, InsertPos); + + if (!Result) { + // It is cheaper to fully construct the resulting range on stack + // and move it to the freshly allocated buffer if we don't have + // a set like this already. + Result = construct(std::move(From)); + Cache.InsertNode(Result, InsertPos); } + + return Result; +} + +RangeSet::ContainerType *RangeSet::Factory::construct(ContainerType &&From) { + void *Buffer = Arena.Allocate(); + return new (Buffer) ContainerType(std::move(From)); +} + +RangeSet RangeSet::Factory::add(RangeSet LHS, RangeSet RHS) { + ContainerType Result; + std::merge(LHS.begin(), LHS.end(), RHS.begin(), RHS.end(), + std::back_inserter(Result)); + return makePersistent(std::move(Result)); } const llvm::APSInt &RangeSet::getMinValue() const { @@ -147,22 +167,31 @@ const llvm::APSInt &RangeSet::getMinValue() const { const llvm::APSInt &RangeSet::getMaxValue() const { assert(!isEmpty()); - // NOTE: It's a shame that we can't implement 'getMaxValue' without scanning - // the whole tree to get to the last element. - // llvm::ImmutableSet should support decrement for 'end' iterators - // or reverse order iteration. - auto It = begin(); - for (auto End = end(); std::next(It) != End; ++It) { - } - return It->To(); + return std::prev(end())->To(); } -bool RangeSet::pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const { - if (isEmpty()) { - // This range is already infeasible. +bool RangeSet::containsImpl(llvm::APSInt &Point) const { + if (isEmpty() || !pin(Point)) return false; - } + Range Dummy(Point); + const_iterator It = llvm::upper_bound(*this, Dummy); + if (It == begin()) + return false; + + return std::prev(It)->Includes(Point); +} + +bool RangeSet::pin(llvm::APSInt &Point) const { + APSIntType Type(getMinValue()); + if (Type.testInRange(Point, true) != APSIntType::RTR_Within) + return false; + + Type.apply(Point); + return true; +} + +bool RangeSet::pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const { // This function has nine cases, the cartesian product of range-testing // both the upper and lower bounds against the symbol's type. // Each case requires a different pinning operation. @@ -243,129 +272,216 @@ bool RangeSet::pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const { return true; } -// Returns a set containing the values in the receiving set, intersected with -// the closed range [Lower, Upper]. Unlike the Range type, this range uses -// modular arithmetic, corresponding to the common treatment of C integer -// overflow. Thus, if the Lower bound is greater than the Upper bound, the -// range is taken to wrap around. This is equivalent to taking the -// intersection with the two ranges [Min, Upper] and [Lower, Max], -// or, alternatively, /removing/ all integers between Upper and Lower. -RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F, - llvm::APSInt Lower, llvm::APSInt Upper) const { - PrimRangeSet newRanges = F.getEmptySet(); - - if (isEmpty() || !pin(Lower, Upper)) - return newRanges; - - PrimRangeSet::iterator i = begin(), e = end(); - if (Lower <= Upper) - IntersectInRange(BV, F, Lower, Upper, newRanges, i, e); - else { - // The order of the next two statements is important! - // IntersectInRange() does not reset the iteration state for i and e. - // Therefore, the lower range most be handled first. - IntersectInRange(BV, F, BV.getMinValue(Upper), Upper, newRanges, i, e); - IntersectInRange(BV, F, Lower, BV.getMaxValue(Lower), newRanges, i, e); - } - - return newRanges; -} - -// Returns a set containing the values in the receiving set, intersected with -// the range set passed as parameter. -RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F, - const RangeSet &Other) const { - PrimRangeSet newRanges = F.getEmptySet(); - - for (iterator i = Other.begin(), e = Other.end(); i != e; ++i) { - RangeSet newPiece = Intersect(BV, F, i->From(), i->To()); - for (iterator j = newPiece.begin(), ee = newPiece.end(); j != ee; ++j) { - newRanges = F.add(newRanges, *j); - } +RangeSet RangeSet::Factory::intersect(RangeSet What, llvm::APSInt Lower, + llvm::APSInt Upper) { + if (What.isEmpty() || !What.pin(Lower, Upper)) + return getEmptySet(); + + ContainerType DummyContainer; + + if (Lower <= Upper) { + // [Lower, Upper] is a regular range. + // + // Shortcut: check that there is even a possibility of the intersection + // by checking the two following situations: + // + // <---[ What ]---[------]------> + // Lower Upper + // -or- + // <----[------]----[ What ]----> + // Lower Upper + if (What.getMaxValue() < Lower || Upper < What.getMinValue()) + return getEmptySet(); + + DummyContainer.push_back( + Range(ValueFactory.getValue(Lower), ValueFactory.getValue(Upper))); + } else { + // [Lower, Upper] is an inverted range, i.e. [MIN, Upper] U [Lower, MAX] + // + // Shortcut: check that there is even a possibility of the intersection + // by checking the following situation: + // + // <------]---[ What ]---[------> + // Upper Lower + if (What.getMaxValue() < Lower && Upper < What.getMinValue()) + return getEmptySet(); + + DummyContainer.push_back( + Range(ValueFactory.getMinValue(Upper), ValueFactory.getValue(Upper))); + DummyContainer.push_back( + Range(ValueFactory.getValue(Lower), ValueFactory.getMaxValue(Lower))); } - return newRanges; + return intersect(*What.Impl, DummyContainer); } -// Turn all [A, B] ranges to [-B, -A], when "-" is a C-like unary minus -// operation under the values of the type. -// -// We also handle MIN because applying unary minus to MIN does not change it. -// Example 1: -// char x = -128; // -128 is a MIN value in a range of 'char' -// char y = -x; // y: -128 -// Example 2: -// unsigned char x = 0; // 0 is a MIN value in a range of 'unsigned char' -// unsigned char y = -x; // y: 0 -// -// And it makes us to separate the range -// like [MIN, N] to [MIN, MIN] U [-N,MAX]. -// For instance, whole range is {-128..127} and subrange is [-128,-126], -// thus [-128,-127,-126,.....] negates to [-128,.....,126,127]. -// -// Negate restores disrupted ranges on bounds, -// e.g. [MIN, B] => [MIN, MIN] U [-B, MAX] => [MIN, B]. -RangeSet RangeSet::Negate(BasicValueFactory &BV, Factory &F) const { - PrimRangeSet newRanges = F.getEmptySet(); +RangeSet RangeSet::Factory::intersect(const RangeSet::ContainerType &LHS, + const RangeSet::ContainerType &RHS) { + ContainerType Result; + Result.reserve(std::max(LHS.size(), RHS.size())); + + const_iterator First = LHS.begin(), Second = RHS.begin(), + FirstEnd = LHS.end(), SecondEnd = RHS.end(); + + const auto SwapIterators = [&First, &FirstEnd, &Second, &SecondEnd]() { + std::swap(First, Second); + std::swap(FirstEnd, SecondEnd); + }; - if (isEmpty()) - return newRanges; + // If we ran out of ranges in one set, but not in the other, + // it means that those elements are definitely not in the + // intersection. + while (First != FirstEnd && Second != SecondEnd) { + // We want to keep the following invariant at all times: + // + // ----[ First ----------------------> + // --------[ Second -----------------> + if (Second->From() < First->From()) + SwapIterators(); + + // Loop where the invariant holds: + do { + // Check for the following situation: + // + // ----[ First ]---------------------> + // ---------------[ Second ]---------> + // + // which means that... + if (Second->From() > First->To()) { + // ...First is not in the intersection. + // + // We should move on to the next range after First and break out of the + // loop because the invariant might not be true. + ++First; + break; + } - const llvm::APSInt sampleValue = getMinValue(); - const llvm::APSInt &MIN = BV.getMinValue(sampleValue); - const llvm::APSInt &MAX = BV.getMaxValue(sampleValue); + // We have a guaranteed intersection at this point! + // And this is the current situation: + // + // ----[ First ]-----------------> + // -------[ Second ------------------> + // + // Additionally, it definitely starts with Second->From(). + const llvm::APSInt &IntersectionStart = Second->From(); + + // It is important to know which of the two ranges' ends + // is greater. That "longer" range might have some other + // intersections, while the "shorter" range might not. + if (Second->To() > First->To()) { + // Here we make a decision to keep First as the "longer" + // range. + SwapIterators(); + } + + // At this point, we have the following situation: + // + // ---- First ]--------------------> + // ---- Second ]--[ Second+1 ----------> + // + // We don't know the relationship between First->From and + // Second->From and we don't know whether Second+1 intersects + // with First. + // + // However, we know that [IntersectionStart, Second->To] is + // a part of the intersection... + Result.push_back(Range(IntersectionStart, Second->To())); + ++Second; + // ...and that the invariant will hold for a valid Second+1 + // because First->From <= Second->To < (Second+1)->From. + } while (Second != SecondEnd); + } + + if (Result.empty()) + return getEmptySet(); + + return makePersistent(std::move(Result)); +} + +RangeSet RangeSet::Factory::intersect(RangeSet LHS, RangeSet RHS) { + // Shortcut: let's see if the intersection is even possible. + if (LHS.isEmpty() || RHS.isEmpty() || LHS.getMaxValue() < RHS.getMinValue() || + RHS.getMaxValue() < LHS.getMinValue()) + return getEmptySet(); + + return intersect(*LHS.Impl, *RHS.Impl); +} + +RangeSet RangeSet::Factory::intersect(RangeSet LHS, llvm::APSInt Point) { + if (LHS.containsImpl(Point)) + return getRangeSet(ValueFactory.getValue(Point)); + + return getEmptySet(); +} + +RangeSet RangeSet::Factory::negate(RangeSet What) { + if (What.isEmpty()) + return getEmptySet(); + + const llvm::APSInt SampleValue = What.getMinValue(); + const llvm::APSInt &MIN = ValueFactory.getMinValue(SampleValue); + const llvm::APSInt &MAX = ValueFactory.getMaxValue(SampleValue); + + ContainerType Result; + Result.reserve(What.size() + (SampleValue == MIN)); // Handle a special case for MIN value. - iterator i = begin(); - const llvm::APSInt &from = i->From(); - const llvm::APSInt &to = i->To(); - if (from == MIN) { - // If [from, to] are [MIN, MAX], then just return the same [MIN, MAX]. - if (to == MAX) { - newRanges = ranges; + const_iterator It = What.begin(); + const_iterator End = What.end(); + + const llvm::APSInt &From = It->From(); + const llvm::APSInt &To = It->To(); + + if (From == MIN) { + // If the range [From, To] is [MIN, MAX], then result is also [MIN, MAX]. + if (To == MAX) { + return What; + } + + const_iterator Last = std::prev(End); + + // Try to find and unite the following ranges: + // [MIN, MIN] & [MIN + 1, N] => [MIN, N]. + if (Last->To() == MAX) { + // It means that in the original range we have ranges + // [MIN, A], ... , [B, MAX] + // And the result should be [MIN, -B], ..., [-A, MAX] + Result.emplace_back(MIN, ValueFactory.getValue(-Last->From())); + // We already negated Last, so we can skip it. + End = Last; } else { - // Add separate range for the lowest value. - newRanges = F.add(newRanges, Range(MIN, MIN)); - // Skip adding the second range in case when [from, to] are [MIN, MIN]. - if (to != MIN) { - newRanges = F.add(newRanges, Range(BV.getValue(-to), MAX)); - } + // Add a separate range for the lowest value. + Result.emplace_back(MIN, MIN); } + + // Skip adding the second range in case when [From, To] are [MIN, MIN]. + if (To != MIN) { + Result.emplace_back(ValueFactory.getValue(-To), MAX); + } + // Skip the first range in the loop. - ++i; + ++It; } // Negate all other ranges. - for (iterator e = end(); i != e; ++i) { + for (; It != End; ++It) { // Negate int values. - const llvm::APSInt &newFrom = BV.getValue(-i->To()); - const llvm::APSInt &newTo = BV.getValue(-i->From()); - // Add a negated range. - newRanges = F.add(newRanges, Range(newFrom, newTo)); - } - - if (newRanges.isSingleton()) - return newRanges; - - // Try to find and unite next ranges: - // [MIN, MIN] & [MIN + 1, N] => [MIN, N]. - iterator iter1 = newRanges.begin(); - iterator iter2 = std::next(iter1); + const llvm::APSInt &NewFrom = ValueFactory.getValue(-It->To()); + const llvm::APSInt &NewTo = ValueFactory.getValue(-It->From()); - if (iter1->To() == MIN && (iter2->From() - 1) == MIN) { - const llvm::APSInt &to = iter2->To(); - // remove adjacent ranges - newRanges = F.remove(newRanges, *iter1); - newRanges = F.remove(newRanges, *newRanges.begin()); - // add united range - newRanges = F.add(newRanges, Range(MIN, to)); + // Add a negated range. + Result.emplace_back(NewFrom, NewTo); } - return newRanges; + llvm::sort(Result); + return makePersistent(std::move(Result)); } -RangeSet RangeSet::Delete(BasicValueFactory &BV, Factory &F, - const llvm::APSInt &Point) const { +RangeSet RangeSet::Factory::deletePoint(RangeSet From, + const llvm::APSInt &Point) { + if (!From.contains(Point)) + return From; + llvm::APSInt Upper = Point; llvm::APSInt Lower = Point; @@ -373,22 +489,17 @@ RangeSet RangeSet::Delete(BasicValueFactory &BV, Factory &F, --Lower; // Notice that the lower bound is greater than the upper bound. - return Intersect(BV, F, Upper, Lower); + return intersect(From, Upper, Lower); } -void RangeSet::print(raw_ostream &os) const { - bool isFirst = true; - os << "{ "; - for (iterator i = begin(), e = end(); i != e; ++i) { - if (isFirst) - isFirst = false; - else - os << ", "; +void Range::dump(raw_ostream &OS) const { + OS << '[' << From().toString(10) << ", " << To().toString(10) << ']'; +} - os << '[' << i->From().toString(10) << ", " << i->To().toString(10) - << ']'; - } - os << " }"; +void RangeSet::dump(raw_ostream &OS) const { + OS << "{ "; + llvm::interleaveComma(*this, OS, [&OS](const Range &R) { R.dump(OS); }); + OS << " }"; } REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(SymbolSet, SymbolRef) @@ -446,12 +557,12 @@ class EquivalenceClass : public llvm::FoldingSetNode { EquivalenceClass Other); /// Return a set of class members for the given state. - LLVM_NODISCARD inline SymbolSet getClassMembers(ProgramStateRef State); + LLVM_NODISCARD inline SymbolSet getClassMembers(ProgramStateRef State) const; /// Return true if the current class is trivial in the given state. - LLVM_NODISCARD inline bool isTrivial(ProgramStateRef State); + LLVM_NODISCARD inline bool isTrivial(ProgramStateRef State) const; /// Return true if the current class is trivial and its only member is dead. LLVM_NODISCARD inline bool isTriviallyDead(ProgramStateRef State, - SymbolReaper &Reaper); + SymbolReaper &Reaper) const; LLVM_NODISCARD static inline ProgramStateRef markDisequal(BasicValueFactory &BV, RangeSet::Factory &F, @@ -519,7 +630,7 @@ class EquivalenceClass : public llvm::FoldingSetNode { ProgramStateRef State, SymbolSet Members, EquivalenceClass Other, SymbolSet OtherMembers); - static inline void + static inline bool addToDisequalityInfo(DisequalityMapTy &Info, ConstraintRangeTy &Constraints, BasicValueFactory &BV, RangeSet::Factory &F, ProgramStateRef State, EquivalenceClass First, @@ -533,6 +644,15 @@ class EquivalenceClass : public llvm::FoldingSetNode { // Constraint functions //===----------------------------------------------------------------------===// +LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED bool +areFeasible(ConstraintRangeTy Constraints) { + return llvm::none_of( + Constraints, + [](const std::pair &ClassConstraint) { + return ClassConstraint.second.isEmpty(); + }); +} + LLVM_NODISCARD inline const RangeSet *getConstraint(ProgramStateRef State, EquivalenceClass Class) { return State->get(Class); @@ -651,7 +771,7 @@ LLVM_NODISCARD inline RangeSet intersect(BasicValueFactory &BV, RangeSet Second, RestTy... Tail) { // Here we call either the or version // of the function and can be sure that the result is RangeSet. - return intersect(BV, F, Head.Intersect(BV, F, Second), Tail...); + return intersect(BV, F, F.intersect(Head, Second), Tail...); } template @@ -940,7 +1060,7 @@ class SymbolicRangeInferrer /// Return a range set subtracting zero from \p Domain. RangeSet assumeNonZero(RangeSet Domain, QualType T) { APSIntType IntType = ValueFactory.getAPSIntType(T); - return Domain.Delete(ValueFactory, RangeFactory, IntType.getZeroValue()); + return RangeFactory.deletePoint(Domain, IntType.getZeroValue()); } // FIXME: Once SValBuilder supports unary minus, we should use SValBuilder to @@ -963,7 +1083,7 @@ class SymbolicRangeInferrer SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub, SSE->getLHS(), T); if (const RangeSet *NegatedRange = getConstraint(State, NegatedSym)) { - return NegatedRange->Negate(ValueFactory, RangeFactory); + return RangeFactory.negate(*NegatedRange); } } } @@ -1257,7 +1377,7 @@ RangeSet SymbolicRangeInferrer::VisitBinaryOperator(Range LHS, class RangeConstraintManager : public RangedConstraintManager { public: RangeConstraintManager(ExprEngine *EE, SValBuilder &SVB) - : RangedConstraintManager(EE, SVB) {} + : RangedConstraintManager(EE, SVB), F(getBasicVals()) {} //===------------------------------------------------------------------===// // Implementation for interface from ConstraintManager. @@ -1395,12 +1515,14 @@ class RangeConstraintManager : public RangedConstraintManager { return EquivalenceClass::merge(getBasicVals(), F, State, LHS, RHS); } - LLVM_NODISCARD inline ProgramStateRef setConstraint(ProgramStateRef State, - EquivalenceClass Class, - RangeSet Constraint) { + LLVM_NODISCARD ProgramStateRef setConstraint(ProgramStateRef State, + EquivalenceClass Class, + RangeSet Constraint) { ConstraintRangeTy Constraints = State->get(); ConstraintRangeTy::Factory &CF = State->get_context(); + assert(!Constraint.isEmpty() && "New constraint should not be empty"); + // Add new constraint. Constraints = CF.add(Constraints, Class, Constraint); @@ -1411,11 +1533,20 @@ class RangeConstraintManager : public RangedConstraintManager { // be simply a constant because we can't reason about range disequalities. if (const llvm::APSInt *Point = Constraint.getConcreteValue()) for (EquivalenceClass DisequalClass : Class.getDisequalClasses(State)) { - RangeSet UpdatedConstraint = - getRange(State, DisequalClass).Delete(getBasicVals(), F, *Point); + RangeSet UpdatedConstraint = getRange(State, DisequalClass); + UpdatedConstraint = F.deletePoint(UpdatedConstraint, *Point); + + // If we end up with at least one of the disequal classes to be + // constrained with an empty range-set, the state is infeasible. + if (UpdatedConstraint.isEmpty()) + return nullptr; + Constraints = CF.add(Constraints, DisequalClass, UpdatedConstraint); } + assert(areFeasible(Constraints) && "Constraint manager shouldn't produce " + "a state with infeasible constraints"); + return State->set(Constraints); } @@ -1552,6 +1683,9 @@ EquivalenceClass::mergeImpl(BasicValueFactory &ValueFactory, // Assign new constraints for this class. Constraints = CRF.add(Constraints, *this, *NewClassConstraint); + assert(areFeasible(Constraints) && "Constraint manager shouldn't produce " + "a state with infeasible constraints"); + State = State->set(Constraints); } @@ -1622,7 +1756,7 @@ EquivalenceClass::getMembersFactory(ProgramStateRef State) { return State->get_context(); } -SymbolSet EquivalenceClass::getClassMembers(ProgramStateRef State) { +SymbolSet EquivalenceClass::getClassMembers(ProgramStateRef State) const { if (const SymbolSet *Members = State->get(*this)) return *Members; @@ -1632,12 +1766,12 @@ SymbolSet EquivalenceClass::getClassMembers(ProgramStateRef State) { return F.add(F.getEmptySet(), getRepresentativeSymbol()); } -bool EquivalenceClass::isTrivial(ProgramStateRef State) { +bool EquivalenceClass::isTrivial(ProgramStateRef State) const { return State->get(*this) == nullptr; } bool EquivalenceClass::isTriviallyDead(ProgramStateRef State, - SymbolReaper &Reaper) { + SymbolReaper &Reaper) const { return isTrivial(State) && Reaper.isDead(getRepresentativeSymbol()); } @@ -1672,10 +1806,14 @@ EquivalenceClass::markDisequal(BasicValueFactory &VF, RangeSet::Factory &RF, // Disequality is a symmetric relation, so if we mark A as disequal to B, // we should also mark B as disequalt to A. - addToDisequalityInfo(DisequalityInfo, Constraints, VF, RF, State, *this, - Other); - addToDisequalityInfo(DisequalityInfo, Constraints, VF, RF, State, Other, - *this); + if (!addToDisequalityInfo(DisequalityInfo, Constraints, VF, RF, State, *this, + Other) || + !addToDisequalityInfo(DisequalityInfo, Constraints, VF, RF, State, Other, + *this)) + return nullptr; + + assert(areFeasible(Constraints) && "Constraint manager shouldn't produce " + "a state with infeasible constraints"); State = State->set(DisequalityInfo); State = State->set(Constraints); @@ -1683,7 +1821,7 @@ EquivalenceClass::markDisequal(BasicValueFactory &VF, RangeSet::Factory &RF, return State; } -inline void EquivalenceClass::addToDisequalityInfo( +inline bool EquivalenceClass::addToDisequalityInfo( DisequalityMapTy &Info, ConstraintRangeTy &Constraints, BasicValueFactory &VF, RangeSet::Factory &RF, ProgramStateRef State, EquivalenceClass First, EquivalenceClass Second) { @@ -1711,9 +1849,17 @@ inline void EquivalenceClass::addToDisequalityInfo( RangeSet FirstConstraint = SymbolicRangeInferrer::inferRange( VF, RF, State, First.getRepresentativeSymbol()); - FirstConstraint = FirstConstraint.Delete(VF, RF, *Point); + FirstConstraint = RF.deletePoint(FirstConstraint, *Point); + + // If the First class is about to be constrained with an empty + // range-set, the state is infeasible. + if (FirstConstraint.isEmpty()) + return false; + Constraints = CRF.add(Constraints, First, FirstConstraint); } + + return true; } inline Optional EquivalenceClass::areEqual(ProgramStateRef State, @@ -1862,7 +2008,7 @@ ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State, llvm::APSInt Zero = IntType.getZeroValue(); // Check if zero is in the set of possible values. - if (Ranges->Intersect(BV, F, Zero, Zero).isEmpty()) + if (!Ranges->contains(Zero)) return false; // Zero is a possible value, but it is not the /only/ possible value. @@ -2048,7 +2194,8 @@ RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym, llvm::APSInt Point = AdjustmentType.convert(Int) - Adjustment; - RangeSet New = getRange(St, Sym).Delete(getBasicVals(), F, Point); + RangeSet New = getRange(St, Sym); + New = F.deletePoint(New, Point); return trackNE(New, St, Sym, Int, Adjustment); } @@ -2064,7 +2211,8 @@ RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym, // [Int-Adjustment, Int-Adjustment] llvm::APSInt AdjInt = AdjustmentType.convert(Int) - Adjustment; - RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt); + RangeSet New = getRange(St, Sym); + New = F.intersect(New, AdjInt); return trackEQ(New, St, Sym, Int, Adjustment); } @@ -2094,7 +2242,8 @@ RangeSet RangeConstraintManager::getSymLTRange(ProgramStateRef St, llvm::APSInt Upper = ComparisonVal - Adjustment; --Upper; - return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper); + RangeSet Result = getRange(St, Sym); + return F.intersect(Result, Lower, Upper); } ProgramStateRef @@ -2130,7 +2279,8 @@ RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St, llvm::APSInt Upper = Max - Adjustment; ++Lower; - return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper); + RangeSet SymRange = getRange(St, Sym); + return F.intersect(SymRange, Lower, Upper); } ProgramStateRef @@ -2166,7 +2316,8 @@ RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St, llvm::APSInt Lower = ComparisonVal - Adjustment; llvm::APSInt Upper = Max - Adjustment; - return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper); + RangeSet SymRange = getRange(St, Sym); + return F.intersect(SymRange, Lower, Upper); } ProgramStateRef @@ -2202,7 +2353,8 @@ RangeConstraintManager::getSymLERange(llvm::function_ref RS, llvm::APSInt Lower = Min - Adjustment; llvm::APSInt Upper = ComparisonVal - Adjustment; - return RS().Intersect(getBasicVals(), F, Lower, Upper); + RangeSet Default = RS(); + return F.intersect(Default, Lower, Upper); } RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St, @@ -2235,7 +2387,7 @@ ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange( const llvm::APSInt &To, const llvm::APSInt &Adjustment) { RangeSet RangeLT = getSymLTRange(State, Sym, From, Adjustment); RangeSet RangeGT = getSymGTRange(State, Sym, To, Adjustment); - RangeSet New(RangeLT.addRange(F, RangeGT)); + RangeSet New(F.add(RangeLT, RangeGT)); return New.isEmpty() ? nullptr : setConstraint(State, Sym, New); } @@ -2270,7 +2422,7 @@ void RangeConstraintManager::printJson(raw_ostream &Out, ProgramStateRef State, } Indent(Out, Space, IsDot) << "{ \"symbol\": \"" << ClassMember << "\", \"range\": \""; - P.second.print(Out); + P.second.dump(Out); Out << "\" }"; } } diff --git a/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp index e7a03e6ed582..1b8945fb66af 100644 --- a/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp @@ -220,5 +220,4 @@ void RangedConstraintManager::computeAdjustment(SymbolRef &Sym, } } // end of namespace ento - } // end of namespace clang diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index facadaf1225f..872616fedb4e 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -652,6 +652,8 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, if (LHSValue == 0) return evalCastFromNonLoc(lhs, resultTy); return makeSymExprValNN(op, InputLHS, InputRHS, resultTy); + case BO_Div: + // 0 / x == 0 case BO_Rem: // 0 % x == 0 if (LHSValue == 0) diff --git a/clang/lib/Tooling/ArgumentsAdjusters.cpp b/clang/lib/Tooling/ArgumentsAdjusters.cpp index bcfb5b39a077..d94673bd2ab9 100644 --- a/clang/lib/Tooling/ArgumentsAdjusters.cpp +++ b/clang/lib/Tooling/ArgumentsAdjusters.cpp @@ -62,7 +62,8 @@ ArgumentsAdjuster getClangSyntaxOnlyAdjuster() { HasSyntaxOnly = true; } if (!HasSyntaxOnly) - AdjustedArgs.push_back("-fsyntax-only"); + AdjustedArgs = + getInsertArgumentAdjuster("-fsyntax-only")(AdjustedArgs, ""); return AdjustedArgs; }; } @@ -137,7 +138,7 @@ ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra, CommandLineArguments::iterator I; if (Pos == ArgumentInsertPosition::END) { - I = Return.end(); + I = std::find(Return.begin(), Return.end(), "--"); } else { I = Return.begin(); ++I; // To leave the program name in place diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index 7a58af59dad1..0a6fb99152dc 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -8,10 +8,116 @@ add_subdirectory(Core) add_subdirectory(Inclusions) add_subdirectory(Refactoring) add_subdirectory(ASTDiff) +add_subdirectory(DumpTool) add_subdirectory(Syntax) add_subdirectory(DependencyScanning) add_subdirectory(Transformer) +find_package(Python3 COMPONENTS Interpreter) + +# Replace the last lib component of the current binary directory with include +string(FIND ${CMAKE_CURRENT_BINARY_DIR} "/lib/" PATH_LIB_START REVERSE) +if(PATH_LIB_START EQUAL -1) + message(FATAL_ERROR "Couldn't find lib component in binary directory") +endif() +math(EXPR PATH_LIB_END "${PATH_LIB_START}+5") +string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) +string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} ${PATH_LIB_END} -1 PATH_TAIL) +string(CONCAT BINARY_INCLUDE_DIR ${PATH_HEAD} "/include/clang/" ${PATH_TAIL}) + +if (NOT Python3_EXECUTABLE + OR WIN32 + OR APPLE + OR GENERATOR_IS_MULTI_CONFIG + OR NOT LLVM_NATIVE_ARCH IN_LIST LLVM_TARGETS_TO_BUILD + OR NOT X86 IN_LIST LLVM_TARGETS_TO_BUILD + ) + file(GENERATE OUTPUT ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc + CONTENT " +namespace clang { +namespace tooling { + +NodeLocationAccessors NodeIntrospection::GetLocations(clang::Stmt const *) { + return {}; +} +NodeLocationAccessors NodeIntrospection::GetLocations(clang::Decl const *) { + return {}; +} +NodeLocationAccessors +NodeIntrospection::GetLocations(clang::DynTypedNode const &) { + return {}; +} +} // namespace tooling +} // namespace clang +" + ) + set(CLANG_TOOLING_BUILD_AST_INTROSPECTION "OFF" CACHE BOOL "") +else() + # The generation of ASTNodeAPI.json takes a long time in a + # Debug build due to parsing AST.h. Disable the processing + # but setting CLANG_TOOLING_BUILD_AST_INTROSPECTION as an + # internal hidden setting to override. + # When the processing is disabled, a trivial/empty JSON + # file is generated by clang-ast-dump and generate_cxx_src_locs.py + # generates the same API, but with a trivial implementation. + option(CLANG_TOOLING_BUILD_AST_INTROSPECTION "Enable AST introspection" TRUE) + + set(skip_expensive_processing $,$>>) + + file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ASTTU.cpp + CONTENT " +#include +") + + set(implicitDirs) + foreach(implicitDir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) + list(APPEND implicitDirs -I ${implicitDir}) + endforeach() + + add_custom_command( + COMMENT Generate ASTNodeAPI.json + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ASTNodeAPI.json + DEPENDS clang-ast-dump clang-resource-headers ${CMAKE_CURRENT_BINARY_DIR}/ASTTU.cpp + COMMAND + $ + # Skip this in debug mode because parsing AST.h is too slow + --skip-processing=${skip_expensive_processing} + --astheader=${CMAKE_CURRENT_BINARY_DIR}/ASTTU.cpp + -I ${CMAKE_BINARY_DIR}/lib/clang/${CLANG_VERSION}/include + -I ${CMAKE_SOURCE_DIR}/../clang/include + -I ${CMAKE_BINARY_DIR}/tools/clang/include + -I ${CMAKE_BINARY_DIR}/include + -I ${CMAKE_SOURCE_DIR}/include + ${implicitDirs} + --json-output-path ${CMAKE_CURRENT_BINARY_DIR}/ASTNodeAPI.json + ) + + add_custom_target(run-ast-api-dump-tool + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ASTNodeAPI.json + ) + + add_custom_command( + COMMENT Generate NodeIntrospection.inc + OUTPUT ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ASTNodeAPI.json + ${CMAKE_CURRENT_SOURCE_DIR}/DumpTool/generate_cxx_src_locs.py + COMMAND + ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/DumpTool/generate_cxx_src_locs.py + --json-input-path ${CMAKE_CURRENT_BINARY_DIR}/ASTNodeAPI.json + --output-file NodeIntrospection.inc + --empty-implementation ${skip_expensive_processing} + COMMAND + ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_BINARY_DIR}/NodeIntrospection.inc + ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc + ) + + add_custom_target(run-ast-api-generate-tool + DEPENDS + ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc + ) +endif() + add_clang_library(clangTooling AllTUsExecution.cpp ArgumentsAdjusters.cpp @@ -27,6 +133,8 @@ add_clang_library(clangTooling Refactoring.cpp RefactoringCallbacks.cpp StandaloneExecution.cpp + NodeIntrospection.cpp + ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc Tooling.cpp DEPENDS diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp index 16040c2f4626..3c61242da575 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -14,8 +14,8 @@ namespace tooling{ namespace dependencies{ std::vector FullDependencies::getAdditionalCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const { + std::function LookupPCMPath, + std::function LookupModuleDeps) const { std::vector Ret = AdditionalNonPathCommandLine; dependencies::detail::appendCommonModuleArguments( @@ -109,7 +109,7 @@ DependencyScanningTool::getFullDependencies( } void handleModuleDependency(ModuleDeps MD) override { - ClangModuleDeps[MD.ContextHash + MD.ModuleName] = std::move(MD); + ClangModuleDeps[MD.ID.ContextHash + MD.ID.ModuleName] = std::move(MD); } void handleContextHash(std::string Hash) override { @@ -119,14 +119,14 @@ DependencyScanningTool::getFullDependencies( FullDependenciesResult getFullDependencies() const { FullDependencies FD; - FD.ContextHash = std::move(ContextHash); + FD.ID.ContextHash = std::move(ContextHash); FD.FileDeps.assign(Dependencies.begin(), Dependencies.end()); for (auto &&M : ClangModuleDeps) { auto &MD = M.second; if (MD.ImportedByMainFile) - FD.ClangModuleDeps.push_back({MD.ModuleName, ContextHash}); + FD.ClangModuleDeps.push_back({MD.ID.ModuleName, ContextHash}); } FullDependenciesResult FDR; diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index f74ce7304df5..1fee831143e6 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -18,8 +18,8 @@ using namespace tooling; using namespace dependencies; std::vector ModuleDeps::getFullCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const { + std::function LookupPCMPath, + std::function LookupModuleDeps) const { std::vector Ret = NonPathCommandLine; // TODO: Build full command line. That also means capturing the original @@ -32,21 +32,21 @@ std::vector ModuleDeps::getFullCommandLine( } void dependencies::detail::appendCommonModuleArguments( - llvm::ArrayRef Modules, - std::function LookupPCMPath, - std::function LookupModuleDeps, + llvm::ArrayRef Modules, + std::function LookupPCMPath, + std::function LookupModuleDeps, std::vector &Result) { llvm::StringSet<> AlreadyAdded; - std::function)> AddArgs = - [&](llvm::ArrayRef Modules) { - for (const ClangModuleDep &CMD : Modules) { - if (!AlreadyAdded.insert(CMD.ModuleName + CMD.ContextHash).second) + std::function)> AddArgs = + [&](llvm::ArrayRef Modules) { + for (const ModuleID &MID : Modules) { + if (!AlreadyAdded.insert(MID.ModuleName + MID.ContextHash).second) continue; - const ModuleDeps &M = LookupModuleDeps(CMD); + const ModuleDeps &M = LookupModuleDeps(MID); // Depth first traversal. AddArgs(M.ClangModuleDeps); - Result.push_back(("-fmodule-file=" + LookupPCMPath(CMD)).str()); + Result.push_back(("-fmodule-file=" + LookupPCMPath(MID)).str()); if (!M.ClangModuleMapFile.empty()) { Result.push_back("-fmodule-map-file=" + M.ClangModuleMapFile); } @@ -79,7 +79,7 @@ void ModuleDepCollectorPP::FileChanged(SourceLocation Loc, // We do not want #line markers to affect dependency generation! if (Optional Filename = SM.getNonBuiltinFilenameForID(SM.getFileID(SM.getExpansionLoc(Loc)))) - MDC.MainDeps.push_back( + MDC.FileDeps.push_back( std::string(llvm::sys::path::remove_leading_dotslash(*Filename))); } @@ -91,7 +91,7 @@ void ModuleDepCollectorPP::InclusionDirective( if (!File && !Imported) { // This is a non-modular include that HeaderSearch failed to find. Add it // here as `FileChanged` will never see it. - MDC.MainDeps.push_back(std::string(FileName)); + MDC.FileDeps.push_back(std::string(FileName)); } handleImport(Imported); } @@ -106,9 +106,10 @@ void ModuleDepCollectorPP::handleImport(const Module *Imported) { if (!Imported) return; - MDC.Deps[MDC.ContextHash + Imported->getTopLevelModule()->getFullModuleName()] + const Module *TopLevelModule = Imported->getTopLevelModule(); + MDC.ModularDeps[MDC.ContextHash + TopLevelModule->getFullModuleName()] .ImportedByMainFile = true; - DirectDeps.insert(Imported->getTopLevelModule()); + DirectModularDeps.insert(TopLevelModule); } void ModuleDepCollectorPP::EndOfMainFile() { @@ -116,24 +117,23 @@ void ModuleDepCollectorPP::EndOfMainFile() { MDC.MainFile = std::string( Instance.getSourceManager().getFileEntryForID(MainFileID)->getName()); - for (const Module *M : DirectDeps) { + for (const Module *M : DirectModularDeps) handleTopLevelModule(M); - } - for (auto &&I : MDC.Deps) + for (auto &&I : MDC.ModularDeps) MDC.Consumer.handleModuleDependency(I.second); - for (auto &&I : MDC.MainDeps) + for (auto &&I : MDC.FileDeps) MDC.Consumer.handleFileDependency(*MDC.Opts, I); } void ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { assert(M == M->getTopLevelModule() && "Expected top level module!"); - auto ModI = MDC.Deps.insert( + auto ModI = MDC.ModularDeps.insert( std::make_pair(MDC.ContextHash + M->getFullModuleName(), ModuleDeps{})); - if (!ModI.first->second.ModuleName.empty()) + if (!ModI.first->second.ID.ModuleName.empty()) return; ModuleDeps &MD = ModI.first->second; @@ -144,9 +144,9 @@ void ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { .getContainingModuleMapFile(M); MD.ClangModuleMapFile = std::string(ModuleMap ? ModuleMap->getName() : ""); - MD.ModuleName = M->getFullModuleName(); + MD.ID.ModuleName = M->getFullModuleName(); MD.ImplicitModulePCMPath = std::string(M->getASTFile()->getName()); - MD.ContextHash = MDC.ContextHash; + MD.ID.ContextHash = MDC.ContextHash; serialization::ModuleFile *MF = MDC.Instance.getASTReader()->getModuleManager().lookup(M->getASTFile()); MDC.Instance.getASTReader()->visitInputFiles( diff --git a/clang/lib/Tooling/DumpTool/APIData.h b/clang/lib/Tooling/DumpTool/APIData.h new file mode 100644 index 000000000000..0ec53f6e7dc3 --- /dev/null +++ b/clang/lib/Tooling/DumpTool/APIData.h @@ -0,0 +1,32 @@ +//===- APIData.h ---------------------------------------------*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_TOOLING_DUMPTOOL_APIDATA_H +#define LLVM_CLANG_LIB_TOOLING_DUMPTOOL_APIDATA_H + +#include +#include + +namespace clang { +namespace tooling { + +struct ClassData { + + bool isEmpty() const { + return ASTClassLocations.empty() && ASTClassRanges.empty(); + } + + std::vector ASTClassLocations; + std::vector ASTClassRanges; + // TODO: Extend this with locations available via typelocs etc. +}; + +} // namespace tooling +} // namespace clang + +#endif diff --git a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp new file mode 100644 index 000000000000..d611261dd1a7 --- /dev/null +++ b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp @@ -0,0 +1,173 @@ +//===- ASTSrcLocProcessor.cpp --------------------------------*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ASTSrcLocProcessor.h" + +#include "clang/Frontend/CompilerInstance.h" +#include "llvm/Support/JSON.h" + +using namespace clang::tooling; +using namespace llvm; +using namespace clang::ast_matchers; + +ASTSrcLocProcessor::ASTSrcLocProcessor(StringRef JsonPath) + : JsonPath(JsonPath) { + + MatchFinder::MatchFinderOptions FinderOptions; + + Finder = std::make_unique(std::move(FinderOptions)); + Finder->addMatcher( + cxxRecordDecl( + isDefinition(), + isSameOrDerivedFrom( + // TODO: Extend this with other clades + namedDecl(hasAnyName("clang::Stmt", "clang::Decl")) + .bind("nodeClade")), + optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom")))) + .bind("className"), + this); +} + +std::unique_ptr +ASTSrcLocProcessor::createASTConsumer(clang::CompilerInstance &Compiler, + StringRef File) { + return Finder->newASTConsumer(); +} + +llvm::json::Object toJSON(llvm::StringMap> const &Obj) { + using llvm::json::toJSON; + + llvm::json::Object JsonObj; + for (const auto &Item : Obj) { + JsonObj[Item.first()] = Item.second; + } + return JsonObj; +} + +llvm::json::Object toJSON(llvm::StringMap const &Obj) { + using llvm::json::toJSON; + + llvm::json::Object JsonObj; + for (const auto &Item : Obj) { + JsonObj[Item.first()] = Item.second; + } + return JsonObj; +} + +llvm::json::Object toJSON(ClassData const &Obj) { + llvm::json::Object JsonObj; + + if (!Obj.ASTClassLocations.empty()) + JsonObj["sourceLocations"] = Obj.ASTClassLocations; + if (!Obj.ASTClassRanges.empty()) + JsonObj["sourceRanges"] = Obj.ASTClassRanges; + return JsonObj; +} + +llvm::json::Object toJSON(llvm::StringMap const &Obj) { + using llvm::json::toJSON; + + llvm::json::Object JsonObj; + for (const auto &Item : Obj) { + if (!Item.second.isEmpty()) + JsonObj[Item.first()] = ::toJSON(Item.second); + } + return JsonObj; +} + +void WriteJSON(std::string JsonPath, llvm::json::Object &&ClassInheritance, + llvm::json::Object &&ClassesInClade, + llvm::json::Object &&ClassEntries) { + llvm::json::Object JsonObj; + + using llvm::json::toJSON; + + JsonObj["classInheritance"] = std::move(ClassInheritance); + JsonObj["classesInClade"] = std::move(ClassesInClade); + JsonObj["classEntries"] = std::move(ClassEntries); + + std::error_code EC; + llvm::raw_fd_ostream JsonOut(JsonPath, EC, llvm::sys::fs::F_Text); + if (EC) + return; + + llvm::json::Value JsonVal(std::move(JsonObj)); + JsonOut << formatv("{0:2}", JsonVal); +} + +void ASTSrcLocProcessor::generate() { + WriteJSON(JsonPath, ::toJSON(ClassInheritance), ::toJSON(ClassesInClade), + ::toJSON(ClassEntries)); +} + +void ASTSrcLocProcessor::generateEmpty() { WriteJSON(JsonPath, {}, {}, {}); } + +std::vector +CaptureMethods(std::string TypeString, const clang::CXXRecordDecl *ASTClass, + const MatchFinder::MatchResult &Result) { + + auto publicAccessor = [](auto... InnerMatcher) { + return cxxMethodDecl(isPublic(), parameterCountIs(0), isConst(), + InnerMatcher...); + }; + + auto BoundNodesVec = + match(findAll(publicAccessor(ofClass(equalsNode(ASTClass)), + returns(asString(TypeString))) + .bind("classMethod")), + *ASTClass, *Result.Context); + + std::vector Methods; + for (const auto &BN : BoundNodesVec) { + if (const auto *Node = BN.getNodeAs("classMethod")) { + // Only record the getBeginLoc etc on Stmt etc, because it will call + // more-derived implementations pseudo-virtually. + if ((ASTClass->getName() != "Stmt" && ASTClass->getName() != "Decl") && + (Node->getName() == "getBeginLoc" || Node->getName() == "getEndLoc" || + Node->getName() == "getSourceRange")) { + continue; + } + // Only record the getExprLoc on Expr, because it will call + // more-derived implementations pseudo-virtually. + if (ASTClass->getName() != "Expr" && Node->getName() == "getExprLoc") { + continue; + } + Methods.push_back(Node->getName().str()); + } + } + return Methods; +} + +void ASTSrcLocProcessor::run(const MatchFinder::MatchResult &Result) { + + if (const auto *ASTClass = + Result.Nodes.getNodeAs("className")) { + + StringRef ClassName = ASTClass->getName(); + + ClassData CD; + + const auto *NodeClade = + Result.Nodes.getNodeAs("nodeClade"); + StringRef CladeName = NodeClade->getName(); + + if (const auto *DerivedFrom = + Result.Nodes.getNodeAs("derivedFrom")) + ClassInheritance[ClassName] = DerivedFrom->getName(); + + CD.ASTClassLocations = + CaptureMethods("class clang::SourceLocation", ASTClass, Result); + CD.ASTClassRanges = + CaptureMethods("class clang::SourceRange", ASTClass, Result); + + if (!CD.isEmpty()) { + ClassEntries[ClassName] = CD; + ClassesInClade[CladeName].push_back(ClassName); + } + } +} diff --git a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h new file mode 100644 index 000000000000..5d848f48ed54 --- /dev/null +++ b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h @@ -0,0 +1,49 @@ +//===- ASTSrcLocProcessor.h ---------------------------------*- C++ -*-----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_DUMPTOOL_ASTSRCLOCPROCESSOR_H +#define LLVM_CLANG_TOOLING_DUMPTOOL_ASTSRCLOCPROCESSOR_H + +#include "APIData.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/ADT/StringRef.h" +#include +#include +#include + +namespace clang { + +class CompilerInstance; + +namespace tooling { + +class ASTSrcLocProcessor : public ast_matchers::MatchFinder::MatchCallback { +public: + explicit ASTSrcLocProcessor(StringRef JsonPath); + + std::unique_ptr createASTConsumer(CompilerInstance &Compiler, + StringRef File); + + void generate(); + void generateEmpty(); + +private: + void run(const ast_matchers::MatchFinder::MatchResult &Result) override; + + llvm::StringMap ClassInheritance; + llvm::StringMap> ClassesInClade; + llvm::StringMap ClassEntries; + + std::string JsonPath; + std::unique_ptr Finder; +}; + +} // namespace tooling +} // namespace clang + +#endif diff --git a/clang/lib/Tooling/DumpTool/CMakeLists.txt b/clang/lib/Tooling/DumpTool/CMakeLists.txt new file mode 100644 index 000000000000..712985bf7e2b --- /dev/null +++ b/clang/lib/Tooling/DumpTool/CMakeLists.txt @@ -0,0 +1,16 @@ + +add_clang_executable(clang-ast-dump + ASTSrcLocProcessor.cpp + ClangSrcLocDump.cpp +) + +target_link_libraries(clang-ast-dump + PRIVATE + clangAST + clangASTMatchers + clangBasic + clangDriver + clangFrontend + clangSerialization + clangToolingCore +) diff --git a/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp b/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp new file mode 100644 index 000000000000..8328977178cc --- /dev/null +++ b/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp @@ -0,0 +1,154 @@ +//===- ClangSrcLocDump.cpp ------------------------------------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/Diagnostic.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Job.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/Tool.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/JSON.h" + +#include "ASTSrcLocProcessor.h" + +using namespace clang::tooling; +using namespace clang; +using namespace llvm; + +static cl::list IncludeDirectories( + "I", cl::desc("Include directories to use while compiling"), + cl::value_desc("directory"), cl::Required, cl::OneOrMore, cl::Prefix); + +static cl::opt + AstHeaderFile("astheader", cl::desc("AST header to parse API from"), + cl::Required, cl::value_desc("AST header file")); + +static cl::opt + SkipProcessing("skip-processing", + cl::desc("Avoid processing the AST header file"), + cl::Required, cl::value_desc("bool")); + +static cl::opt JsonOutputPath("json-output-path", + cl::desc("json output path"), + cl::Required, + cl::value_desc("path")); + +class ASTSrcLocGenerationAction : public clang::ASTFrontendAction { +public: + ASTSrcLocGenerationAction() : Processor(JsonOutputPath) {} + + void ExecuteAction() override { + clang::ASTFrontendAction::ExecuteAction(); + if (getCompilerInstance().getDiagnostics().getNumErrors() > 0) + Processor.generateEmpty(); + else + Processor.generate(); + } + + std::unique_ptr + CreateASTConsumer(clang::CompilerInstance &Compiler, + llvm::StringRef File) override { + return Processor.createASTConsumer(Compiler, File); + } + +private: + ASTSrcLocProcessor Processor; +}; + +int main(int argc, const char **argv) { + + cl::ParseCommandLineOptions(argc, argv); + + if (SkipProcessing) { + std::error_code EC; + llvm::raw_fd_ostream JsonOut(JsonOutputPath, EC, llvm::sys::fs::F_Text); + if (EC) + return 1; + JsonOut << formatv("{0:2}", llvm::json::Value(llvm::json::Object())); + return 0; + } + + std::vector Args; + Args.push_back("-cc1"); + + llvm::transform(IncludeDirectories, std::back_inserter(Args), + [](const std::string &IncDir) { return "-I" + IncDir; }); + + Args.push_back("-fsyntax-only"); + Args.push_back(AstHeaderFile); + + std::vector Argv(Args.size(), nullptr); + llvm::transform(Args, Argv.begin(), + [](const std::string &Arg) { return Arg.c_str(); }); + + IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); + unsigned MissingArgIndex, MissingArgCount; + auto Opts = driver::getDriverOptTable(); + auto ParsedArgs = Opts.ParseArgs(llvm::makeArrayRef(Argv).slice(1), + MissingArgIndex, MissingArgCount); + ParseDiagnosticArgs(*DiagOpts, ParsedArgs); + + // Don't output diagnostics, because common scenarios such as + // cross-compiling fail with diagnostics. This is not fatal, but + // just causes attempts to use the introspection API to return no data. + std::string Str; + llvm::raw_string_ostream OS(Str); + TextDiagnosticPrinter DiagnosticPrinter(OS, &*DiagOpts); + DiagnosticsEngine Diagnostics( + IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts, + &DiagnosticPrinter, false); + + FileManager Files(FileSystemOptions(), vfs::getRealFileSystem()); + + auto Driver = std::make_unique( + "clang", llvm::sys::getDefaultTargetTriple(), Diagnostics, + "ast-api-dump-tool", &Files.getVirtualFileSystem()); + + std::unique_ptr Comp( + Driver->BuildCompilation(llvm::makeArrayRef(Argv))); + if (!Comp) + return 1; + + const auto &Jobs = Comp->getJobs(); + if (Jobs.size() != 1 || !isa(*Jobs.begin())) { + SmallString<256> error_msg; + llvm::raw_svector_ostream error_stream(error_msg); + Jobs.Print(error_stream, "; ", true); + return 1; + } + + const auto &Cmd = cast(*Jobs.begin()); + const llvm::opt::ArgStringList &CC1Args = Cmd.getArguments(); + + auto Invocation = std::make_unique(); + CompilerInvocation::CreateFromArgs(*Invocation, CC1Args, Diagnostics); + + CompilerInstance Compiler(std::make_shared()); + Compiler.setInvocation(std::move(Invocation)); + + Compiler.createDiagnostics(&DiagnosticPrinter, false); + if (!Compiler.hasDiagnostics()) + return 1; + + // Suppress "2 errors generated" or similar messages + Compiler.getDiagnosticOpts().ShowCarets = false; + Compiler.createSourceManager(Files); + + ASTSrcLocGenerationAction ScopedToolAction; + Compiler.ExecuteAction(ScopedToolAction); + + Files.clearStatCache(); + + return 0; +} diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py new file mode 100755 index 000000000000..15a373e52480 --- /dev/null +++ b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import sys +import json + +import argparse + +class Generator(object): + + implementationContent = '' + + def GeneratePrologue(self): + + self.implementationContent += \ + """ +/*===- Generated file -------------------------------------------*- C++ -*-===*\ +|* *| +|* Introspection of available AST node SourceLocations *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +namespace clang { +namespace tooling { + +using LocationAndString = SourceLocationMap::value_type; +using RangeAndString = SourceRangeMap::value_type; +""" + + def GenerateBaseGetLocationsDeclaration(self, CladeName): + self.implementationContent += \ + """ +void GetLocationsImpl(std::shared_ptr const& Prefix, + clang::{0} const *Object, SourceLocationMap &Locs, + SourceRangeMap &Rngs); +""".format(CladeName) + + def GenerateSrcLocMethod(self, ClassName, ClassData): + + self.implementationContent += \ + """ +static void GetLocations{0}(std::shared_ptr const& Prefix, + clang::{0} const &Object, + SourceLocationMap &Locs, SourceRangeMap &Rngs) +{{ +""".format(ClassName) + + if 'sourceLocations' in ClassData: + for locName in ClassData['sourceLocations']: + self.implementationContent += \ + """ + Locs.insert(LocationAndString(Object.{0}(), + std::make_shared(Prefix, "{0}"))); +""".format(locName) + + self.implementationContent += '\n' + + if 'sourceRanges' in ClassData: + for rngName in ClassData['sourceRanges']: + self.implementationContent += \ + """ + Rngs.insert(RangeAndString(Object.{0}(), + std::make_shared(Prefix, "{0}"))); +""".format(rngName) + + self.implementationContent += '\n' + + self.implementationContent += '}\n' + + def GenerateFiles(self, OutputFile): + with open(os.path.join(os.getcwd(), + OutputFile), 'w') as f: + f.write(self.implementationContent) + + def GenerateBaseGetLocationsFunction(self, ASTClassNames, CladeName): + + MethodReturnType = 'NodeLocationAccessors' + + Signature = \ + 'GetLocations(clang::{0} const *Object)'.format(CladeName) + ImplSignature = \ + """ +GetLocationsImpl(std::shared_ptr const& Prefix, + clang::{0} const *Object, SourceLocationMap &Locs, + SourceRangeMap &Rngs) +""".format(CladeName) + + self.implementationContent += \ + 'void {0} {{ GetLocations{1}(Prefix, *Object, Locs, Rngs);'.format( + ImplSignature, + CladeName) + + for ASTClassName in ASTClassNames: + if ASTClassName != CladeName: + self.implementationContent += \ + """ +if (auto Derived = llvm::dyn_cast(Object)) {{ + GetLocations{0}(Prefix, *Derived, Locs, Rngs); +}} +""".format(ASTClassName) + + self.implementationContent += '}' + + self.implementationContent += \ + """ +{0} NodeIntrospection::{1} {{ + NodeLocationAccessors Result; + std::shared_ptr Prefix; + + GetLocationsImpl(Prefix, Object, Result.LocationAccessors, + Result.RangeAccessors); +""".format(MethodReturnType, + Signature) + + self.implementationContent += 'return Result; }' + + def GenerateDynNodeVisitor(self, CladeNames): + MethodReturnType = 'NodeLocationAccessors' + + Signature = \ + 'GetLocations(clang::DynTypedNode const &Node)' + + self.implementationContent += MethodReturnType \ + + ' NodeIntrospection::' + Signature + '{' + + for CladeName in CladeNames: + self.implementationContent += \ + """ + if (const auto *N = Node.get<{0}>()) + return GetLocations(const_cast<{0} *>(N));""".format(CladeName) + + self.implementationContent += '\nreturn {}; }' + + def GenerateEpilogue(self): + + self.implementationContent += ''' + } +} +''' + +def main(): + + parser = argparse.ArgumentParser() + parser.add_argument('--json-input-path', + help='Read API description from FILE', metavar='FILE') + parser.add_argument('--output-file', help='Generate output in FILEPATH', + metavar='FILEPATH') + parser.add_argument('--empty-implementation', + help='Generate empty implementation', + action="store", type=int) + + options = parser.parse_args() + + use_empty_implementation = options.empty_implementation + + if (not use_empty_implementation + and not os.path.exists(options.json_input_path)): + use_empty_implementation = True + + if not use_empty_implementation: + with open(options.json_input_path) as f: + jsonData = json.load(f) + + if not 'classesInClade' in jsonData or not jsonData["classesInClade"]: + use_empty_implementation = True + + if use_empty_implementation: + with open(os.path.join(os.getcwd(), + options.output_file), 'w') as f: + f.write(""" +namespace clang { +namespace tooling { + +NodeLocationAccessors NodeIntrospection::GetLocations(clang::Stmt const *) { + return {}; +} +NodeLocationAccessors NodeIntrospection::GetLocations(clang::Decl const *) { + return {}; +} +NodeLocationAccessors +NodeIntrospection::GetLocations(clang::DynTypedNode const &) { + return {}; +} +} // namespace tooling +} // namespace clang + """) + sys.exit(0) + + g = Generator() + + g.GeneratePrologue() + + for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): + g.GenerateBaseGetLocationsDeclaration(CladeName) + + for (ClassName, ClassAccessors) in jsonData['classEntries'].items(): + if ClassAccessors: + g.GenerateSrcLocMethod(ClassName, ClassAccessors) + + for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): + g.GenerateBaseGetLocationsFunction(ClassNameData, CladeName) + + g.GenerateDynNodeVisitor(jsonData['classesInClade'].keys()) + + g.GenerateEpilogue() + + g.GenerateFiles(options.output_file) + +if __name__ == '__main__': + main() diff --git a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp index 6f97d2867ae5..3b65504b98ea 100644 --- a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -177,6 +177,10 @@ struct TransferableCommand { Opt.matches(OPT__SLASH_Fo)))) continue; + // ...including when the inputs are passed after --. + if (Opt.matches(OPT__DASH_DASH)) + break; + // Strip -x, but record the overridden language. if (const auto GivenType = tryParseTypeArg(*Arg)) { Type = *GivenType; @@ -235,6 +239,8 @@ struct TransferableCommand { llvm::Twine(ClangCLMode ? "/std:" : "-std=") + LangStandard::getLangStandardForKind(Std).getName()).str()); } + if (Filename.startswith("-") || (ClangCLMode && Filename.startswith("/"))) + Result.CommandLine.push_back("--"); Result.CommandLine.push_back(std::string(Filename)); return Result; } diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp index 2d8847a7a327..97ba7e411fbb 100644 --- a/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -198,7 +198,7 @@ JSONCompilationDatabase::loadFromFile(StringRef FilePath, JSONCommandLineSyntax Syntax) { // Don't mmap: if we're a long-lived process, the build system may overwrite. llvm::ErrorOr> DatabaseBuffer = - llvm::MemoryBuffer::getFile(FilePath, /*FileSize=*/-1, + llvm::MemoryBuffer::getFile(FilePath, /*IsText=*/false, /*RequiresNullTerminator=*/true, /*IsVolatile=*/true); if (std::error_code Result = DatabaseBuffer.getError()) { diff --git a/clang/lib/Tooling/NodeIntrospection.cpp b/clang/lib/Tooling/NodeIntrospection.cpp new file mode 100644 index 000000000000..89e8c19c6ba8 --- /dev/null +++ b/clang/lib/Tooling/NodeIntrospection.cpp @@ -0,0 +1,61 @@ +//===- NodeIntrospection.h -----------------------------------*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the implementation of the NodeIntrospection. +// +//===----------------------------------------------------------------------===// + +#include "clang/Tooling/NodeIntrospection.h" + +#include "clang/AST/AST.h" + +namespace clang { + +namespace tooling { + +std::string LocationCallFormatterCpp::format(LocationCall *Call) { + SmallVector vec; + while (Call) { + vec.push_back(Call); + Call = Call->on(); + } + std::string result; + for (auto *VecCall : llvm::reverse(llvm::makeArrayRef(vec).drop_front())) { + result += + (VecCall->name() + "()" + (VecCall->returnsPointer() ? "->" : ".")) + .str(); + } + result += (vec.back()->name() + "()").str(); + return result; +} + +namespace internal { +bool RangeLessThan::operator()( + std::pair> const &LHS, + std::pair> const &RHS) const { + if (!LHS.first.isValid() || !RHS.first.isValid()) + return false; + + if (LHS.first.getBegin() < RHS.first.getBegin()) + return true; + else if (LHS.first.getBegin() != RHS.first.getBegin()) + return false; + + if (LHS.first.getEnd() < RHS.first.getEnd()) + return true; + else if (LHS.first.getEnd() != RHS.first.getEnd()) + return false; + + return LHS.second->name() < RHS.second->name(); +} +} // namespace internal + +} // namespace tooling +} // namespace clang + +#include "clang/Tooling/NodeIntrospection.inc" diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp index 234df9cb7182..2326e89ea48b 100644 --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -183,7 +183,31 @@ llvm::StringRef FileRange::text(const SourceManager &SM) const { return Text.substr(Begin, length()); } +void TokenBuffer::indexExpandedTokens() { + // No-op if the index is already created. + if (!ExpandedTokIndex.empty()) + return; + ExpandedTokIndex.reserve(ExpandedTokens.size()); + // Index ExpandedTokens for faster lookups by SourceLocation. + for (size_t I = 0, E = ExpandedTokens.size(); I != E; ++I) + ExpandedTokIndex[ExpandedTokens[I].location()] = I; +} + llvm::ArrayRef TokenBuffer::expandedTokens(SourceRange R) const { + if (!ExpandedTokIndex.empty()) { + // Quick lookup if `R` is a token range. + // This is a huge win since majority of the users use ranges provided by an + // AST. Ranges in AST are token ranges from expanded token stream. + const auto B = ExpandedTokIndex.find(R.getBegin()); + const auto E = ExpandedTokIndex.find(R.getEnd()); + if (B != ExpandedTokIndex.end() && E != ExpandedTokIndex.end()) { + // Add 1 to End to make a half-open range. + return {ExpandedTokens.data() + B->getSecond(), + ExpandedTokens.data() + E->getSecond() + 1}; + } + } + // Slow case. Use `isBeforeInTranslationUnit` to binary search for the + // required range. return getTokensCovering(expandedTokens(), R, *SourceMgr); } diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index 79851ac723da..b28e8f6a7c96 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -440,8 +440,9 @@ static void injectResourceDir(CommandLineArguments &Args, const char *Argv0, return; // If there's no override in place add our resource dir. - Args.push_back("-resource-dir=" + - CompilerInvocation::GetResourcesPath(Argv0, MainAddr)); + Args = getInsertArgumentAdjuster( + ("-resource-dir=" + CompilerInvocation::GetResourcesPath(Argv0, MainAddr)) + .c_str())(Args, ""); } int ClangTool::run(ToolAction *Action) { diff --git a/clang/runtime/CMakeLists.txt b/clang/runtime/CMakeLists.txt index 61bbbf8faedd..1716c53b031e 100644 --- a/clang/runtime/CMakeLists.txt +++ b/clang/runtime/CMakeLists.txt @@ -95,6 +95,8 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/) USES_TERMINAL_CONFIGURE 1 USES_TERMINAL_BUILD 1 USES_TERMINAL_INSTALL 1 + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS 1 ) get_ext_project_build_command(run_clean_compiler_rt clean) diff --git a/clang/test/AST/alignas_maybe_odr_cleanup.cpp b/clang/test/AST/alignas_maybe_odr_cleanup.cpp index 3adef4cba144..ed34930e98a0 100644 --- a/clang/test/AST/alignas_maybe_odr_cleanup.cpp +++ b/clang/test/AST/alignas_maybe_odr_cleanup.cpp @@ -8,7 +8,7 @@ // RUN: | FileCheck %s struct FOO { - static const int vec_align_bytes = 32; + static const int vec_align_bytes = 16; void foo() { double a alignas(vec_align_bytes); ; @@ -17,7 +17,7 @@ struct FOO { // CHECK: | `-AlignedAttr {{.*}} alignas // CHECK-NEXT: | `-ConstantExpr {{.*}} 'int' -// CHECK-NEXT: | |-value: Int 32 +// CHECK-NEXT: | |-value: Int 16 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'const int' lvalue Var {{.*}} 'vec_align_bytes' 'const int' non_odr_use_constant // CHECK-NEXT: `-NullStmt {{.*}} diff --git a/clang/test/AST/ast-print-int128.cpp b/clang/test/AST/ast-print-int128.cpp new file mode 100644 index 000000000000..51d15b609f0b --- /dev/null +++ b/clang/test/AST/ast-print-int128.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -ast-print -std=c++20 %s -o - -triple x86_64-linux | FileCheck %s + +template +struct enable_if { +}; + +template <__uint128_t x, typename = typename enable_if::type> +void f(); + +template <__int128_t> +void f(); + +using T = decltype(f<0>()); + +// CHECK: using T = decltype(f<0>()); diff --git a/clang/test/Analysis/Inputs/ctu-inherited-default-ctor-other.cpp b/clang/test/Analysis/Inputs/ctu-inherited-default-ctor-other.cpp new file mode 100644 index 000000000000..b529f416999d --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-inherited-default-ctor-other.cpp @@ -0,0 +1,27 @@ +namespace llvm { +template +class impl; +// basecase +template +class impl {}; +// recursion +template +class impl : impl { + using child = impl; + using child::child; // no-crash + impl(T); +}; +template +class container : impl<0, TS...> {}; +} // namespace llvm +namespace clang { +class fun { + llvm::container k; + fun() {} +}; +class DeclContextLookupResult { + static int *const SingleElementDummyList; +}; +} // namespace clang +using namespace clang; +int *const DeclContextLookupResult::SingleElementDummyList = nullptr; diff --git a/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist b/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist index 74e11075fe3d..1d82f3cd8424 100644 --- a/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist +++ b/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist @@ -2368,7 +2368,7 @@ descriptionValue stored to 'x' is never read - categoryDead store + categoryUnused code typeDead increment check_namedeadcode.DeadStores @@ -11409,7 +11409,7 @@ descriptionValue stored to 'foo' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores diff --git a/clang/test/Analysis/Inputs/expected-plists/objc-arc.m.plist b/clang/test/Analysis/Inputs/expected-plists/objc-arc.m.plist index d3a1a5c6c47f..b8bc73611111 100644 --- a/clang/test/Analysis/Inputs/expected-plists/objc-arc.m.plist +++ b/clang/test/Analysis/Inputs/expected-plists/objc-arc.m.plist @@ -382,7 +382,7 @@ descriptionValue stored to 'x' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -450,7 +450,7 @@ descriptionValue stored to 'obj1' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -518,7 +518,7 @@ descriptionValue stored to 'obj4' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -586,7 +586,7 @@ descriptionValue stored to 'obj5' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -654,7 +654,7 @@ descriptionValue stored to 'obj6' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -1064,7 +1064,7 @@ descriptionValue stored to 'cf1' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -1132,7 +1132,7 @@ descriptionValue stored to 'cf2' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -1200,7 +1200,7 @@ descriptionValue stored to 'cf3' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -1268,7 +1268,7 @@ descriptionValue stored to 'cf4' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores diff --git a/clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist b/clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist index 76fec546267c..b7ffbf5b5fee 100644 --- a/clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist +++ b/clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist @@ -2169,7 +2169,7 @@ descriptionValue stored to 'foo' during its initialization is never read - categoryDead store + categoryUnused code typeDead initialization check_namedeadcode.DeadStores @@ -5654,7 +5654,7 @@ descriptionValue stored to 'x' is never read - categoryDead store + categoryUnused code typeDead increment check_namedeadcode.DeadStores diff --git a/clang/test/Analysis/PR49490.cpp b/clang/test/Analysis/PR49490.cpp new file mode 100644 index 000000000000..3254355013a6 --- /dev/null +++ b/clang/test/Analysis/PR49490.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core -verify %s + +// expected-no-diagnostics + +struct toggle { + bool value; +}; + +toggle global_toggle; +toggle get_global_toggle() { return global_toggle; } + +int oob_access(); + +bool compare(toggle one, bool other) { + if (one.value != other) + return true; + + if (one.value) + oob_access(); + return true; +} + +bool coin(); + +void bar() { + bool left = coin(); + bool right = coin(); + for (;;) + compare(get_global_toggle(), left) && compare(get_global_toggle(), right); +} diff --git a/clang/test/Analysis/PR49642.c b/clang/test/Analysis/PR49642.c new file mode 100644 index 000000000000..af691d6afd6f --- /dev/null +++ b/clang/test/Analysis/PR49642.c @@ -0,0 +1,24 @@ +// RUN: %clang_analyze_cc1 -w -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions + +// expected-no-diagnostics + +typedef ssize_t; +b; + +unsigned c; +int write(int, const void *, unsigned long); + +a() { + d(); + while (c > 0) { + b = write(0, d, c); + if (b) + c -= b; + b < 1; + } + if (c && c) { + // ^ no-crash + } +} diff --git a/clang/test/Analysis/atomics.c b/clang/test/Analysis/atomics.c index b3d2d352a228..ef1a216c7d57 100644 --- a/clang/test/Analysis/atomics.c +++ b/clang/test/Analysis/atomics.c @@ -93,3 +93,11 @@ void test_atomic_compare_exchange_weak(struct RefCountedStruct *s) { clang_analyzer_eval(s->refCount == 3); // expected-warning {{UNKNOWN}} clang_analyzer_eval(expected == 2); // expected-warning {{UNKNOWN}} } + +// PR49422 +void test_atomic_compare(int input) { + _Atomic(int) x = input; + if (x > 0) { + // no crash + } +} diff --git a/clang/test/Analysis/ctu-inherited-default-ctor.cpp b/clang/test/Analysis/ctu-inherited-default-ctor.cpp new file mode 100644 index 000000000000..7c208a86ba93 --- /dev/null +++ b/clang/test/Analysis/ctu-inherited-default-ctor.cpp @@ -0,0 +1,28 @@ +// Should not crash with '-analyzer-opt-analyze-headers' option during CTU analysis. +// +// RUN: rm -rf %t && mkdir -p %t/ctudir +// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ +// RUN: -emit-pch -o %t/ctudir/ctu-inherited-default-ctor-other.cpp.ast \ +// RUN: %S/Inputs/ctu-inherited-default-ctor-other.cpp +// RUN: echo "c:@N@clang@S@DeclContextLookupResult@SingleElementDummyList ctu-inherited-default-ctor-other.cpp.ast" \ +// RUN: > %t/ctudir/externalDefMap.txt +// +// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ +// RUN: -analyzer-opt-analyze-headers \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir \ +// RUN: -analyzer-config display-ctu-progress=true \ +// RUN: -verify %s 2>&1 | FileCheck %s +// +// expected-no-diagnostics +// +// CHECK: CTU loaded AST file: ctu-inherited-default-ctor-other.cpp.ast + +namespace clang {} +namespace llvm {} +namespace clang { +class DeclContextLookupResult { + static int *const SingleElementDummyList; +}; +} // namespace clang diff --git a/clang/test/Analysis/division-by-zero-track-zero.c b/clang/test/Analysis/division-by-zero-track-zero.c new file mode 100644 index 000000000000..f6b2a78ed701 --- /dev/null +++ b/clang/test/Analysis/division-by-zero-track-zero.c @@ -0,0 +1,11 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core \ +// RUN: -analyzer-output=text \ +// RUN: -verify %s + +int track_mul_lhs_0(int x, int y) { + int p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = p0 * y; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} +} diff --git a/clang/test/Analysis/division-by-zero-track-zero.cpp b/clang/test/Analysis/division-by-zero-track-zero.cpp new file mode 100644 index 000000000000..c4b9550c76c0 --- /dev/null +++ b/clang/test/Analysis/division-by-zero-track-zero.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core \ +// RUN: -analyzer-output=text \ +// RUN: -verify %s + +namespace test_tracking_of_lhs_multiplier { + int f(int x, int y) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = p0 * y; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_of_lhs_multiplier + +namespace test_tracking_of_rhs_multiplier { + int f(int x, int y) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = y * p0; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_of_rhs_multiplier + +namespace test_tracking_of_nested_multiplier { + int f(int x, int y, int z) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = y*z*p0; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_of_nested_multiplier + +namespace test_tracking_through_multiple_stmts { + int f(int x, int y) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} + bool p1 = p0 ? 0 : 1; // expected-note {{'p0' is false}} \ + // expected-note {{'?' condition is false}} + bool p2 = 1 - p1; // expected-note {{'p2' initialized to 0}} + int div = p2 * y; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_through_multiple_stmts + +namespace test_tracking_both_lhs_and_rhs { + int f(int x, int y) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + bool p1 = y < 0; // expected-note {{Assuming 'y' is >= 0}} \ + // expected-note {{'p1' initialized to 0}} + int div = p0 * p1; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_both_lhs_and_rhs + +namespace test_tracking_of_multiplier_and_parens { + int f(int x, int y, int z) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = y*(z*p0); // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_of_multiplier_and_parens + +namespace test_tracking_of_divisible { + int f(int x, int y) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = p0 / y; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_of_divisible + +namespace test_tracking_of_modulo { + int f(int x, int y) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = p0 % y; // expected-note {{'div' initialized to 0}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_of_modulo + +namespace test_tracking_of_assignment { + int f(int x) { + bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \ + // expected-note {{'p0' initialized to 0}} + int div = 1; + div *= p0; // expected-note {{The value 0 is assigned to 'div'}} + return 1 / div; // expected-note {{Division by zero}} \ + // expected-warning {{Division by zero}} + } +} // namespace test_tracking_of_assignment diff --git a/clang/test/Analysis/iterator-range.cpp b/clang/test/Analysis/iterator-range.cpp index 8d7103929047..849a1e9814ae 100644 --- a/clang/test/Analysis/iterator-range.cpp +++ b/clang/test/Analysis/iterator-range.cpp @@ -939,3 +939,10 @@ void ptr_iter_diff(cont_with_ptr_iterator &c) { auto i0 = c.begin(), i1 = c.end(); ptrdiff_t len = i1 - i0; // no-crash } + +int uninit_var(int n) { + int uninit; // expected-note{{'uninit' declared without an initial value}} + return n - uninit; // no-crash + // expected-warning@-1 {{The right operand of '-' is a garbage value}} + // expected-note@-2 {{The right operand of '-' is a garbage value}} +} diff --git a/clang/test/Analysis/nullptr.cpp b/clang/test/Analysis/nullptr.cpp index e9b975c148aa..24b574a4ccfe 100644 --- a/clang/test/Analysis/nullptr.cpp +++ b/clang/test/Analysis/nullptr.cpp @@ -64,7 +64,7 @@ void zoo1backwards() { typedef __INTPTR_TYPE__ intptr_t; void zoo1multiply() { - char **p = 0; // FIXME-should-be-note:{{'p' initialized to a null pointer value}} + char **p = 0; // expected-note{{'p' initialized to a null pointer value}} delete *((char **)((intptr_t)p * 2)); // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } diff --git a/clang/test/Analysis/os_object_base.h b/clang/test/Analysis/os_object_base.h index 4698185f2b3c..c3d5d6271d48 100644 --- a/clang/test/Analysis/os_object_base.h +++ b/clang/test/Analysis/os_object_base.h @@ -66,6 +66,7 @@ struct OSObject : public OSMetaClassBase { struct OSMetaClass : public OSMetaClassBase { virtual OSObject * alloc() const; + static OSObject * allocClassWithName(const char * name); virtual ~OSMetaClass(){} }; diff --git a/clang/test/Analysis/osobjectcstylecastchecker_test.cpp b/clang/test/Analysis/osobjectcstylecastchecker_test.cpp index a5ebb2823a92..aa43a18e6346 100644 --- a/clang/test/Analysis/osobjectcstylecastchecker_test.cpp +++ b/clang/test/Analysis/osobjectcstylecastchecker_test.cpp @@ -37,3 +37,12 @@ unsigned no_warn_on_other_type_cast(A *a) { return b->getCount(); } +unsigned no_warn_alloc_class_with_name() { + OSArray *a = (OSArray *)OSMetaClass::allocClassWithName("OSArray"); // no warning + return a->getCount(); +} + +unsigned warn_alloc_class_with_name() { + OSArray *a = (OSArray *)OSMetaClass::allocClassWithName("OSObject"); // expected-warning{{C-style cast of an OSObject is prone to type confusion attacks; use 'OSRequiredCast' if the object is definitely of type 'OSArray', or 'OSDynamicCast' followed by a null check if unsure}} + return a->getCount(); +} diff --git a/clang/test/Analysis/out-of-bounds-false-positive.c b/clang/test/Analysis/out-of-bounds-false-positive.c new file mode 100644 index 000000000000..3e8071449250 --- /dev/null +++ b/clang/test/Analysis/out-of-bounds-false-positive.c @@ -0,0 +1,101 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection \ +// RUN: -analyzer-config eagerly-assume=false -verify %s + +void clang_analyzer_eval(int); +void clang_analyzer_printState(); + +typedef unsigned long long size_t; +const char a[] = "abcd"; // extent: 5 bytes + +void symbolic_size_t_and_int0(size_t len) { + // FIXME: Should not warn for this. + (void)a[len + 1]; // expected-warning {{Out of bound memory access}} + // We infered that the 'len' must be in a specific range to make the previous indexing valid. + // len: [0,3] + clang_analyzer_eval(len <= 3); // expected - warning {{TRUE}} + clang_analyzer_eval(len <= 2); // expected - warning {{UNKNOWN}} +} + +void symbolic_size_t_and_int1(size_t len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} + +void symbolic_size_t_and_int2(size_t len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} + +void symbolic_uint_and_int0(unsigned len) { + (void)a[len + 1]; // no-warning + // len: [0,3] + clang_analyzer_eval(0 <= len && len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} +} + +void symbolic_uint_and_int1(unsigned len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} +void symbolic_uint_and_int2(unsigned len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} + +void symbolic_int_and_int0(int len) { + (void)a[len + 1]; // no-warning + // len: [-1,3] + clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} +} +void symbolic_int_and_int1(int len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} +void symbolic_int_and_int2(int len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} + +void symbolic_longlong_and_int0(long long len) { + (void)a[len + 1]; // no-warning + // len: [-1,3] + clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} +} + +void symbolic_longlong_and_int1(long long len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} + +void symbolic_longlong_and_int2(long long len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} diff --git a/clang/test/Analysis/pthreadlock_state.c b/clang/test/Analysis/pthreadlock_state.c new file mode 100644 index 000000000000..f6b26e4071b9 --- /dev/null +++ b/clang/test/Analysis/pthreadlock_state.c @@ -0,0 +1,60 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.PthreadLock,debug.ExprInspection 2>&1 %s | FileCheck %s + +#include "Inputs/system-header-simulator-for-pthread-lock.h" + +#define NULL 0 + +void clang_analyzer_printState(); + +pthread_mutex_t mtx; + +void test() { + clang_analyzer_printState(); + // CHECK: "checker_messages": null + + pthread_mutex_init(&mtx, NULL); + clang_analyzer_printState(); + // CHECK: { "checker": "alpha.core.PthreadLockBase", "messages": [ + // CHECK-NEXT: "Mutex states:", + // CHECK-NEXT: "mtx: unlocked", + // CHECK-NEXT: "" + // CHECK-NEXT: ]} + + pthread_mutex_lock(&mtx); + clang_analyzer_printState(); + // CHECK: { "checker": "alpha.core.PthreadLockBase", "messages": [ + // CHECK-NEXT: "Mutex states:", + // CHECK-NEXT: "mtx: locked", + // CHECK-NEXT: "Mutex lock order:", + // CHECK-NEXT: "mtx", + // CHECK-NEXT: "" + // CHECK-NEXT: ]} + + pthread_mutex_unlock(&mtx); + clang_analyzer_printState(); + // CHECK: { "checker": "alpha.core.PthreadLockBase", "messages": [ + // CHECK-NEXT: "Mutex states:", + // CHECK-NEXT: "mtx: unlocked", + // CHECK-NEXT: "" + // CHECK-NEXT: ]} + + int ret = pthread_mutex_destroy(&mtx); + clang_analyzer_printState(); + // CHECK: { "checker": "alpha.core.PthreadLockBase", "messages": [ + // CHECK-NEXT: "Mutex states:", + // CHECK-NEXT: "mtx: unlocked, possibly destroyed", + // CHECK-NEXT: "Mutexes in unresolved possibly destroyed state:", + // CHECK-NEXT: "mtx: conj_$ + // CHECK-NEXT: "" + // CHECK-NEXT: ]} + + if (ret) + return; + + clang_analyzer_printState(); + // CHECK: { "checker": "alpha.core.PthreadLockBase", "messages": [ + // CHECK-NEXT: "Mutex states:", + // CHECK-NEXT: "mtx: destroyed", + // CHECK-NEXT: "" + // CHECK-NEXT: ]} +} diff --git a/clang/test/Analysis/pthreadlock_state_nottracked.c b/clang/test/Analysis/pthreadlock_state_nottracked.c new file mode 100644 index 000000000000..e6281372e214 --- /dev/null +++ b/clang/test/Analysis/pthreadlock_state_nottracked.c @@ -0,0 +1,22 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.PthreadLock,debug.ExprInspection 2>&1 %s | FileCheck %s + +#include "Inputs/system-header-simulator-for-pthread-lock.h" + +#define NULL 0 + +void clang_analyzer_printState(); + +void test(pthread_mutex_t *mtx) { + int ret = pthread_mutex_destroy(mtx); + clang_analyzer_printState(); + // CHECK: { "checker": "alpha.core.PthreadLockBase", "messages": [ + // CHECK-NEXT: "Mutex states:", + // CHECK-NEXT: "SymRegion{reg_$[[REG:[0-9]+]]}: not tracked, possibly destroyed", + // CHECK-NEXT: "Mutexes in unresolved possibly destroyed state:", + // CHECK-NEXT: "SymRegion{reg_$[[REG]]}: conj_$ + // CHECK-NEXT: "" + // CHECK-NEXT: ]} + if (ret) + return; + pthread_mutex_init(mtx, NULL); +} diff --git a/clang/test/Analysis/zero-operands.c b/clang/test/Analysis/zero-operands.c new file mode 100644 index 000000000000..3311c524f814 --- /dev/null +++ b/clang/test/Analysis/zero-operands.c @@ -0,0 +1,53 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core \ +// RUN: -analyzer-checker=debug.ExprInspection \ +// RUN: -verify %s + +void clang_analyzer_dump(int); + +void test_0_multiplier1(int x, int y) { + int a = x < 0; // Eagerly bifurcate. + clang_analyzer_dump(a); + // expected-warning@-1{{0 S32b}} + // expected-warning@-2{{1 S32b}} + + int b = a * y; + clang_analyzer_dump(b); + // expected-warning@-1{{0 S32b}} + // expected-warning-re@-2{{reg_${{[[:digit:]]+}}}} +} + +void test_0_multiplier2(int x, int y) { + int a = x < 0; // Eagerly bifurcate. + clang_analyzer_dump(a); + // expected-warning@-1{{0 S32b}} + // expected-warning@-2{{1 S32b}} + + int b = y * a; + clang_analyzer_dump(b); + // expected-warning@-1{{0 S32b}} + // expected-warning-re@-2{{reg_${{[[:digit:]]+}}}} +} + +void test_0_modulo(int x, int y) { + int a = x < 0; // Eagerly bifurcate. + clang_analyzer_dump(a); + // expected-warning@-1{{0 S32b}} + // expected-warning@-2{{1 S32b}} + + int b = a % y; + clang_analyzer_dump(b); + // expected-warning@-1{{0 S32b}} + // expected-warning-re@-2{{1 % (reg_${{[[:digit:]]+}})}} +} + +void test_0_divisible(int x, int y) { + int a = x < 0; // Eagerly bifurcate. + clang_analyzer_dump(a); + // expected-warning@-1{{0 S32b}} + // expected-warning@-2{{1 S32b}} + + int b = a / y; + clang_analyzer_dump(b); + // expected-warning@-1{{0 S32b}} + // expected-warning-re@-2{{1 / (reg_${{[[:digit:]]+}})}} +} diff --git a/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp index 1a0ccc91741b..dd622988d458 100644 --- a/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp +++ b/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp @@ -127,7 +127,7 @@ namespace P1946 { friend bool operator==(A &, A &); // expected-note {{would lose const qualifier}} }; struct B { - A a; // expected-note {{no viable comparison}} + A a; // expected-note {{no viable three-way comparison}} friend bool operator==(B, B) = default; // ok friend bool operator==(const B&, const B&) = default; // expected-warning {{deleted}} }; diff --git a/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp index 226245ce8a44..a1653d85abbf 100644 --- a/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp +++ b/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp @@ -44,7 +44,7 @@ struct A3 { bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}} bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}} - // expected-note@-1 {{because there is no viable comparison function}} + // expected-note@-1 {{because there is no viable three-way comparison function for 'A3'}} }; struct B1 { diff --git a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp index 8c303c63d899..02adf3d51ded 100644 --- a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp +++ b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp @@ -99,7 +99,7 @@ namespace DeleteAfterFirstDecl { struct Q { struct X { friend std::strong_ordering operator<=>(const X&, const X&); - } x; // expected-note {{no viable comparison}} + } x; // expected-note {{no viable three-way comparison}} // expected-error@+1 {{defaulting the corresponding implicit 'operator==' for this defaulted 'operator<=>' would delete it after its first declaration}} friend std::strong_ordering operator<=>(const Q&, const Q&) = default; }; diff --git a/clang/test/CXX/class/class.compare/class.eq/p2.cpp b/clang/test/CXX/class/class.compare/class.eq/p2.cpp index 7e9416574eee..44da9191dc0e 100644 --- a/clang/test/CXX/class/class.compare/class.eq/p2.cpp +++ b/clang/test/CXX/class/class.compare/class.eq/p2.cpp @@ -18,26 +18,26 @@ struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here struct H1 { bool operator==(const H1 &) const = default; bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}} - // expected-note@-1 {{because there is no viable comparison function}} + // expected-note@-1 {{because there is no viable three-way comparison function for 'H1'}} void (*x)(); }; struct H2 { bool operator==(const H2 &) const = default; bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}} - // expected-note@-1 {{because there is no viable comparison function}} + // expected-note@-1 {{because there is no viable three-way comparison function for 'H2'}} void (H2::*x)(); }; struct H3 { bool operator==(const H3 &) const = default; bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}} - // expected-note@-1 {{because there is no viable comparison function}} + // expected-note@-1 {{because there is no viable three-way comparison function for 'H3'}} int H3::*x; }; template struct X { X(); bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}} - T t; // expected-note 3{{because there is no viable comparison function for member 't'}} + T t; // expected-note 3{{because there is no viable three-way comparison function for member 't'}} // expected-note@-1 {{because it would invoke a deleted comparison function for member 't'}} }; diff --git a/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp b/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp index 7768e84323d0..b951ed2dabd9 100644 --- a/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp +++ b/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp @@ -78,9 +78,9 @@ namespace Deletedness { }; // expected-note@#base {{deleted comparison function for base class 'C'}} - // expected-note@#base {{no viable comparison function for base class 'D1'}} + // expected-note@#base {{no viable three-way comparison function for base class 'D1'}} // expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}} - // expected-note@#base {{no viable comparison function for base class 'D2'}} + // expected-note@#base {{no viable three-way comparison function for base class 'D2'}} // expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}} // expected-note@#base {{deleted comparison function for base class 'E'}} // expected-note@#base {{implied comparison for base class 'F' is ambiguous}} @@ -110,9 +110,9 @@ namespace Deletedness { } // expected-note@#arr {{deleted comparison function for member 'arr'}} - // expected-note@#arr {{no viable comparison function for member 'arr'}} + // expected-note@#arr {{no viable three-way comparison function for member 'arr'}} // expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}} - // expected-note@#arr {{no viable comparison function for member 'arr'}} + // expected-note@#arr {{no viable three-way comparison function for member 'arr'}} // expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}} // expected-note@#arr {{deleted comparison function for member 'arr'}} // expected-note@#arr {{implied comparison for member 'arr' is ambiguous}} diff --git a/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp b/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp index d7f95ee4a6fd..06126a48acf1 100644 --- a/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp +++ b/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp @@ -52,7 +52,7 @@ namespace DeducedVsSynthesized { bool operator<(const A&) const; }; struct B { - A a; // expected-note {{no viable comparison function for member 'a'}} + A a; // expected-note {{no viable three-way comparison function for member 'a'}} auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}} }; } @@ -159,16 +159,16 @@ namespace BadDeducedType { namespace PR48856 { struct A { auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}} - void (*x)(); // expected-note {{because there is no viable comparison function for member 'x'}} + void (*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}} }; struct B { auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}} - void (B::*x)(); // expected-note {{because there is no viable comparison function for member 'x'}} + void (B::*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}} }; struct C { auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}} - int C::*x; // expected-note {{because there is no viable comparison function for member 'x'}} + int C::*x; // expected-note {{because there is no viable three-way comparison function for member 'x'}} }; } diff --git a/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp b/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp index 29d818602537..e4056221b4f3 100644 --- a/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp +++ b/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp @@ -292,3 +292,108 @@ NeedValue test_4_3() { return b; // cxx20-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::B2'}} } } // namespace test_ctor_param_rvalue_ref + +namespace test_lvalue_ref_is_not_moved_from { + +struct Target {}; + // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable}} + // expected-note@-2 {{candidate constructor (the implicit move constructor) not viable}} + // cxx11_14_17-note@-3 {{candidate constructor (the implicit copy constructor) not viable}} + // cxx11_14_17-note@-4 {{candidate constructor (the implicit move constructor) not viable}} + +struct CopyOnly { + CopyOnly(CopyOnly&&) = delete; // cxx20-note {{has been explicitly marked deleted here}} + CopyOnly(CopyOnly&); + operator Target() && = delete; // cxx20-note {{has been explicitly marked deleted here}} + operator Target() &; +}; + +struct MoveOnly { + MoveOnly(MoveOnly&&); // expected-note {{copy constructor is implicitly deleted because}} + // cxx11_14_17-note@-1 {{copy constructor is implicitly deleted because}} + operator Target() &&; // expected-note {{candidate function not viable}} + // cxx11_14_17-note@-1 {{candidate function not viable}} +}; + +extern CopyOnly copyonly; +extern MoveOnly moveonly; + +CopyOnly t1() { + CopyOnly& r = copyonly; + return r; +} + +CopyOnly t2() { + CopyOnly&& r = static_cast(copyonly); + return r; // cxx20-error {{call to deleted constructor}} +} + +MoveOnly t3() { + MoveOnly& r = moveonly; + return r; // expected-error {{call to implicitly-deleted copy constructor}} +} + +MoveOnly t4() { + MoveOnly&& r = static_cast(moveonly); + return r; // cxx11_14_17-error {{call to implicitly-deleted copy constructor}} +} + +Target t5() { + CopyOnly& r = copyonly; + return r; +} + +Target t6() { + CopyOnly&& r = static_cast(copyonly); + return r; // cxx20-error {{invokes a deleted function}} +} + +Target t7() { + MoveOnly& r = moveonly; + return r; // expected-error {{no viable conversion}} +} + +Target t8() { + MoveOnly&& r = static_cast(moveonly); + return r; // cxx11_14_17-error {{no viable conversion}} +} + +} // namespace test_lvalue_ref_is_not_moved_from + +namespace test_rvalue_ref_to_nonobject { + +struct CopyOnly {}; +struct MoveOnly {}; + +struct Target { + Target(CopyOnly (&)()); + Target(CopyOnly (&&)()) = delete; + Target(MoveOnly (&)()) = delete; // expected-note {{has been explicitly marked deleted here}} + // expected-note@-1 {{has been explicitly marked deleted here}} + Target(MoveOnly (&&)()); +}; + +CopyOnly make_copyonly(); +MoveOnly make_moveonly(); + +Target t1() { + CopyOnly (&r)() = make_copyonly; + return r; +} + +Target t2() { + CopyOnly (&&r)() = static_cast(make_copyonly); + return r; // OK in all modes; not subject to implicit move +} + +Target t3() { + MoveOnly (&r)() = make_moveonly; + return r; // expected-error {{invokes a deleted function}} +} + +Target t4() { + MoveOnly (&&r)() = static_cast(make_moveonly); + return r; // expected-error {{invokes a deleted function}} +} + +} // namespace test_rvalue_ref_to_nonobject diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp index f267d9067bcc..22815bbde9db 100644 --- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp @@ -53,7 +53,7 @@ class [[fallthrough]] C {}; // expected-error {{'fallthrough' attribute cannot b [[fallthrough]] // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} void g() { [[fallthrough]] int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} - [[fallthrough]] ++n; // expected-error-re {{{{^}}fallthrough attribute is only allowed on empty statements}} + [[fallthrough]] ++n; // expected-error {{'fallthrough' attribute only applies to empty statements}} switch (n) { // FIXME: This should be an error. diff --git a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp index 44539bd125ff..7830d1f43526 100644 --- a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp +++ b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp @@ -68,3 +68,11 @@ namespace PR48384 { True decltype(auto) h = (b); static_assert(is_same_v); } + +namespace PR48593 { + template concept a = true; + a auto c = 0; // expected-error{{use of undeclared identifier 'B'}} + + template concept d = true; + d<,> auto e = 0; // expected-error{{expected expression}} +} diff --git a/clang/test/CXX/drs/dr6xx.cpp b/clang/test/CXX/drs/dr6xx.cpp index a34cf0a2e01f..1ec723b04b9a 100644 --- a/clang/test/CXX/drs/dr6xx.cpp +++ b/clang/test/CXX/drs/dr6xx.cpp @@ -1153,7 +1153,7 @@ namespace dr696 { // dr696: yes }; #if __cplusplus >= 201103L (void) [] { int arr[N]; (void)arr; }; - (void) [] { f(&N); }; // expected-error {{cannot be implicitly captured}} expected-note {{here}} + (void)[] { f(&N); }; // expected-error {{cannot be implicitly captured}} expected-note {{here}} expected-note 2 {{capture 'N' by}} expected-note 2 {{default capture by}} #endif } } diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp index e7fce11abc5e..b69bc939c39d 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp @@ -42,7 +42,7 @@ void immediately_enclosing(int i) { // expected-note{{'i' declared here}} [i] {}(); }(); - []() { // expected-note{{lambda expression begins here}} + []() { // expected-note{{lambda expression begins here}} expected-note 2 {{capture 'i' by}} expected-note 2 {{default capture by}} [i] {}(); // expected-error{{variable 'i' cannot be implicitly captured in a lambda with no capture-default specified}} }(); } @@ -64,7 +64,7 @@ void f1(int i) { // expected-note{{declared here}} void work(int n) { // expected-note{{declared here}} int m = n*n; int j = 40; // expected-note{{declared here}} - auto m3 = [this,m] { // expected-note 3{{lambda expression begins here}} + auto m3 = [this, m] { // expected-note 3{{lambda expression begins here}} expected-note 2 {{capture 'i' by}} expected-note 2 {{capture 'j' by}} expected-note 2 {{capture 'n' by}} auto m4 = [&,j] { // expected-error{{variable 'j' cannot be implicitly captured in a lambda with no capture-default specified}} int x = n; // expected-error{{variable 'n' cannot be implicitly captured in a lambda with no capture-default specified}} x += m; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp index d791ed60cfca..3112bc726818 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp @@ -19,7 +19,9 @@ void unevaluated_operand(P &p, int i) { //expected-note{{declared here}} int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); // expected-error{{lambda expression in an unevaluated operand}} \ // expected-error{{invalid application of 'sizeof'}} const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p; return p; }(i)); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} - const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i)); // expected-error{{lambda expression in an unevaluated operand}}\ + const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i)); // expected-error{{lambda expression in an unevaluated operand}}\ // expected-error{{cannot be implicitly captured}}\ - // expected-note{{begins here}} + // expected-note{{begins here}}\ + // expected-note 2 {{capture 'i' by}}\ + // expected-note 2 {{default capture by}} } diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp index f8461335b768..f2b0e26e29f9 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp @@ -52,7 +52,10 @@ int test_no_parameter_list() { static int si = 0; auto M = [] { return 5; }; // OK - auto M2 = [] -> auto&& { return si; }; // expected-error{{lambda requires '()'}} + auto M2 = [] -> auto && { return si; }; +#if __cplusplus <= 202002L + // expected-warning@-2{{is a C++2b extension}} +#endif M(); } diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp index 19b794ba29ad..b7366207882f 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp @@ -79,19 +79,23 @@ constexpr bool is_same_v = false; template constexpr bool is_same_v = true; +template struct remove_reference { using type = T; }; +template struct remove_reference { using type = T; }; + template concept Same = is_same_v; template -concept Large = sizeof(T) >= 4; // expected-note{{because 'sizeof(short) >= 4' (2 >= 4) evaluated to false}} +concept Large = sizeof(typename remove_reference::type) >= 4; +// expected-note@-1{{because 'sizeof(typename remove_reference::type) >= 4' (2 >= 4) evaluated to false}} -template requires requires (T t) { { t } -> Large; } // expected-note{{because 'decltype(t)' (aka 'short') does not satisfy 'Large':}} +template requires requires (T t) { { t } -> Large; } // expected-note{{because 'short &' does not satisfy 'Large':}} struct r7 {}; using r7i1 = r7; using r7i2 = r7; // expected-error{{constraints not satisfied for class template 'r7' [with T = short]}} -template requires requires (T t) { { t } -> Same; } +template requires requires (T t) { { t } -> Same; } struct r8 {}; using r8i1 = r8; @@ -99,7 +103,8 @@ using r8i2 = r8; // Substitution failure in type constraint -template requires requires (T t) { { t } -> Same; } // expected-note{{because 'Same' would be invalid: type 'int' cannot be used prior to '::' because it has no members}} +template requires requires (T t) { { t } -> Same; } +// expected-note@-1{{because 'Same' would be invalid: type 'int' cannot be used prior to '::' because it has no members}} struct r9 {}; struct M { using type = M; }; @@ -122,6 +127,17 @@ concept IsEven = (T % 2) == 0; template requires requires (T t) { { t } -> IsEven; } // expected-error{{concept named in type constraint is not a type concept}} struct r11 {}; +// Value categories + +template +requires requires (int b) { + { a } -> Same; + { b } -> Same; + { 0 } -> Same; + { static_cast(a) } -> Same; +} void f1() {} +template void f1<>(); + // C++ [expr.prim.req.compound] Example namespace std_example { template concept C1 = @@ -172,4 +188,4 @@ namespace std_example { static_assert(C5); template struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}} using c5 = C5_check; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}} -} \ No newline at end of file +} diff --git a/clang/test/CodeCompletion/desig-init.cpp b/clang/test/CodeCompletion/desig-init.cpp index 8a66f4554217..999f368ba563 100644 --- a/clang/test/CodeCompletion/desig-init.cpp +++ b/clang/test/CodeCompletion/desig-init.cpp @@ -62,3 +62,18 @@ void aux() { Test X{.x = T(2)}; // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:62:14 %s -o - -std=c++2a | FileCheck -check-prefix=CHECK-CC3 %s } + +namespace signature_regression { + // Verify that an old bug is gone: passing an init-list as a constructor arg + // would emit overloads as a side-effect. + struct S{int x;}; + int wrongFunction(S); + int rightFunction(); + int dummy = wrongFunction({1}); + int x = rightFunction(); + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:73:25 %s -o - -std=c++2a | FileCheck -check-prefix=CHECK-SIGNATURE-REGRESSION %s + // CHECK-SIGNATURE-REGRESSION-NOT: OVERLOAD: [#int#]wrongFunction + // CHECK-SIGNATURE-REGRESSION: OVERLOAD: [#int#]rightFunction + // CHECK-SIGNATURE-REGRESSION-NOT: OVERLOAD: [#int#]wrongFunction +} + diff --git a/clang/test/CodeGen/PR5060-align.c b/clang/test/CodeGen/PR5060-align.c index 34293a933aa9..6e65175a7115 100644 --- a/clang/test/CodeGen/PR5060-align.c +++ b/clang/test/CodeGen/PR5060-align.c @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -// CHECK: @foo.p = internal global i8 0, align 32 +// CHECK: @foo.p = internal global i8 0, align 16 char *foo(void) { - static char p __attribute__((aligned(32))); + static char p __attribute__((aligned(16))); return &p; } void bar(long n) { - // CHECK: align 32 - char p[n] __attribute__((aligned(32))); + // CHECK: align 16 + char p[n] __attribute__((aligned(16))); } diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c b/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c new file mode 100644 index 000000000000..14558778278e --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-v \ +// RUN: -O2 -emit-llvm %s -o - \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-v \ +// RUN: -O2 -emit-llvm %s -o - \ +// RUN: | FileCheck %s + +// Test RISC-V V-extension specific inline assembly constraints. +#include + +void test_v_reg() { + asm volatile( + "vsetvli x1, x0, e32,m2,tu,mu\n" + "vadd.vv v1, v2, v3, v0.t" + : + : + : "v1", "x1"); +// CHECK-LABEL: define{{.*}} @test_v_reg +// CHECK: "~{v1},~{x1}" +} + +vint32m1_t test_vr(vint32m1_t a, vint32m1_t b) { +// CHECK-LABEL: define{{.*}} @test_vr +// CHECK: %0 = tail call asm sideeffect "vadd.vv $0, $1, $2", "=v,v,v"( %a, %b) + vint32m1_t ret; + asm volatile ("vadd.vv %0, %1, %2" : "=vr"(ret) : "vr"(a), "vr"(b)); + return ret; +} + +vbool1_t test_vm(vbool1_t a, vbool1_t b) { +// CHECK-LABEL: define{{.*}} @test_vm +// CHECK: %0 = tail call asm sideeffect "vmand.mm $0, $1, $2", "=v,v,v"( %a, %b) + vbool1_t ret; + asm volatile ("vmand.mm %0, %1, %2" : "=vm"(ret) : "vm"(a), "vm"(b)); + return ret; +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c new file mode 100644 index 000000000000..fc783e7bdac7 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c @@ -0,0 +1,2476 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vv_i8mf8(vint8mf8_t op1, vint8mf8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vx_i8mf8(vint8mf8_t op1, int8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vv_i8mf4(vint8mf4_t op1, vint8mf4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vx_i8mf4(vint8mf4_t op1, int8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vv_i8mf2(vint8mf2_t op1, vint8mf2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vx_i8mf2(vint8mf2_t op1, int8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vv_i8m1(vint8m1_t op1, vint8m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vx_i8m1(vint8m1_t op1, int8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vv_i8m2(vint8m2_t op1, vint8m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vx_i8m2(vint8m2_t op1, int8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vv_i8m4(vint8m4_t op1, vint8m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vx_i8m4(vint8m4_t op1, int8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vv_i8m8(vint8m8_t op1, vint8m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vx_i8m8(vint8m8_t op1, int8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vv_i16mf4(vint16mf4_t op1, vint16mf4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vx_i16mf4(vint16mf4_t op1, int16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vv_i16mf2(vint16mf2_t op1, vint16mf2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vx_i16mf2(vint16mf2_t op1, int16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vv_i16m1(vint16m1_t op1, vint16m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vx_i16m1(vint16m1_t op1, int16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vv_i16m2(vint16m2_t op1, vint16m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vx_i16m2(vint16m2_t op1, int16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vv_i16m4(vint16m4_t op1, vint16m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vx_i16m4(vint16m4_t op1, int16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vv_i16m8(vint16m8_t op1, vint16m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vx_i16m8(vint16m8_t op1, int16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vv_i32mf2(vint32mf2_t op1, vint32mf2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vx_i32mf2(vint32mf2_t op1, int32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vv_i32m1(vint32m1_t op1, vint32m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vx_i32m1(vint32m1_t op1, int32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vv_i32m2(vint32m2_t op1, vint32m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vx_i32m2(vint32m2_t op1, int32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vv_i32m4(vint32m4_t op1, vint32m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vx_i32m4(vint32m4_t op1, int32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vv_i32m8(vint32m8_t op1, vint32m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vx_i32m8(vint32m8_t op1, int32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vv_i64m1(vint64m1_t op1, vint64m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vx_i64m1(vint64m1_t op1, int64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vv_i64m2(vint64m2_t op1, vint64m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vx_i64m2(vint64m2_t op1, int64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vv_i64m4(vint64m4_t op1, vint64m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vx_i64m4(vint64m4_t op1, int64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vv_i64m8(vint64m8_t op1, vint64m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vx_i64m8(vint64m8_t op1, int64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vv_u8mf8(vuint8mf8_t op1, vuint8mf8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vx_u8mf8(vuint8mf8_t op1, uint8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vv_u8mf4(vuint8mf4_t op1, vuint8mf4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vx_u8mf4(vuint8mf4_t op1, uint8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vv_u8mf2(vuint8mf2_t op1, vuint8mf2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vx_u8mf2(vuint8mf2_t op1, uint8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vv_u8m1(vuint8m1_t op1, vuint8m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vx_u8m1(vuint8m1_t op1, uint8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vv_u8m2(vuint8m2_t op1, vuint8m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vx_u8m2(vuint8m2_t op1, uint8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vv_u8m4(vuint8m4_t op1, vuint8m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vx_u8m4(vuint8m4_t op1, uint8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vv_u8m8(vuint8m8_t op1, vuint8m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vx_u8m8(vuint8m8_t op1, uint8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vv_u16mf4(vuint16mf4_t op1, vuint16mf4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vx_u16mf4(vuint16mf4_t op1, uint16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vv_u16mf2(vuint16mf2_t op1, vuint16mf2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vx_u16mf2(vuint16mf2_t op1, uint16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vv_u16m1(vuint16m1_t op1, vuint16m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vx_u16m1(vuint16m1_t op1, uint16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vv_u16m2(vuint16m2_t op1, vuint16m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vx_u16m2(vuint16m2_t op1, uint16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vv_u16m4(vuint16m4_t op1, vuint16m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vx_u16m4(vuint16m4_t op1, uint16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vv_u16m8(vuint16m8_t op1, vuint16m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vx_u16m8(vuint16m8_t op1, uint16_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vv_u32mf2(vuint32mf2_t op1, vuint32mf2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vx_u32mf2(vuint32mf2_t op1, uint32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vv_u32m1(vuint32m1_t op1, vuint32m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vx_u32m1(vuint32m1_t op1, uint32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vv_u32m2(vuint32m2_t op1, vuint32m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vx_u32m2(vuint32m2_t op1, uint32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vv_u32m4(vuint32m4_t op1, vuint32m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vx_u32m4(vuint32m4_t op1, uint32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vv_u32m8(vuint32m8_t op1, vuint32m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vx_u32m8(vuint32m8_t op1, uint32_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vv_u64m1(vuint64m1_t op1, vuint64m1_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vx_u64m1(vuint64m1_t op1, uint64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vv_u64m2(vuint64m2_t op1, vuint64m2_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vx_u64m2(vuint64m2_t op1, uint64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vv_u64m4(vuint64m4_t op1, vuint64m4_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vx_u64m4(vuint64m4_t op1, uint64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vv_u64m8(vuint64m8_t op1, vuint64m8_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vx_u64m8(vuint64m8_t op1, uint64_t op2, size_t vl) { + return vadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vv_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, vint8mf8_t op1, vint8mf8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vx_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, vint8mf8_t op1, int8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vv_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, vint8mf4_t op1, vint8mf4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vx_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, vint8mf4_t op1, int8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vv_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, vint8mf2_t op1, vint8mf2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vx_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, vint8mf2_t op1, int8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vv_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, vint8m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vx_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, int8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vv_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, vint8m2_t op1, vint8m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vx_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, vint8m2_t op1, int8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vv_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, vint8m4_t op1, vint8m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vx_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, vint8m4_t op1, int8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vv_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, vint8m8_t op1, vint8m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vx_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, vint8m8_t op1, int8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vv_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, vint16mf4_t op1, vint16mf4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vx_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, vint16mf4_t op1, int16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vv_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, vint16mf2_t op1, vint16mf2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vx_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, vint16mf2_t op1, int16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vv_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, vint16m1_t op1, vint16m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vx_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, vint16m1_t op1, int16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vv_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, vint16m2_t op1, vint16m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vx_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, vint16m2_t op1, int16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vv_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, vint16m4_t op1, vint16m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vx_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, vint16m4_t op1, int16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vv_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, vint16m8_t op1, vint16m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vx_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, vint16m8_t op1, int16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vv_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, vint32mf2_t op1, vint32mf2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vx_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, vint32mf2_t op1, int32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vv_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, vint32m1_t op1, vint32m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vx_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, vint32m1_t op1, int32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vv_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, vint32m2_t op1, vint32m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vx_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, vint32m2_t op1, int32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vv_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, vint32m4_t op1, vint32m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vx_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, vint32m4_t op1, int32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vv_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, vint32m8_t op1, vint32m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vx_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, vint32m8_t op1, int32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vv_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, vint64m1_t op1, vint64m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vx_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, vint64m1_t op1, int64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vv_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, vint64m2_t op1, vint64m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vx_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, vint64m2_t op1, int64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vv_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, vint64m4_t op1, vint64m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vx_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, vint64m4_t op1, int64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vv_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, vint64m8_t op1, vint64m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vx_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, vint64m8_t op1, int64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vv_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t op1, vuint8mf8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vx_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t op1, uint8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vv_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t op1, vuint8mf4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vx_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t op1, uint8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vv_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t op1, vuint8mf2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vx_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t op1, uint8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vv_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t op1, vuint8m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vx_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t op1, uint8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vv_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t op1, vuint8m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vx_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t op1, uint8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vv_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t op1, vuint8m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vx_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t op1, uint8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vv_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t op1, vuint8m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vx_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t op1, uint8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vv_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t op1, vuint16mf4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vx_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t op1, uint16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vv_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t op1, vuint16mf2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vx_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t op1, uint16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vv_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t op1, vuint16m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vx_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t op1, uint16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vv_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t op1, vuint16m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vx_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t op1, uint16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vv_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t op1, vuint16m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vx_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t op1, uint16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vv_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t op1, vuint16m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vx_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t op1, uint16_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vv_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t op1, vuint32mf2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vx_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t op1, uint32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vv_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t op1, vuint32m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vx_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t op1, uint32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vv_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t op1, vuint32m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vx_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t op1, uint32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vv_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t op1, vuint32m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vx_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t op1, uint32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vv_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t op1, vuint32m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vx_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t op1, uint32_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vv_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t op1, vuint64m1_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vx_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t op1, uint64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vv_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t op1, vuint64m2_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vx_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t op1, uint64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vv_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t op1, vuint64m4_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vx_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t op1, uint64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vv_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t op1, vuint64m8_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vx_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t op1, uint64_t op2, size_t vl) { + return vadd(mask, maskedoff, op1, op2, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vfadd.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vfadd.c new file mode 100644 index 000000000000..25fc2fe4e101 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vfadd.c @@ -0,0 +1,516 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.nxv1f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6:#.*]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.nxv1f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6:#.*]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vv_f32mf2(vfloat32mf2_t op1, vfloat32mf2_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vf_f32mf2(vfloat32mf2_t op1, float op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.nxv2f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.nxv2f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vv_f32m1(vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vf_f32m1(vfloat32m1_t op1, float op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.nxv4f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.nxv4f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vv_f32m2(vfloat32m2_t op1, vfloat32m2_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vf_f32m2(vfloat32m2_t op1, float op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.nxv8f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.nxv8f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vv_f32m4(vfloat32m4_t op1, vfloat32m4_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vf_f32m4(vfloat32m4_t op1, float op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.nxv16f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.nxv16f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vv_f32m8(vfloat32m8_t op1, vfloat32m8_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vf_f32m8(vfloat32m8_t op1, float op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.nxv1f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.nxv1f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vv_f64m1(vfloat64m1_t op1, vfloat64m1_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vf_f64m1(vfloat64m1_t op1, double op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.nxv2f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.nxv2f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vv_f64m2(vfloat64m2_t op1, vfloat64m2_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vf_f64m2(vfloat64m2_t op1, double op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.nxv4f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.nxv4f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vv_f64m4(vfloat64m4_t op1, vfloat64m4_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vf_f64m4(vfloat64m4_t op1, double op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.nxv8f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.nxv8f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vv_f64m8(vfloat64m8_t op1, vfloat64m8_t op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vf_f64m8(vfloat64m8_t op1, double op2, size_t vl) { + return vfadd(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.nxv1f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.nxv1f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vv_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat32mf2_t op1, vfloat32mf2_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vf_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat32mf2_t op1, float op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.nxv2f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.nxv2f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vv_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vf_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, vfloat32m1_t op1, float op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.nxv4f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.nxv4f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vv_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, vfloat32m2_t op1, vfloat32m2_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vf_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, vfloat32m2_t op1, float op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.nxv8f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.nxv8f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vv_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, vfloat32m4_t op1, vfloat32m4_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vf_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, vfloat32m4_t op1, float op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.nxv16f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.nxv16f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vv_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, vfloat32m8_t op1, vfloat32m8_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vf_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, vfloat32m8_t op1, float op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.nxv1f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.nxv1f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vv_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, vfloat64m1_t op1, vfloat64m1_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vf_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, vfloat64m1_t op1, double op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.nxv2f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.nxv2f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vv_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, vfloat64m2_t op1, vfloat64m2_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vf_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, vfloat64m2_t op1, double op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.nxv4f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.nxv4f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vv_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, vfloat64m4_t op1, vfloat64m4_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vf_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, vfloat64m4_t op1, double op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.nxv8f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.nxv8f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vv_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, vfloat64m8_t op1, vfloat64m8_t op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR6]] +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vf_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, vfloat64m8_t op1, double op2, size_t vl) { + return vfadd(mask, maskedoff, op1, op2, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vle.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vle.c new file mode 100644 index 000000000000..0b313a0f5c30 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vle.c @@ -0,0 +1,859 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vle8_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vle8_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vle8_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vle8_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vle8_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vle8_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t test_vle8_v_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, const int8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vle16_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vle16_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vle16_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vle16_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vle16_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vle16_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vle32_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vle32_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vle32_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vle32_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vle32_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vle64_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vle64_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vle64_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vle64_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vle8_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vle8_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vle8_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vle8_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vle8_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vle8_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t test_vle8_v_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, const uint8_t *base, size_t vl) { + return vle8(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vle16_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vle16_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vle16_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vle16_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vle16_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vle16_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, size_t vl) { + return vle16(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vle32_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vle32_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vle32_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vle32_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vle32_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vle64_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vle64_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vle64_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vle64_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vle32_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vle32_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vle32_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vle32_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vle32_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, size_t vl) { + return vle32(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vle64_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vle64_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vle64_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vle64_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, size_t vl) { + return vle64(mask, maskedoff, base, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vloxei.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vloxei.c new file mode 100644 index 000000000000..5652eda62b25 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vloxei.c @@ -0,0 +1,6125 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei8_v_i8mf8(const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei8_v_i8mf4(const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei8_v_i8mf2(const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei8_v_i8m1(const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vloxei8_v_i8m2(const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vloxei8_v_i8m4(const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t test_vloxei8_v_i8m8(const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei16_v_i8mf8(const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei16_v_i8mf4(const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei16_v_i8mf2(const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei16_v_i8m1(const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vloxei16_v_i8m2(const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vloxei16_v_i8m4(const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei32_v_i8mf8(const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei32_v_i8mf4(const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei32_v_i8mf2(const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei32_v_i8m1(const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vloxei32_v_i8m2(const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei64_v_i8mf8(const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei64_v_i8mf4(const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei64_v_i8mf2(const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei64_v_i8m1(const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei8_v_i16mf4(const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei8_v_i16mf2(const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei8_v_i16m1(const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei8_v_i16m2(const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vloxei8_v_i16m4(const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vloxei8_v_i16m8(const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei16_v_i16mf4(const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei16_v_i16mf2(const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei16_v_i16m1(const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei16_v_i16m2(const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vloxei16_v_i16m4(const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vloxei16_v_i16m8(const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei32_v_i16mf4(const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei32_v_i16mf2(const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei32_v_i16m1(const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei32_v_i16m2(const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vloxei32_v_i16m4(const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei64_v_i16mf4(const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei64_v_i16mf2(const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei64_v_i16m1(const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei64_v_i16m2(const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei8_v_i32mf2(const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei8_v_i32m1(const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei8_v_i32m2(const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei8_v_i32m4(const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vloxei8_v_i32m8(const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei16_v_i32mf2(const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei16_v_i32m1(const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei16_v_i32m2(const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei16_v_i32m4(const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vloxei16_v_i32m8(const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei32_v_i32mf2(const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei32_v_i32m1(const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei32_v_i32m2(const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei32_v_i32m4(const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vloxei32_v_i32m8(const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei64_v_i32mf2(const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei64_v_i32m1(const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei64_v_i32m2(const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei64_v_i32m4(const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei8_v_i64m1(const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei8_v_i64m2(const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei8_v_i64m4(const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei8_v_i64m8(const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei16_v_i64m1(const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei16_v_i64m2(const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei16_v_i64m4(const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei16_v_i64m8(const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei32_v_i64m1(const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei32_v_i64m2(const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei32_v_i64m4(const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei32_v_i64m8(const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei64_v_i64m1(const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei64_v_i64m2(const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei64_v_i64m4(const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei64_v_i64m8(const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei8_v_u8mf8(const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei8_v_u8mf4(const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei8_v_u8mf2(const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei8_v_u8m1(const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vloxei8_v_u8m2(const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vloxei8_v_u8m4(const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t test_vloxei8_v_u8m8(const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei16_v_u8mf8(const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei16_v_u8mf4(const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei16_v_u8mf2(const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei16_v_u8m1(const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vloxei16_v_u8m2(const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vloxei16_v_u8m4(const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei32_v_u8mf8(const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei32_v_u8mf4(const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei32_v_u8mf2(const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei32_v_u8m1(const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vloxei32_v_u8m2(const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei64_v_u8mf8(const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei64_v_u8mf4(const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei64_v_u8mf2(const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei64_v_u8m1(const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei8_v_u16mf4(const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei8_v_u16mf2(const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei8_v_u16m1(const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei8_v_u16m2(const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vloxei8_v_u16m4(const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vloxei8_v_u16m8(const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei16_v_u16mf4(const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei16_v_u16mf2(const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei16_v_u16m1(const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei16_v_u16m2(const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vloxei16_v_u16m4(const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vloxei16_v_u16m8(const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei32_v_u16mf4(const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei32_v_u16mf2(const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei32_v_u16m1(const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei32_v_u16m2(const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vloxei32_v_u16m4(const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei64_v_u16mf4(const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei64_v_u16mf2(const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei64_v_u16m1(const uint16_t *base, vuint64m4_t bindex, size_t vl) { + // + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei64_v_u16m2(const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei8_v_u32mf2(const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei8_v_u32m1(const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei8_v_u32m2(const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei8_v_u32m4(const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vloxei8_v_u32m8(const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei16_v_u32mf2(const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei16_v_u32m1(const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei16_v_u32m2(const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei16_v_u32m4(const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vloxei16_v_u32m8(const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei32_v_u32mf2(const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei32_v_u32m1(const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei32_v_u32m2(const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei32_v_u32m4(const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vloxei32_v_u32m8(const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei64_v_u32mf2(const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei64_v_u32m1(const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei64_v_u32m2(const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei64_v_u32m4(const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei8_v_u64m1(const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei8_v_u64m2(const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei8_v_u64m4(const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei8_v_u64m8(const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei16_v_u64m1(const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei16_v_u64m2(const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei16_v_u64m4(const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei16_v_u64m8(const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei32_v_u64m1(const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei32_v_u64m2(const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei32_v_u64m4(const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei32_v_u64m8(const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei64_v_u64m1(const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei64_v_u64m2(const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei64_v_u64m4(const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei64_v_u64m8(const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei8_v_f32mf2(const float *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei8_v_f32m1(const float *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei8_v_f32m2(const float *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei8_v_f32m4(const float *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vloxei8_v_f32m8(const float *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei16_v_f32mf2(const float *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei16_v_f32m1(const float *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei16_v_f32m2(const float *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei16_v_f32m4(const float *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vloxei16_v_f32m8(const float *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei32_v_f32mf2(const float *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei32_v_f32m1(const float *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei32_v_f32m2(const float *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei32_v_f32m4(const float *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vloxei32_v_f32m8(const float *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei64_v_f32mf2(const float *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei64_v_f32m1(const float *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei64_v_f32m2(const float *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei64_v_f32m4(const float *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei8_v_f64m1(const double *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei8_v_f64m2(const double *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei8_v_f64m4(const double *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei8_v_f64m8(const double *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei16_v_f64m1(const double *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei16_v_f64m2(const double *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei16_v_f64m4(const double *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei16_v_f64m8(const double *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei32_v_f64m1(const double *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei32_v_f64m2(const double *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei32_v_f64m4(const double *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei32_v_f64m8(const double *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei64_v_f64m1(const double *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei64_v_f64m2(const double *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei64_v_f64m4(const double *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei64_v_f64m8(const double *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei8_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei8_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei8_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei8_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vloxei8_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vloxei8_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t test_vloxei8_v_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei16_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei16_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei16_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei16_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vloxei16_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vloxei16_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei32_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei32_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei32_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei32_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vloxei32_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vloxei64_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vloxei64_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vloxei64_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vloxei64_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei8_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei8_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei8_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei8_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vloxei8_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vloxei8_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei16_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei16_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei16_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei16_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vloxei16_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vloxei16_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei32_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei32_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei32_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei32_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vloxei32_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vloxei64_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vloxei64_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vloxei64_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vloxei64_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei8_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei8_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei8_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei8_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vloxei8_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei16_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei16_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei16_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei16_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vloxei16_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei32_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei32_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei32_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei32_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vloxei32_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vloxei64_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vloxei64_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vloxei64_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vloxei64_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei8_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei8_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei8_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei8_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei16_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei16_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei16_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei16_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei32_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei32_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei32_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei32_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vloxei64_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vloxei64_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vloxei64_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vloxei64_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei8_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei8_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei8_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei8_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vloxei8_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vloxei8_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t test_vloxei8_v_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei16_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei16_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei16_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei16_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vloxei16_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vloxei16_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei32_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei32_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei32_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei32_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vloxei32_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vloxei64_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vloxei64_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vloxei64_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vloxei64_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei8_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei8_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei8_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei8_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vloxei8_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vloxei8_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei16_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei16_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei16_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei16_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vloxei16_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vloxei16_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei32_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei32_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei32_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei32_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vloxei32_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vloxei64_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vloxei64_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vloxei64_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vloxei64_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei8_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei8_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei8_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei8_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vloxei8_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei16_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei16_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei16_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei16_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vloxei16_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei32_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei32_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei32_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei32_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vloxei32_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vloxei64_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vloxei64_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vloxei64_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vloxei64_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei8_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei8_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei8_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei8_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei16_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei16_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei16_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei16_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei32_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei32_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei32_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei32_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vloxei64_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vloxei64_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vloxei64_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vloxei64_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei8_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei8_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei8_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei8_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vloxei8_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint8m2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei16_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei16_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei16_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei16_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vloxei16_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint16m4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei32_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei32_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei32_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei32_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vloxei32_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint32m8_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vloxei64_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vloxei64_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vloxei64_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vloxei64_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei8_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei8_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei8_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei8_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei8_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei8_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint8m1_t bindex, size_t vl) { + return vloxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei16_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei16_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei16_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint16m1_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei16_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei16_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei16_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint16m2_t bindex, size_t vl) { + return vloxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei32_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei32_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint32m1_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei32_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint32m2_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei32_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei32_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei32_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint32m4_t bindex, size_t vl) { + return vloxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vloxei64_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint64m1_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vloxei64_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint64m2_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vloxei64_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint64m4_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vloxei64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vloxei64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vloxei64_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint64m8_t bindex, size_t vl) { + return vloxei64(mask, maskedoff, base, bindex, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vluxei.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vluxei.c new file mode 100644 index 000000000000..15fa817c9e90 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vluxei.c @@ -0,0 +1,6123 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8:#.*]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei8_v_i8mf8(const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei8_v_i8mf4(const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei8_v_i8mf2(const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei8_v_i8m1(const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vluxei8_v_i8m2(const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vluxei8_v_i8m4(const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t test_vluxei8_v_i8m8(const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei16_v_i8mf8(const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei16_v_i8mf4(const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei16_v_i8mf2(const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei16_v_i8m1(const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vluxei16_v_i8m2(const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vluxei16_v_i8m4(const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei32_v_i8mf8(const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei32_v_i8mf4(const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei32_v_i8mf2(const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei32_v_i8m1(const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vluxei32_v_i8m2(const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei64_v_i8mf8(const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei64_v_i8mf4(const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei64_v_i8mf2(const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei64_v_i8m1(const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei8_v_i16mf4(const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei8_v_i16mf2(const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei8_v_i16m1(const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei8_v_i16m2(const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vluxei8_v_i16m4(const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vluxei8_v_i16m8(const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei16_v_i16mf4(const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei16_v_i16mf2(const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei16_v_i16m1(const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei16_v_i16m2(const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vluxei16_v_i16m4(const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vluxei16_v_i16m8(const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei32_v_i16mf4(const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei32_v_i16mf2(const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei32_v_i16m1(const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei32_v_i16m2(const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vluxei32_v_i16m4(const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei64_v_i16mf4(const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei64_v_i16mf2(const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei64_v_i16m1(const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei64_v_i16m2(const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei8_v_i32mf2(const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei8_v_i32m1(const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei8_v_i32m2(const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei8_v_i32m4(const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vluxei8_v_i32m8(const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei16_v_i32mf2(const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei16_v_i32m1(const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei16_v_i32m2(const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei16_v_i32m4(const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vluxei16_v_i32m8(const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei32_v_i32mf2(const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei32_v_i32m1(const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei32_v_i32m2(const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei32_v_i32m4(const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vluxei32_v_i32m8(const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei64_v_i32mf2(const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei64_v_i32m1(const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei64_v_i32m2(const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei64_v_i32m4(const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei8_v_i64m1(const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei8_v_i64m2(const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei8_v_i64m4(const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei8_v_i64m8(const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei16_v_i64m1(const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei16_v_i64m2(const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei16_v_i64m4(const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei16_v_i64m8(const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei32_v_i64m1(const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei32_v_i64m2(const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei32_v_i64m4(const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei32_v_i64m8(const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei64_v_i64m1(const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei64_v_i64m2(const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei64_v_i64m4(const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei64_v_i64m8(const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei8_v_u8mf8(const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei8_v_u8mf4(const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei8_v_u8mf2(const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei8_v_u8m1(const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vluxei8_v_u8m2(const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vluxei8_v_u8m4(const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t test_vluxei8_v_u8m8(const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei16_v_u8mf8(const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei16_v_u8mf4(const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei16_v_u8mf2(const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei16_v_u8m1(const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vluxei16_v_u8m2(const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vluxei16_v_u8m4(const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei32_v_u8mf8(const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei32_v_u8mf4(const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei32_v_u8mf2(const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei32_v_u8m1(const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vluxei32_v_u8m2(const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei64_v_u8mf8(const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei64_v_u8mf4(const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei64_v_u8mf2(const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei64_v_u8m1(const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei8_v_u16mf4(const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei8_v_u16mf2(const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei8_v_u16m1(const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei8_v_u16m2(const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vluxei8_v_u16m4(const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vluxei8_v_u16m8(const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei16_v_u16mf4(const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei16_v_u16mf2(const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei16_v_u16m1(const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei16_v_u16m2(const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vluxei16_v_u16m4(const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vluxei16_v_u16m8(const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei32_v_u16mf4(const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei32_v_u16mf2(const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei32_v_u16m1(const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei32_v_u16m2(const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vluxei32_v_u16m4(const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei64_v_u16mf4(const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei64_v_u16mf2(const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei64_v_u16m1(const uint16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei64_v_u16m2(const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei8_v_u32mf2(const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei8_v_u32m1(const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei8_v_u32m2(const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei8_v_u32m4(const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vluxei8_v_u32m8(const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei16_v_u32mf2(const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei16_v_u32m1(const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei16_v_u32m2(const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei16_v_u32m4(const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vluxei16_v_u32m8(const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei32_v_u32mf2(const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei32_v_u32m1(const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei32_v_u32m2(const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei32_v_u32m4(const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vluxei32_v_u32m8(const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei64_v_u32mf2(const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei64_v_u32m1(const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei64_v_u32m2(const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei64_v_u32m4(const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei8_v_u64m1(const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei8_v_u64m2(const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei8_v_u64m4(const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei8_v_u64m8(const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei16_v_u64m1(const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei16_v_u64m2(const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei16_v_u64m4(const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei16_v_u64m8(const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei32_v_u64m1(const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei32_v_u64m2(const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei32_v_u64m4(const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei32_v_u64m8(const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei64_v_u64m1(const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei64_v_u64m2(const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei64_v_u64m4(const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei64_v_u64m8(const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei8_v_f32mf2(const float *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei8_v_f32m1(const float *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei8_v_f32m2(const float *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei8_v_f32m4(const float *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vluxei8_v_f32m8(const float *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei16_v_f32mf2(const float *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei16_v_f32m1(const float *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei16_v_f32m2(const float *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei16_v_f32m4(const float *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vluxei16_v_f32m8(const float *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei32_v_f32mf2(const float *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei32_v_f32m1(const float *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei32_v_f32m2(const float *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei32_v_f32m4(const float *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vluxei32_v_f32m8(const float *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei64_v_f32mf2(const float *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei64_v_f32m1(const float *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei64_v_f32m2(const float *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei64_v_f32m4(const float *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei8_v_f64m1(const double *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei8_v_f64m2(const double *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei8_v_f64m4(const double *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei8_v_f64m8(const double *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei16_v_f64m1(const double *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei16_v_f64m2(const double *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei16_v_f64m4(const double *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei16_v_f64m8(const double *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei32_v_f64m1(const double *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei32_v_f64m2(const double *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei32_v_f64m4(const double *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei32_v_f64m8(const double *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei64_v_f64m1(const double *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei64_v_f64m2(const double *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei64_v_f64m4(const double *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei64_v_f64m8(const double *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei8_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei8_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei8_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei8_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vluxei8_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vluxei8_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t test_vluxei8_v_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei16_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei16_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei16_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei16_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vluxei16_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vluxei16_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei32_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei32_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei32_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei32_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vluxei32_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vluxei64_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vluxei64_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vluxei64_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vluxei64_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei8_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei8_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei8_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei8_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vluxei8_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vluxei8_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei16_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei16_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei16_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei16_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vluxei16_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vluxei16_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei32_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei32_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei32_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei32_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vluxei32_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vluxei64_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vluxei64_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vluxei64_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vluxei64_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei8_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei8_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei8_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei8_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vluxei8_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei16_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei16_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei16_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei16_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vluxei16_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei32_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei32_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei32_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei32_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vluxei32_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vluxei64_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vluxei64_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vluxei64_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vluxei64_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei8_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei8_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei8_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei8_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei16_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei16_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei16_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei16_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei32_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei32_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei32_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei32_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vluxei64_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vluxei64_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vluxei64_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vluxei64_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei8_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei8_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei8_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei8_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vluxei8_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vluxei8_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t test_vluxei8_v_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei16_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei16_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei16_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei16_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vluxei16_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vluxei16_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei32_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei32_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei32_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei32_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vluxei32_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vluxei64_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vluxei64_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vluxei64_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vluxei64_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei8_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei8_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei8_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei8_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vluxei8_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vluxei8_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei16_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei16_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei16_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei16_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vluxei16_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vluxei16_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei32_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei32_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei32_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei32_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vluxei32_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vluxei64_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vluxei64_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vluxei64_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vluxei64_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei8_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei8_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei8_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei8_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vluxei8_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei16_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei16_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei16_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei16_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vluxei16_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei32_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei32_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei32_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei32_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vluxei32_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vluxei64_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vluxei64_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vluxei64_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vluxei64_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei8_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei8_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei8_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei8_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei16_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei16_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei16_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei16_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei32_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei32_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei32_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei32_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vluxei64_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vluxei64_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vluxei64_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vluxei64_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei8_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei8_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei8_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei8_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vluxei8_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint8m2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei16_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei16_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei16_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei16_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vluxei16_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint16m4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei32_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei32_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei32_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei32_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vluxei32_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint32m8_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vluxei64_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vluxei64_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vluxei64_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vluxei64_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei8_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei8_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei8_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei8_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei8_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei8_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint8m1_t bindex, size_t vl) { + return vluxei8(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei16_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei16_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei16_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint16m1_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei16_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei16_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei16_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint16m2_t bindex, size_t vl) { + return vluxei16(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei32_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei32_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint32m1_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei32_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint32m2_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei32_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei32_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei32_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint32m4_t bindex, size_t vl) { + return vluxei32(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vluxei64_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint64m1_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vluxei64_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint64m2_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vluxei64_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint64m4_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @test_vluxei64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vluxei64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) [[ATTR8]] +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vluxei64_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint64m8_t bindex, size_t vl) { + return vluxei64(mask, maskedoff, base, bindex, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vse.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vse.c new file mode 100644 index 000000000000..a8242403b83d --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vse.c @@ -0,0 +1,1707 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11:[0-9]+]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11:[0-9]+]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf8(int8_t *base, vint8mf8_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf4(int8_t *base, vint8mf4_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf2(int8_t *base, vint8mf2_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m1(int8_t *base, vint8m1_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m2(int8_t *base, vint8m2_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m4(int8_t *base, vint8m4_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m8(int8_t *base, vint8m8_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf4(int16_t *base, vint16mf4_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf2(int16_t *base, vint16mf2_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m1(int16_t *base, vint16m1_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m2(int16_t *base, vint16m2_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m4(int16_t *base, vint16m4_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m8(int16_t *base, vint16m8_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32mf2(int32_t *base, vint32mf2_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m1(int32_t *base, vint32m1_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m2(int32_t *base, vint32m2_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m4(int32_t *base, vint32m4_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m8(int32_t *base, vint32m8_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m1(int64_t *base, vint64m1_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m2(int64_t *base, vint64m2_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m4(int64_t *base, vint64m4_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m8(int64_t *base, vint64m8_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf8(uint8_t *base, vuint8mf8_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf4(uint8_t *base, vuint8mf4_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf2(uint8_t *base, vuint8mf2_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m1(uint8_t *base, vuint8m1_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m2(uint8_t *base, vuint8m2_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m4(uint8_t *base, vuint8m4_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m8(uint8_t *base, vuint8m8_t value, size_t vl) { + return vse8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf4(uint16_t *base, vuint16mf4_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf2(uint16_t *base, vuint16mf2_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m1(uint16_t *base, vuint16m1_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m2(uint16_t *base, vuint16m2_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m4(uint16_t *base, vuint16m4_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m8(uint16_t *base, vuint16m8_t value, size_t vl) { + return vse16(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32mf2(uint32_t *base, vuint32mf2_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m1(uint32_t *base, vuint32m1_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m2(uint32_t *base, vuint32m2_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m4(uint32_t *base, vuint32m4_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m8(uint32_t *base, vuint32m8_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m1(uint64_t *base, vuint64m1_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m2(uint64_t *base, vuint64m2_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m4(uint64_t *base, vuint64m4_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m8(uint64_t *base, vuint64m8_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32mf2(float *base, vfloat32mf2_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m1(float *base, vfloat32m1_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m2(float *base, vfloat32m2_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m4(float *base, vfloat32m4_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m8(float *base, vfloat32m8_t value, size_t vl) { + return vse32(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m1(double *base, vfloat64m1_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m2(double *base, vfloat64m2_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m4(double *base, vfloat64m4_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m8(double *base, vfloat64m8_t value, size_t vl) { + return vse64(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf8_m(vbool64_t mask, int8_t *base, vint8mf8_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf4_m(vbool32_t mask, int8_t *base, vint8mf4_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf2_m(vbool16_t mask, int8_t *base, vint8mf2_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m1_m(vbool8_t mask, int8_t *base, vint8m1_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m2_m(vbool4_t mask, int8_t *base, vint8m2_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m4_m(vbool2_t mask, int8_t *base, vint8m4_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m8_m(vbool1_t mask, int8_t *base, vint8m8_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf4_m(vbool64_t mask, int16_t *base, vint16mf4_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf2_m(vbool32_t mask, int16_t *base, vint16mf2_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m1_m(vbool16_t mask, int16_t *base, vint16m1_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m2_m(vbool8_t mask, int16_t *base, vint16m2_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m4_m(vbool4_t mask, int16_t *base, vint16m4_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m8_m(vbool2_t mask, int16_t *base, vint16m8_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32mf2_m(vbool64_t mask, int32_t *base, vint32mf2_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m1_m(vbool32_t mask, int32_t *base, vint32m1_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m2_m(vbool16_t mask, int32_t *base, vint32m2_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m4_m(vbool8_t mask, int32_t *base, vint32m4_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m8_m(vbool4_t mask, int32_t *base, vint32m8_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m1_m(vbool64_t mask, int64_t *base, vint64m1_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m2_m(vbool32_t mask, int64_t *base, vint64m2_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m4_m(vbool16_t mask, int64_t *base, vint64m4_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m8_m(vbool8_t mask, int64_t *base, vint64m8_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf8_m(vbool64_t mask, uint8_t *base, vuint8mf8_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf4_m(vbool32_t mask, uint8_t *base, vuint8mf4_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf2_m(vbool16_t mask, uint8_t *base, vuint8mf2_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m1_m(vbool8_t mask, uint8_t *base, vuint8m1_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m2_m(vbool4_t mask, uint8_t *base, vuint8m2_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m4_m(vbool2_t mask, uint8_t *base, vuint8m4_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m8_m(vbool1_t mask, uint8_t *base, vuint8m8_t value, size_t vl) { + return vse8(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf4_m(vbool64_t mask, uint16_t *base, vuint16mf4_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf2_m(vbool32_t mask, uint16_t *base, vuint16mf2_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m1_m(vbool16_t mask, uint16_t *base, vuint16m1_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m2_m(vbool8_t mask, uint16_t *base, vuint16m2_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m4_m(vbool4_t mask, uint16_t *base, vuint16m4_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m8_m(vbool2_t mask, uint16_t *base, vuint16m8_t value, size_t vl) { + return vse16(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32mf2_m(vbool64_t mask, uint32_t *base, vuint32mf2_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m1_m(vbool32_t mask, uint32_t *base, vuint32m1_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m2_m(vbool16_t mask, uint32_t *base, vuint32m2_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m4_m(vbool8_t mask, uint32_t *base, vuint32m4_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m8_m(vbool4_t mask, uint32_t *base, vuint32m8_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m1_m(vbool64_t mask, uint64_t *base, vuint64m1_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m2_m(vbool32_t mask, uint64_t *base, vuint64m2_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m4_m(vbool16_t mask, uint64_t *base, vuint64m4_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m8_m(vbool8_t mask, uint64_t *base, vuint64m8_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32mf2_m(vbool64_t mask, float *base, vfloat32mf2_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m1_m(vbool32_t mask, float *base, vfloat32m1_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m2_m(vbool16_t mask, float *base, vfloat32m2_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m4_m(vbool8_t mask, float *base, vfloat32m4_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m8_m(vbool4_t mask, float *base, vfloat32m8_t value, size_t vl) { + return vse32(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m1_m(vbool64_t mask, double *base, vfloat64m1_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m2_m(vbool32_t mask, double *base, vfloat64m2_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m4_m(vbool16_t mask, double *base, vfloat64m4_t value, size_t vl) { + return vse64(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) #[[ATTR11]] +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m8_m(vbool8_t mask, double *base, vfloat64m8_t value, size_t vl) { + return vse64(mask, base, value, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vadd.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vadd.c new file mode 100644 index 000000000000..902f5e0bf2ed --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vadd.c @@ -0,0 +1,2476 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vv_i8mf8(vint8mf8_t op1, vint8mf8_t op2, size_t vl) { + return vadd_vv_i8mf8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vx_i8mf8(vint8mf8_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8mf8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vv_i8mf4(vint8mf4_t op1, vint8mf4_t op2, size_t vl) { + return vadd_vv_i8mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vx_i8mf4(vint8mf4_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vv_i8mf2(vint8mf2_t op1, vint8mf2_t op2, size_t vl) { + return vadd_vv_i8mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vx_i8mf2(vint8mf2_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vv_i8m1(vint8m1_t op1, vint8m1_t op2, size_t vl) { + return vadd_vv_i8m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vx_i8m1(vint8m1_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vv_i8m2(vint8m2_t op1, vint8m2_t op2, size_t vl) { + return vadd_vv_i8m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vx_i8m2(vint8m2_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vv_i8m4(vint8m4_t op1, vint8m4_t op2, size_t vl) { + return vadd_vv_i8m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vx_i8m4(vint8m4_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vv_i8m8(vint8m8_t op1, vint8m8_t op2, size_t vl) { + return vadd_vv_i8m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vx_i8m8(vint8m8_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vv_i16mf4(vint16mf4_t op1, vint16mf4_t op2, size_t vl) { + return vadd_vv_i16mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vx_i16mf4(vint16mf4_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vv_i16mf2(vint16mf2_t op1, vint16mf2_t op2, size_t vl) { + return vadd_vv_i16mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vx_i16mf2(vint16mf2_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vv_i16m1(vint16m1_t op1, vint16m1_t op2, size_t vl) { + return vadd_vv_i16m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vx_i16m1(vint16m1_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vv_i16m2(vint16m2_t op1, vint16m2_t op2, size_t vl) { + return vadd_vv_i16m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vx_i16m2(vint16m2_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vv_i16m4(vint16m4_t op1, vint16m4_t op2, size_t vl) { + return vadd_vv_i16m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vx_i16m4(vint16m4_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vv_i16m8(vint16m8_t op1, vint16m8_t op2, size_t vl) { + return vadd_vv_i16m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vx_i16m8(vint16m8_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vv_i32mf2(vint32mf2_t op1, vint32mf2_t op2, size_t vl) { + return vadd_vv_i32mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vx_i32mf2(vint32mf2_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vv_i32m1(vint32m1_t op1, vint32m1_t op2, size_t vl) { + return vadd_vv_i32m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vx_i32m1(vint32m1_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vv_i32m2(vint32m2_t op1, vint32m2_t op2, size_t vl) { + return vadd_vv_i32m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vx_i32m2(vint32m2_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vv_i32m4(vint32m4_t op1, vint32m4_t op2, size_t vl) { + return vadd_vv_i32m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vx_i32m4(vint32m4_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vv_i32m8(vint32m8_t op1, vint32m8_t op2, size_t vl) { + return vadd_vv_i32m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vx_i32m8(vint32m8_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vv_i64m1(vint64m1_t op1, vint64m1_t op2, size_t vl) { + return vadd_vv_i64m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vx_i64m1(vint64m1_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vv_i64m2(vint64m2_t op1, vint64m2_t op2, size_t vl) { + return vadd_vv_i64m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vx_i64m2(vint64m2_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vv_i64m4(vint64m4_t op1, vint64m4_t op2, size_t vl) { + return vadd_vv_i64m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vx_i64m4(vint64m4_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vv_i64m8(vint64m8_t op1, vint64m8_t op2, size_t vl) { + return vadd_vv_i64m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vx_i64m8(vint64m8_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.nxv1i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vv_u8mf8(vuint8mf8_t op1, vuint8mf8_t op2, size_t vl) { + return vadd_vv_u8mf8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vx_u8mf8(vuint8mf8_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8mf8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.nxv2i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vv_u8mf4(vuint8mf4_t op1, vuint8mf4_t op2, size_t vl) { + return vadd_vv_u8mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vx_u8mf4(vuint8mf4_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.nxv4i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vv_u8mf2(vuint8mf2_t op1, vuint8mf2_t op2, size_t vl) { + return vadd_vv_u8mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vx_u8mf2(vuint8mf2_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.nxv8i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vv_u8m1(vuint8m1_t op1, vuint8m1_t op2, size_t vl) { + return vadd_vv_u8m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vx_u8m1(vuint8m1_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.nxv16i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vv_u8m2(vuint8m2_t op1, vuint8m2_t op2, size_t vl) { + return vadd_vv_u8m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vx_u8m2(vuint8m2_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.nxv32i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vv_u8m4(vuint8m4_t op1, vuint8m4_t op2, size_t vl) { + return vadd_vv_u8m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vx_u8m4(vuint8m4_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.nxv64i8.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vv_u8m8(vuint8m8_t op1, vuint8m8_t op2, size_t vl) { + return vadd_vv_u8m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i32( [[OP1:%.*]], i8 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv64i8.i8.i64( [[OP1:%.*]], i8 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vx_u8m8(vuint8m8_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.nxv1i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vv_u16mf4(vuint16mf4_t op1, vuint16mf4_t op2, size_t vl) { + return vadd_vv_u16mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vx_u16mf4(vuint16mf4_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16mf4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.nxv2i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vv_u16mf2(vuint16mf2_t op1, vuint16mf2_t op2, size_t vl) { + return vadd_vv_u16mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vx_u16mf2(vuint16mf2_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.nxv4i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vv_u16m1(vuint16m1_t op1, vuint16m1_t op2, size_t vl) { + return vadd_vv_u16m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vx_u16m1(vuint16m1_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.nxv8i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vv_u16m2(vuint16m2_t op1, vuint16m2_t op2, size_t vl) { + return vadd_vv_u16m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vx_u16m2(vuint16m2_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.nxv16i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vv_u16m4(vuint16m4_t op1, vuint16m4_t op2, size_t vl) { + return vadd_vv_u16m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vx_u16m4(vuint16m4_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.nxv32i16.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vv_u16m8(vuint16m8_t op1, vuint16m8_t op2, size_t vl) { + return vadd_vv_u16m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i32( [[OP1:%.*]], i16 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv32i16.i16.i64( [[OP1:%.*]], i16 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vx_u16m8(vuint16m8_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.nxv1i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vv_u32mf2(vuint32mf2_t op1, vuint32mf2_t op2, size_t vl) { + return vadd_vv_u32mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vx_u32mf2(vuint32mf2_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vv_u32m1(vuint32m1_t op1, vuint32m1_t op2, size_t vl) { + return vadd_vv_u32m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vx_u32m1(vuint32m1_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vv_u32m2(vuint32m2_t op1, vuint32m2_t op2, size_t vl) { + return vadd_vv_u32m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vx_u32m2(vuint32m2_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.nxv8i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vv_u32m4(vuint32m4_t op1, vuint32m4_t op2, size_t vl) { + return vadd_vv_u32m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vx_u32m4(vuint32m4_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.nxv16i32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vv_u32m8(vuint32m8_t op1, vuint32m8_t op2, size_t vl) { + return vadd_vv_u32m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i32( [[OP1:%.*]], i32 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv16i32.i32.i64( [[OP1:%.*]], i32 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vx_u32m8(vuint32m8_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.nxv1i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vv_u64m1(vuint64m1_t op1, vuint64m1_t op2, size_t vl) { + return vadd_vv_u64m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv1i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vx_u64m1(vuint64m1_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.nxv2i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vv_u64m2(vuint64m2_t op1, vuint64m2_t op2, size_t vl) { + return vadd_vv_u64m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv2i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vx_u64m2(vuint64m2_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.nxv4i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vv_u64m4(vuint64m4_t op1, vuint64m4_t op2, size_t vl) { + return vadd_vv_u64m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv4i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vx_u64m4(vuint64m4_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.nxv8i64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vv_u64m8(vuint64m8_t op1, vuint64m8_t op2, size_t vl) { + return vadd_vv_u64m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i32( [[OP1:%.*]], i64 [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.nxv8i64.i64.i64( [[OP1:%.*]], i64 [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vx_u64m8(vuint64m8_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vv_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, vint8mf8_t op1, vint8mf8_t op2, size_t vl) { + return vadd_vv_i8mf8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf8_t test_vadd_vx_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, vint8mf8_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8mf8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vv_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, vint8mf4_t op1, vint8mf4_t op2, size_t vl) { + return vadd_vv_i8mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf4_t test_vadd_vx_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, vint8mf4_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vv_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, vint8mf2_t op1, vint8mf2_t op2, size_t vl) { + return vadd_vv_i8mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8mf2_t test_vadd_vx_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, vint8mf2_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vv_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, vint8m1_t op2, size_t vl) { + return vadd_vv_i8m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_vadd_vx_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vv_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, vint8m2_t op1, vint8m2_t op2, size_t vl) { + return vadd_vv_i8m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_vadd_vx_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, vint8m2_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vv_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, vint8m4_t op1, vint8m4_t op2, size_t vl) { + return vadd_vv_i8m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_vadd_vx_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, vint8m4_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vv_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, vint8m8_t op1, vint8m8_t op2, size_t vl) { + return vadd_vv_i8m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_vadd_vx_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, vint8m8_t op1, int8_t op2, size_t vl) { + return vadd_vx_i8m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vv_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, vint16mf4_t op1, vint16mf4_t op2, size_t vl) { + return vadd_vv_i16mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf4_t test_vadd_vx_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, vint16mf4_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vv_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, vint16mf2_t op1, vint16mf2_t op2, size_t vl) { + return vadd_vv_i16mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16mf2_t test_vadd_vx_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, vint16mf2_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vv_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, vint16m1_t op1, vint16m1_t op2, size_t vl) { + return vadd_vv_i16m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_vadd_vx_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, vint16m1_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vv_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, vint16m2_t op1, vint16m2_t op2, size_t vl) { + return vadd_vv_i16m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_vadd_vx_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, vint16m2_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vv_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, vint16m4_t op1, vint16m4_t op2, size_t vl) { + return vadd_vv_i16m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_vadd_vx_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, vint16m4_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vv_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, vint16m8_t op1, vint16m8_t op2, size_t vl) { + return vadd_vv_i16m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_vadd_vx_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, vint16m8_t op1, int16_t op2, size_t vl) { + return vadd_vx_i16m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vv_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, vint32mf2_t op1, vint32mf2_t op2, size_t vl) { + return vadd_vv_i32mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32mf2_t test_vadd_vx_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, vint32mf2_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vv_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, vint32m1_t op1, vint32m1_t op2, size_t vl) { + return vadd_vv_i32m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_vadd_vx_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, vint32m1_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vv_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, vint32m2_t op1, vint32m2_t op2, size_t vl) { + return vadd_vv_i32m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_vadd_vx_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, vint32m2_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vv_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, vint32m4_t op1, vint32m4_t op2, size_t vl) { + return vadd_vv_i32m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_vadd_vx_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, vint32m4_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vv_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, vint32m8_t op1, vint32m8_t op2, size_t vl) { + return vadd_vv_i32m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_vadd_vx_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, vint32m8_t op1, int32_t op2, size_t vl) { + return vadd_vx_i32m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vv_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, vint64m1_t op1, vint64m1_t op2, size_t vl) { + return vadd_vv_i64m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_vadd_vx_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, vint64m1_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vv_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, vint64m2_t op1, vint64m2_t op2, size_t vl) { + return vadd_vv_i64m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_vadd_vx_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, vint64m2_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vv_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, vint64m4_t op1, vint64m4_t op2, size_t vl) { + return vadd_vv_i64m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_vadd_vx_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, vint64m4_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vv_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, vint64m8_t op1, vint64m8_t op2, size_t vl) { + return vadd_vv_i64m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_vadd_vx_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, vint64m8_t op1, int64_t op2, size_t vl) { + return vadd_vx_i64m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vv_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t op1, vuint8mf8_t op2, size_t vl) { + return vadd_vv_u8mf8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf8_t test_vadd_vx_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8mf8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vv_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t op1, vuint8mf4_t op2, size_t vl) { + return vadd_vv_u8mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf4_t test_vadd_vx_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vv_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t op1, vuint8mf2_t op2, size_t vl) { + return vadd_vv_u8mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8mf2_t test_vadd_vx_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vv_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t op1, vuint8m1_t op2, size_t vl) { + return vadd_vv_u8m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_vadd_vx_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vv_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t op1, vuint8m2_t op2, size_t vl) { + return vadd_vv_u8m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_vadd_vx_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vv_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t op1, vuint8m4_t op2, size_t vl) { + return vadd_vv_u8m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_vadd_vx_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vv_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t op1, vuint8m8_t op2, size_t vl) { + return vadd_vv_u8m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.i8.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i8 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_vadd_vx_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t op1, uint8_t op2, size_t vl) { + return vadd_vx_u8m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vv_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t op1, vuint16mf4_t op2, size_t vl) { + return vadd_vv_u16mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf4_t test_vadd_vx_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16mf4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vv_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t op1, vuint16mf2_t op2, size_t vl) { + return vadd_vv_u16mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16mf2_t test_vadd_vx_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vv_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t op1, vuint16m1_t op2, size_t vl) { + return vadd_vv_u16m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_vadd_vx_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vv_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t op1, vuint16m2_t op2, size_t vl) { + return vadd_vv_u16m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_vadd_vx_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vv_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t op1, vuint16m4_t op2, size_t vl) { + return vadd_vv_u16m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_vadd_vx_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vv_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t op1, vuint16m8_t op2, size_t vl) { + return vadd_vv_u16m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv32i16.i16.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i16 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_vadd_vx_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t op1, uint16_t op2, size_t vl) { + return vadd_vx_u16m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vv_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t op1, vuint32mf2_t op2, size_t vl) { + return vadd_vv_u32mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32mf2_t test_vadd_vx_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vv_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t op1, vuint32m1_t op2, size_t vl) { + return vadd_vv_u32m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_vadd_vx_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vv_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t op1, vuint32m2_t op2, size_t vl) { + return vadd_vv_u32m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_vadd_vx_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vv_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t op1, vuint32m4_t op2, size_t vl) { + return vadd_vv_u32m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_vadd_vx_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vv_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t op1, vuint32m8_t op2, size_t vl) { + return vadd_vv_u32m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv16i32.i32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i32 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_vadd_vx_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t op1, uint32_t op2, size_t vl) { + return vadd_vx_u32m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vv_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t op1, vuint64m1_t op2, size_t vl) { + return vadd_vv_u64m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv1i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_vadd_vx_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vv_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t op1, vuint64m2_t op2, size_t vl) { + return vadd_vv_u64m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv2i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_vadd_vx_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vv_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t op1, vuint64m4_t op2, size_t vl) { + return vadd_vv_u64m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv4i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_vadd_vx_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vv_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vv_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vv_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t op1, vuint64m8_t op2, size_t vl) { + return vadd_vv_u64m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vadd_vx_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vadd_vx_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vadd.mask.nxv8i64.i64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], i64 [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_vadd_vx_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t op1, uint64_t op2, size_t vl) { + return vadd_vx_u64m8_m(mask, maskedoff, op1, op2, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vfadd.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vfadd.c new file mode 100644 index 000000000000..43be374794d4 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vfadd.c @@ -0,0 +1,516 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.nxv1f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.nxv1f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vv_f32mf2(vfloat32mf2_t op1, vfloat32mf2_t op2, size_t vl) { + return vfadd_vv_f32mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vf_f32mf2(vfloat32mf2_t op1, float op2, size_t vl) { + return vfadd_vf_f32mf2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.nxv2f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.nxv2f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vv_f32m1(vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + return vfadd_vv_f32m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vf_f32m1(vfloat32m1_t op1, float op2, size_t vl) { + return vfadd_vf_f32m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.nxv4f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.nxv4f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vv_f32m2(vfloat32m2_t op1, vfloat32m2_t op2, size_t vl) { + return vfadd_vv_f32m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vf_f32m2(vfloat32m2_t op1, float op2, size_t vl) { + return vfadd_vf_f32m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.nxv8f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.nxv8f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vv_f32m4(vfloat32m4_t op1, vfloat32m4_t op2, size_t vl) { + return vfadd_vv_f32m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vf_f32m4(vfloat32m4_t op1, float op2, size_t vl) { + return vfadd_vf_f32m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.nxv16f32.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.nxv16f32.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vv_f32m8(vfloat32m8_t op1, vfloat32m8_t op2, size_t vl) { + return vfadd_vv_f32m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.f32.i32( [[OP1:%.*]], float [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv16f32.f32.i64( [[OP1:%.*]], float [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vf_f32m8(vfloat32m8_t op1, float op2, size_t vl) { + return vfadd_vf_f32m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.nxv1f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.nxv1f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vv_f64m1(vfloat64m1_t op1, vfloat64m1_t op2, size_t vl) { + return vfadd_vv_f64m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv1f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vf_f64m1(vfloat64m1_t op1, double op2, size_t vl) { + return vfadd_vf_f64m1(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.nxv2f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.nxv2f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vv_f64m2(vfloat64m2_t op1, vfloat64m2_t op2, size_t vl) { + return vfadd_vv_f64m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv2f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vf_f64m2(vfloat64m2_t op1, double op2, size_t vl) { + return vfadd_vf_f64m2(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.nxv4f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.nxv4f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vv_f64m4(vfloat64m4_t op1, vfloat64m4_t op2, size_t vl) { + return vfadd_vv_f64m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vf_f64m4(vfloat64m4_t op1, double op2, size_t vl) { + return vfadd_vf_f64m4(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.nxv8f64.i32( [[OP1:%.*]], [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.nxv8f64.i64( [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vv_f64m8(vfloat64m8_t op1, vfloat64m8_t op2, size_t vl) { + return vfadd_vv_f64m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.f64.i32( [[OP1:%.*]], double [[OP2:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv8f64.f64.i64( [[OP1:%.*]], double [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vf_f64m8(vfloat64m8_t op1, double op2, size_t vl) { + return vfadd_vf_f64m8(op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.nxv1f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.nxv1f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vv_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat32mf2_t op1, vfloat32mf2_t op2, size_t vl) { + return vfadd_vv_f32mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfadd_vf_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat32mf2_t op1, float op2, size_t vl) { + return vfadd_vf_f32mf2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.nxv2f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.nxv2f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vv_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + return vfadd_vv_f32m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfadd_vf_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, vfloat32m1_t op1, float op2, size_t vl) { + return vfadd_vf_f32m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.nxv4f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.nxv4f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vv_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, vfloat32m2_t op1, vfloat32m2_t op2, size_t vl) { + return vfadd_vv_f32m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfadd_vf_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, vfloat32m2_t op1, float op2, size_t vl) { + return vfadd_vf_f32m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.nxv8f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.nxv8f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vv_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, vfloat32m4_t op1, vfloat32m4_t op2, size_t vl) { + return vfadd_vv_f32m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfadd_vf_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, vfloat32m4_t op1, float op2, size_t vl) { + return vfadd_vf_f32m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.nxv16f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.nxv16f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vv_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, vfloat32m8_t op1, vfloat32m8_t op2, size_t vl) { + return vfadd_vv_f32m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.f32.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv16f32.f32.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], float [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfadd_vf_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, vfloat32m8_t op1, float op2, size_t vl) { + return vfadd_vf_f32m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.nxv1f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.nxv1f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vv_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, vfloat64m1_t op1, vfloat64m1_t op2, size_t vl) { + return vfadd_vv_f64m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv1f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfadd_vf_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, vfloat64m1_t op1, double op2, size_t vl) { + return vfadd_vf_f64m1_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.nxv2f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.nxv2f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vv_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, vfloat64m2_t op1, vfloat64m2_t op2, size_t vl) { + return vfadd_vv_f64m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv2f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfadd_vf_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, vfloat64m2_t op1, double op2, size_t vl) { + return vfadd_vf_f64m2_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.nxv4f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.nxv4f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vv_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, vfloat64m4_t op1, vfloat64m4_t op2, size_t vl) { + return vfadd_vv_f64m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv4f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfadd_vf_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, vfloat64m4_t op1, double op2, size_t vl) { + return vfadd_vf_f64m4_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vv_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.nxv8f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vv_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.nxv8f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vv_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, vfloat64m8_t op1, vfloat64m8_t op2, size_t vl) { + return vfadd_vv_f64m8_m(mask, maskedoff, op1, op2, vl); +} + +// CHECK-RV32-LABEL: @test_vfadd_vf_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.f64.i32( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vfadd_vf_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.mask.nxv8f64.f64.i64( [[MASKEDOFF:%.*]], [[OP1:%.*]], double [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfadd_vf_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, vfloat64m8_t op1, double op2, size_t vl) { + return vfadd_vf_f64m8_m(mask, maskedoff, op1, op2, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vle.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vle.c new file mode 100644 index 000000000000..aca7f314b881 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vle.c @@ -0,0 +1,1707 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vle8_v_i8mf8(const int8_t *base, size_t vl) { + return vle8_v_i8mf8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vle8_v_i8mf4(const int8_t *base, size_t vl) { + return vle8_v_i8mf4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vle8_v_i8mf2(const int8_t *base, size_t vl) { + return vle8_v_i8mf2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vle8_v_i8m1(const int8_t *base, size_t vl) { + return vle8_v_i8m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vle8_v_i8m2(const int8_t *base, size_t vl) { + return vle8_v_i8m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vle8_v_i8m4(const int8_t *base, size_t vl) { + return vle8_v_i8m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv64i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv64i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t test_vle8_v_i8m8(const int8_t *base, size_t vl) { + return vle8_v_i8m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vle16_v_i16mf4(const int16_t *base, size_t vl) { + return vle16_v_i16mf4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vle16_v_i16mf2(const int16_t *base, size_t vl) { + return vle16_v_i16mf2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vle16_v_i16m1(const int16_t *base, size_t vl) { + return vle16_v_i16m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vle16_v_i16m2(const int16_t *base, size_t vl) { + return vle16_v_i16m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vle16_v_i16m4(const int16_t *base, size_t vl) { + return vle16_v_i16m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vle16_v_i16m8(const int16_t *base, size_t vl) { + return vle16_v_i16m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vle32_v_i32mf2(const int32_t *base, size_t vl) { + return vle32_v_i32mf2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vle32_v_i32m1(const int32_t *base, size_t vl) { + return vle32_v_i32m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vle32_v_i32m2(const int32_t *base, size_t vl) { + return vle32_v_i32m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vle32_v_i32m4(const int32_t *base, size_t vl) { + return vle32_v_i32m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vle32_v_i32m8(const int32_t *base, size_t vl) { + return vle32_v_i32m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vle64_v_i64m1(const int64_t *base, size_t vl) { + return vle64_v_i64m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vle64_v_i64m2(const int64_t *base, size_t vl) { + return vle64_v_i64m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vle64_v_i64m4(const int64_t *base, size_t vl) { + return vle64_v_i64m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vle64_v_i64m8(const int64_t *base, size_t vl) { + return vle64_v_i64m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vle8_v_u8mf8(const uint8_t *base, size_t vl) { + return vle8_v_u8mf8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vle8_v_u8mf4(const uint8_t *base, size_t vl) { + return vle8_v_u8mf4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vle8_v_u8mf2(const uint8_t *base, size_t vl) { + return vle8_v_u8mf2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vle8_v_u8m1(const uint8_t *base, size_t vl) { + return vle8_v_u8m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vle8_v_u8m2(const uint8_t *base, size_t vl) { + return vle8_v_u8m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vle8_v_u8m4(const uint8_t *base, size_t vl) { + return vle8_v_u8m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv64i8.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv64i8.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t test_vle8_v_u8m8(const uint8_t *base, size_t vl) { + return vle8_v_u8m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vle16_v_u16mf4(const uint16_t *base, size_t vl) { + return vle16_v_u16mf4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vle16_v_u16mf2(const uint16_t *base, size_t vl) { + return vle16_v_u16mf2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vle16_v_u16m1(const uint16_t *base, size_t vl) { + return vle16_v_u16m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vle16_v_u16m2(const uint16_t *base, size_t vl) { + return vle16_v_u16m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vle16_v_u16m4(const uint16_t *base, size_t vl) { + return vle16_v_u16m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i16.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv32i16.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vle16_v_u16m8(const uint16_t *base, size_t vl) { + return vle16_v_u16m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vle32_v_u32mf2(const uint32_t *base, size_t vl) { + return vle32_v_u32mf2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vle32_v_u32m1(const uint32_t *base, size_t vl) { + return vle32_v_u32m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vle32_v_u32m2(const uint32_t *base, size_t vl) { + return vle32_v_u32m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vle32_v_u32m4(const uint32_t *base, size_t vl) { + return vle32_v_u32m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16i32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vle32_v_u32m8(const uint32_t *base, size_t vl) { + return vle32_v_u32m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vle64_v_u64m1(const uint64_t *base, size_t vl) { + return vle64_v_u64m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vle64_v_u64m2(const uint64_t *base, size_t vl) { + return vle64_v_u64m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vle64_v_u64m4(const uint64_t *base, size_t vl) { + return vle64_v_u64m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8i64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vle64_v_u64m8(const uint64_t *base, size_t vl) { + return vle64_v_u64m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1f32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1f32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vle32_v_f32mf2(const float *base, size_t vl) { + return vle32_v_f32mf2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2f32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2f32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vle32_v_f32m1(const float *base, size_t vl) { + return vle32_v_f32m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4f32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4f32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vle32_v_f32m2(const float *base, size_t vl) { + return vle32_v_f32m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8f32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8f32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vle32_v_f32m4(const float *base, size_t vl) { + return vle32_v_f32m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16f32.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv16f32.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vle32_v_f32m8(const float *base, size_t vl) { + return vle32_v_f32m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1f64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv1f64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vle64_v_f64m1(const double *base, size_t vl) { + return vle64_v_f64m1(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2f64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv2f64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vle64_v_f64m2(const double *base, size_t vl) { + return vle64_v_f64m2(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4f64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv4f64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vle64_v_f64m4(const double *base, size_t vl) { + return vle64_v_f64m4(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8f64.i32(* [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.nxv8f64.i64(* [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vle64_v_f64m8(const double *base, size_t vl) { + return vle64_v_f64m8(base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t test_vle8_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, size_t vl) { + return vle8_v_i8mf8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t test_vle8_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, size_t vl) { + return vle8_v_i8mf4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t test_vle8_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, size_t vl) { + return vle8_v_i8mf2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t test_vle8_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, size_t vl) { + return vle8_v_i8m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t test_vle8_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, size_t vl) { + return vle8_v_i8m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t test_vle8_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, size_t vl) { + return vle8_v_i8m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t test_vle8_v_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, const int8_t *base, size_t vl) { + return vle8_v_i8m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t test_vle16_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, size_t vl) { + return vle16_v_i16mf4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t test_vle16_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, size_t vl) { + return vle16_v_i16mf2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t test_vle16_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, size_t vl) { + return vle16_v_i16m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t test_vle16_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, size_t vl) { + return vle16_v_i16m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t test_vle16_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, size_t vl) { + return vle16_v_i16m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t test_vle16_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, size_t vl) { + return vle16_v_i16m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t test_vle32_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, size_t vl) { + return vle32_v_i32mf2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t test_vle32_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, size_t vl) { + return vle32_v_i32m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t test_vle32_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, size_t vl) { + return vle32_v_i32m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t test_vle32_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, size_t vl) { + return vle32_v_i32m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t test_vle32_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, size_t vl) { + return vle32_v_i32m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t test_vle64_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, size_t vl) { + return vle64_v_i64m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t test_vle64_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, size_t vl) { + return vle64_v_i64m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t test_vle64_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, size_t vl) { + return vle64_v_i64m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t test_vle64_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, size_t vl) { + return vle64_v_i64m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t test_vle8_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, size_t vl) { + return vle8_v_u8mf8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t test_vle8_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, size_t vl) { + return vle8_v_u8mf4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t test_vle8_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, size_t vl) { + return vle8_v_u8mf2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t test_vle8_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, size_t vl) { + return vle8_v_u8m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t test_vle8_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, size_t vl) { + return vle8_v_u8m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t test_vle8_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, size_t vl) { + return vle8_v_u8m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t test_vle8_v_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, const uint8_t *base, size_t vl) { + return vle8_v_u8m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t test_vle16_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, size_t vl) { + return vle16_v_u16mf4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t test_vle16_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, size_t vl) { + return vle16_v_u16mf2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t test_vle16_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, size_t vl) { + return vle16_v_u16m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t test_vle16_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, size_t vl) { + return vle16_v_u16m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t test_vle16_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, size_t vl) { + return vle16_v_u16m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t test_vle16_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, size_t vl) { + return vle16_v_u16m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t test_vle32_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, size_t vl) { + return vle32_v_u32mf2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t test_vle32_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, size_t vl) { + return vle32_v_u32m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t test_vle32_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, size_t vl) { + return vle32_v_u32m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t test_vle32_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, size_t vl) { + return vle32_v_u32m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t test_vle32_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, size_t vl) { + return vle32_v_u32m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t test_vle64_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, size_t vl) { + return vle64_v_u64m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t test_vle64_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, size_t vl) { + return vle64_v_u64m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t test_vle64_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, size_t vl) { + return vle64_v_u64m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t test_vle64_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, size_t vl) { + return vle64_v_u64m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t test_vle32_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, size_t vl) { + return vle32_v_f32mf2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t test_vle32_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, size_t vl) { + return vle32_v_f32m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t test_vle32_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, size_t vl) { + return vle32_v_f32m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t test_vle32_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, size_t vl) { + return vle32_v_f32m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16f32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv16f32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t test_vle32_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, size_t vl) { + return vle32_v_f32m8_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv1f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t test_vle64_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, size_t vl) { + return vle64_v_f64m1_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv2f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t test_vle64_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, size_t vl) { + return vle64_v_f64m2_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv4f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t test_vle64_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, size_t vl) { + return vle64_v_f64m4_m(mask, maskedoff, base, vl); +} + +// CHECK-RV32-LABEL: @test_vle64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vle64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vle.mask.nxv8f64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t test_vle64_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, size_t vl) { + return vle64_v_f64m8_m(mask, maskedoff, base, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vloxei.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vloxei.c new file mode 100644 index 000000000000..21ca49ded56b --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vloxei.c @@ -0,0 +1,6123 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S > /dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei8_v_i8mf8(const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei8_v_i8mf4(const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei8_v_i8mf2(const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei8_v_i8m1(const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei8_v_i8m2(const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_i8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei8_v_i8m4(const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_i8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t testuxei8_v_i8m8(const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8_v_i8m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei16_v_i8mf8(const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei16_v_i8mf4(const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei16_v_i8mf2(const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei16_v_i8m1(const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei16_v_i8m2(const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_i8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei16_v_i8m4(const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_i8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei32_v_i8mf8(const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei32_v_i8mf4(const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei32_v_i8mf2(const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei32_v_i8m1(const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei32_v_i8m2(const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_i8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei64_v_i8mf8(const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei64_v_i8mf4(const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei64_v_i8mf2(const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei64_v_i8m1(const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei8_v_i16mf4(const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei8_v_i16mf2(const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei8_v_i16m1(const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei8_v_i16m2(const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei8_v_i16m4(const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_i16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei8_v_i16m8(const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_i16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei16_v_i16mf4(const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei16_v_i16mf2(const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei16_v_i16m1(const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei16_v_i16m2(const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei16_v_i16m4(const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_i16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei16_v_i16m8(const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_i16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei32_v_i16mf4(const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei32_v_i16mf2(const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei32_v_i16m1(const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei32_v_i16m2(const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei32_v_i16m4(const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_i16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei64_v_i16mf4(const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei64_v_i16mf2(const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei64_v_i16m1(const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei64_v_i16m2(const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei8_v_i32mf2(const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei8_v_i32m1(const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei8_v_i32m2(const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei8_v_i32m4(const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei8_v_i32m8(const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_i32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei16_v_i32mf2(const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei16_v_i32m1(const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei16_v_i32m2(const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei16_v_i32m4(const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei16_v_i32m8(const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_i32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei32_v_i32mf2(const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei32_v_i32m1(const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei32_v_i32m2(const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei32_v_i32m4(const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei32_v_i32m8(const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_i32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei64_v_i32mf2(const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei64_v_i32m1(const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei64_v_i32m2(const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei64_v_i32m4(const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei8_v_i64m1(const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei8_v_i64m2(const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei8_v_i64m4(const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei8_v_i64m8(const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei16_v_i64m1(const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei16_v_i64m2(const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei16_v_i64m4(const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei16_v_i64m8(const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei32_v_i64m1(const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei32_v_i64m2(const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei32_v_i64m4(const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei32_v_i64m8(const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei64_v_i64m1(const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei64_v_i64m2(const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei64_v_i64m4(const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei64_v_i64m8(const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei8_v_u8mf8(const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei8_v_u8mf4(const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei8_v_u8mf2(const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei8_v_u8m1(const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei8_v_u8m2(const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_u8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei8_v_u8m4(const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_u8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t testuxei8_v_u8m8(const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8_v_u8m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei16_v_u8mf8(const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei16_v_u8mf4(const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei16_v_u8mf2(const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei16_v_u8m1(const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei16_v_u8m2(const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_u8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei16_v_u8m4(const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_u8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei32_v_u8mf8(const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei32_v_u8mf4(const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei32_v_u8mf2(const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei32_v_u8m1(const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei32_v_u8m2(const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_u8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei64_v_u8mf8(const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei64_v_u8mf4(const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei64_v_u8mf2(const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei64_v_u8m1(const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei8_v_u16mf4(const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei8_v_u16mf2(const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei8_v_u16m1(const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei8_v_u16m2(const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei8_v_u16m4(const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_u16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei8_v_u16m8(const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_u16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei16_v_u16mf4(const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei16_v_u16mf2(const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei16_v_u16m1(const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei16_v_u16m2(const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei16_v_u16m4(const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_u16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei16_v_u16m8(const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_u16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei32_v_u16mf4(const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei32_v_u16mf2(const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei32_v_u16m1(const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei32_v_u16m2(const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei32_v_u16m4(const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_u16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei64_v_u16mf4(const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei64_v_u16mf2(const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei64_v_u16m1(const uint16_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei64_v_u16m2(const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei8_v_u32mf2(const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei8_v_u32m1(const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei8_v_u32m2(const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei8_v_u32m4(const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei8_v_u32m8(const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_u32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei16_v_u32mf2(const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei16_v_u32m1(const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei16_v_u32m2(const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei16_v_u32m4(const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei16_v_u32m8(const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_u32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei32_v_u32mf2(const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei32_v_u32m1(const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei32_v_u32m2(const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei32_v_u32m4(const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei32_v_u32m8(const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_u32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei64_v_u32mf2(const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei64_v_u32m1(const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei64_v_u32m2(const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei64_v_u32m4(const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei8_v_u64m1(const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei8_v_u64m2(const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei8_v_u64m4(const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei8_v_u64m8(const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei16_v_u64m1(const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei16_v_u64m2(const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei16_v_u64m4(const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei16_v_u64m8(const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei32_v_u64m1(const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei32_v_u64m2(const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei32_v_u64m4(const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei32_v_u64m8(const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei64_v_u64m1(const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei64_v_u64m2(const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei64_v_u64m4(const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei64_v_u64m8(const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei8_v_f32mf2(const float *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei8_v_f32m1(const float *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei8_v_f32m2(const float *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei8_v_f32m4(const float *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei8_v_f32m8(const float *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_f32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei16_v_f32mf2(const float *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei16_v_f32m1(const float *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei16_v_f32m2(const float *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei16_v_f32m4(const float *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei16_v_f32m8(const float *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_f32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei32_v_f32mf2(const float *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei32_v_f32m1(const float *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei32_v_f32m2(const float *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei32_v_f32m4(const float *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv16f32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei32_v_f32m8(const float *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_f32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei64_v_f32mf2(const float *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei64_v_f32m1(const float *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei64_v_f32m2(const float *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei64_v_f32m4(const float *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei8_v_f64m1(const double *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei8_v_f64m2(const double *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei8_v_f64m4(const double *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei8_v_f64m8(const double *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei16_v_f64m1(const double *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei16_v_f64m2(const double *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei16_v_f64m4(const double *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei16_v_f64m8(const double *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei32_v_f64m1(const double *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei32_v_f64m2(const double *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei32_v_f64m4(const double *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei32_v_f64m8(const double *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv1f64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei64_v_f64m1(const double *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv2f64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei64_v_f64m2(const double *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv4f64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei64_v_f64m4(const double *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.nxv8f64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei64_v_f64m8(const double *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei8_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei8_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei8_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei8_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei8_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_i8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei8_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_i8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t testuxei8_v_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8_v_i8m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei16_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei16_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei16_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei16_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei16_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_i8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei16_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_i8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei32_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei32_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei32_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei32_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei32_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_i8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei64_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei64_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei64_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei64_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei8_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei8_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei8_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei8_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei8_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_i16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei8_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_i16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei16_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei16_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei16_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei16_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei16_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_i16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei16_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_i16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei32_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei32_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei32_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei32_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei32_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_i16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei64_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei64_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei64_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei64_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei8_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei8_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei8_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei8_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei8_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_i32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei16_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei16_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei16_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei16_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei16_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_i32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei32_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei32_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei32_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei32_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei32_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_i32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei64_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei64_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei64_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei64_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei8_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei8_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei8_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei8_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei16_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei16_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei16_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei16_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei32_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei32_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei32_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei32_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei64_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei64_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei64_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei64_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei8_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei8_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei8_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei8_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei8_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_u8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei8_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_u8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t testuxei8_v_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vloxei8_v_u8m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei16_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei16_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei16_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei16_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei16_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_u8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei16_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_u8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei32_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei32_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei32_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei32_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei32_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_u8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei64_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei64_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei64_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei64_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei8_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei8_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei8_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei8_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei8_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_u16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei8_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vloxei8_v_u16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei16_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei16_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei16_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei16_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei16_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_u16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei16_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vloxei16_v_u16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei32_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei32_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei32_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei32_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei32_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_u16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei64_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei64_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei64_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei64_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei8_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei8_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei8_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei8_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei8_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_u32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei16_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei16_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei16_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei16_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei16_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_u32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei32_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei32_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei32_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei32_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei32_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_u32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei64_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei64_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei64_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei64_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei8_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei8_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei8_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei8_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei16_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei16_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei16_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei16_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei32_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei32_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei32_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei32_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei64_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei64_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei64_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei64_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei8_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei8_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei8_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei8_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei8_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint8m2_t bindex, size_t vl) { + return vloxei8_v_f32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei16_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei16_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei16_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei16_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei16_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint16m4_t bindex, size_t vl) { + return vloxei16_v_f32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei32_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei32_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei32_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei32_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv16f32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei32_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint32m8_t bindex, size_t vl) { + return vloxei32_v_f32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei64_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei64_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei64_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei64_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei8_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint8mf8_t bindex, size_t vl) { + return vloxei8_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei8_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint8mf4_t bindex, size_t vl) { + return vloxei8_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei8_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint8mf2_t bindex, size_t vl) { + return vloxei8_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei8_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint8m1_t bindex, size_t vl) { + return vloxei8_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei16_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint16mf4_t bindex, size_t vl) { + return vloxei16_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei16_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint16mf2_t bindex, size_t vl) { + return vloxei16_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei16_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint16m1_t bindex, size_t vl) { + return vloxei16_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei16_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint16m2_t bindex, size_t vl) { + return vloxei16_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei32_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint32mf2_t bindex, size_t vl) { + return vloxei32_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei32_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint32m1_t bindex, size_t vl) { + return vloxei32_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei32_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint32m2_t bindex, size_t vl) { + return vloxei32_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei32_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint32m4_t bindex, size_t vl) { + return vloxei32_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv1f64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei64_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint64m1_t bindex, size_t vl) { + return vloxei64_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv2f64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei64_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint64m2_t bindex, size_t vl) { + return vloxei64_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv4f64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei64_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint64m4_t bindex, size_t vl) { + return vloxei64_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vloxei.mask.nxv8f64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei64_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint64m8_t bindex, size_t vl) { + return vloxei64_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vluxei.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vluxei.c new file mode 100644 index 000000000000..ae34fbe1909a --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vluxei.c @@ -0,0 +1,6123 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S > /dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei8_v_i8mf8(const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei8_v_i8mf4(const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei8_v_i8mf2(const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei8_v_i8m1(const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei8_v_i8m2(const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_i8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei8_v_i8m4(const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_i8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t testuxei8_v_i8m8(const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8_v_i8m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei16_v_i8mf8(const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei16_v_i8mf4(const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei16_v_i8mf2(const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei16_v_i8m1(const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei16_v_i8m2(const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_i8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei16_v_i8m4(const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_i8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei32_v_i8mf8(const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei32_v_i8mf4(const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei32_v_i8mf2(const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei32_v_i8m1(const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei32_v_i8m2(const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_i8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei64_v_i8mf8(const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei64_v_i8mf4(const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei64_v_i8mf2(const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei64_v_i8m1(const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei8_v_i16mf4(const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei8_v_i16mf2(const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei8_v_i16m1(const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei8_v_i16m2(const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei8_v_i16m4(const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_i16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei8_v_i16m8(const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_i16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei16_v_i16mf4(const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei16_v_i16mf2(const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei16_v_i16m1(const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei16_v_i16m2(const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei16_v_i16m4(const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_i16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei16_v_i16m8(const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_i16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei32_v_i16mf4(const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei32_v_i16mf2(const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei32_v_i16m1(const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei32_v_i16m2(const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei32_v_i16m4(const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_i16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei64_v_i16mf4(const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei64_v_i16mf2(const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei64_v_i16m1(const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei64_v_i16m2(const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei8_v_i32mf2(const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei8_v_i32m1(const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei8_v_i32m2(const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei8_v_i32m4(const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei8_v_i32m8(const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_i32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei16_v_i32mf2(const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei16_v_i32m1(const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei16_v_i32m2(const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei16_v_i32m4(const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei16_v_i32m8(const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_i32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei32_v_i32mf2(const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei32_v_i32m1(const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei32_v_i32m2(const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei32_v_i32m4(const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei32_v_i32m8(const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_i32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei64_v_i32mf2(const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei64_v_i32m1(const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei64_v_i32m2(const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei64_v_i32m4(const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei8_v_i64m1(const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei8_v_i64m2(const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei8_v_i64m4(const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei8_v_i64m8(const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei16_v_i64m1(const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei16_v_i64m2(const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei16_v_i64m4(const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei16_v_i64m8(const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei32_v_i64m1(const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei32_v_i64m2(const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei32_v_i64m4(const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei32_v_i64m8(const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei64_v_i64m1(const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei64_v_i64m2(const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei64_v_i64m4(const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei64_v_i64m8(const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei8_v_u8mf8(const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei8_v_u8mf4(const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei8_v_u8mf2(const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei8_v_u8m1(const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei8_v_u8m2(const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_u8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei8_v_u8m4(const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_u8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv64i8.nxv64i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t testuxei8_v_u8m8(const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8_v_u8m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei16_v_u8mf8(const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei16_v_u8mf4(const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei16_v_u8mf2(const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei16_v_u8m1(const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei16_v_u8m2(const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_u8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i8.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei16_v_u8m4(const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_u8m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei32_v_u8mf8(const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei32_v_u8mf4(const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei32_v_u8mf2(const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei32_v_u8m1(const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i8.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei32_v_u8m2(const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_u8m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i8.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei64_v_u8mf8(const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u8mf8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i8.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei64_v_u8mf4(const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u8mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i8.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei64_v_u8mf2(const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u8mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i8.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei64_v_u8m1(const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u8m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei8_v_u16mf4(const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei8_v_u16mf2(const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei8_v_u16m1(const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei8_v_u16m2(const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei8_v_u16m4(const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_u16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei8_v_u16m8(const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_u16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei16_v_u16mf4(const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei16_v_u16mf2(const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei16_v_u16m1(const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei16_v_u16m2(const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei16_v_u16m4(const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_u16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv32i16.nxv32i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei16_v_u16m8(const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_u16m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei32_v_u16mf4(const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei32_v_u16mf2(const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei32_v_u16m1(const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei32_v_u16m2(const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i16.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei32_v_u16m4(const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_u16m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i16.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei64_v_u16mf4(const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u16mf4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i16.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei64_v_u16mf2(const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u16mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i16.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei64_v_u16m1(const uint16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u16m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i16.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei64_v_u16m2(const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u16m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei8_v_u32mf2(const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei8_v_u32m1(const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei8_v_u32m2(const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei8_v_u32m4(const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei8_v_u32m8(const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_u32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei16_v_u32mf2(const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei16_v_u32m1(const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei16_v_u32m2(const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei16_v_u32m4(const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei16_v_u32m8(const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_u32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei32_v_u32mf2(const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei32_v_u32m1(const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei32_v_u32m2(const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei32_v_u32m4(const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16i32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei32_v_u32m8(const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_u32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei64_v_u32mf2(const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei64_v_u32m1(const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei64_v_u32m2(const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei64_v_u32m4(const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei8_v_u64m1(const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei8_v_u64m2(const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei8_v_u64m4(const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei8_v_u64m8(const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei16_v_u64m1(const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei16_v_u64m2(const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei16_v_u64m4(const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei16_v_u64m8(const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei32_v_u64m1(const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei32_v_u64m2(const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei32_v_u64m4(const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei32_v_u64m8(const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1i64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei64_v_u64m1(const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2i64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei64_v_u64m2(const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4i64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei64_v_u64m4(const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8i64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei64_v_u64m8(const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei8_v_f32mf2(const float *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei8_v_f32m1(const float *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei8_v_f32m2(const float *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei8_v_f32m4(const float *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei8_v_f32m8(const float *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_f32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei16_v_f32mf2(const float *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei16_v_f32m1(const float *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei16_v_f32m2(const float *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei16_v_f32m4(const float *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei16_v_f32m8(const float *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_f32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei32_v_f32mf2(const float *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei32_v_f32m1(const float *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei32_v_f32m2(const float *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei32_v_f32m4(const float *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv16f32.nxv16i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei32_v_f32m8(const float *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_f32m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f32.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei64_v_f32mf2(const float *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_f32mf2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f32.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei64_v_f32m1(const float *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_f32m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f32.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei64_v_f32m2(const float *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_f32m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f32.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei64_v_f32m4(const float *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_f32m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei8_v_f64m1(const double *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei8_v_f64m2(const double *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei8_v_f64m4(const double *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i8.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i8.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei8_v_f64m8(const double *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei16_v_f64m1(const double *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei16_v_f64m2(const double *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei16_v_f64m4(const double *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i16.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i16.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei16_v_f64m8(const double *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei32_v_f64m1(const double *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei32_v_f64m2(const double *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei32_v_f64m4(const double *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i32.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i32.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei32_v_f64m8(const double *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv1f64.nxv1i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei64_v_f64m1(const double *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_f64m1(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv2f64.nxv2i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei64_v_f64m2(const double *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_f64m2(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv4f64.nxv4i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei64_v_f64m4(const double *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_f64m4(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i64.i32(* [[TMP0]], [[BINDEX:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.nxv8f64.nxv8i64.i64(* [[TMP0]], [[BINDEX:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei64_v_f64m8(const double *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_f64m8(base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei8_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei8_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei8_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei8_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei8_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_i8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei8_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_i8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m8_t testuxei8_v_i8m8_m(vbool1_t mask, vint8m8_t maskedoff, const int8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8_v_i8m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei16_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei16_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei16_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei16_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei16_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_i8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m4_t testuxei16_v_i8m4_m(vbool2_t mask, vint8m4_t maskedoff, const int8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_i8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei32_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei32_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei32_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei32_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m2_t testuxei32_v_i8m2_m(vbool4_t mask, vint8m2_t maskedoff, const int8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_i8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf8_t testuxei64_v_i8mf8_m(vbool64_t mask, vint8mf8_t maskedoff, const int8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf4_t testuxei64_v_i8mf4_m(vbool32_t mask, vint8mf4_t maskedoff, const int8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8mf2_t testuxei64_v_i8mf2_m(vbool16_t mask, vint8mf2_t maskedoff, const int8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint8m1_t testuxei64_v_i8m1_m(vbool8_t mask, vint8m1_t maskedoff, const int8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei8_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei8_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei8_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei8_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei8_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_i16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei8_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_i16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei16_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei16_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei16_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei16_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei16_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_i16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m8_t testuxei16_v_i16m8_m(vbool2_t mask, vint16m8_t maskedoff, const int16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_i16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei32_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei32_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei32_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei32_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m4_t testuxei32_v_i16m4_m(vbool4_t mask, vint16m4_t maskedoff, const int16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_i16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf4_t testuxei64_v_i16mf4_m(vbool64_t mask, vint16mf4_t maskedoff, const int16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16mf2_t testuxei64_v_i16mf2_m(vbool32_t mask, vint16mf2_t maskedoff, const int16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m1_t testuxei64_v_i16m1_m(vbool16_t mask, vint16m1_t maskedoff, const int16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint16m2_t testuxei64_v_i16m2_m(vbool8_t mask, vint16m2_t maskedoff, const int16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei8_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei8_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei8_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei8_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei8_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_i32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei16_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei16_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei16_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei16_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei16_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_i32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei32_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei32_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei32_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei32_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m8_t testuxei32_v_i32m8_m(vbool4_t mask, vint32m8_t maskedoff, const int32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_i32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32mf2_t testuxei64_v_i32mf2_m(vbool64_t mask, vint32mf2_t maskedoff, const int32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m1_t testuxei64_v_i32m1_m(vbool32_t mask, vint32m1_t maskedoff, const int32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m2_t testuxei64_v_i32m2_m(vbool16_t mask, vint32m2_t maskedoff, const int32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint32m4_t testuxei64_v_i32m4_m(vbool8_t mask, vint32m4_t maskedoff, const int32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei8_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei8_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei8_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei8_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei16_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei16_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei16_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei16_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei32_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei32_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei32_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei32_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m1_t testuxei64_v_i64m1_m(vbool64_t mask, vint64m1_t maskedoff, const int64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_i64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m2_t testuxei64_v_i64m2_m(vbool32_t mask, vint64m2_t maskedoff, const int64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_i64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m4_t testuxei64_v_i64m4_m(vbool16_t mask, vint64m4_t maskedoff, const int64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_i64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vint64m8_t testuxei64_v_i64m8_m(vbool8_t mask, vint64m8_t maskedoff, const int64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_i64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei8_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei8_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei8_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei8_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei8_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_u8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei8_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_u8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv64i8.nxv64i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m8_t testuxei8_v_u8m8_m(vbool1_t mask, vuint8m8_t maskedoff, const uint8_t *base, vuint8m8_t bindex, size_t vl) { + return vluxei8_v_u8m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei16_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei16_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei16_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei16_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei16_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_u8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i8.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m4_t testuxei16_v_u8m4_m(vbool2_t mask, vuint8m4_t maskedoff, const uint8_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_u8m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei32_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei32_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei32_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei32_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i8.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m2_t testuxei32_v_u8m2_m(vbool4_t mask, vuint8m2_t maskedoff, const uint8_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_u8m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i8.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf8_t testuxei64_v_u8mf8_m(vbool64_t mask, vuint8mf8_t maskedoff, const uint8_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u8mf8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i8.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf4_t testuxei64_v_u8mf4_m(vbool32_t mask, vuint8mf4_t maskedoff, const uint8_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u8mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i8.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8mf2_t testuxei64_v_u8mf2_m(vbool16_t mask, vuint8mf2_t maskedoff, const uint8_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u8mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i8.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint8m1_t testuxei64_v_u8m1_m(vbool8_t mask, vuint8m1_t maskedoff, const uint8_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u8m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei8_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei8_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei8_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei8_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei8_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_u16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei8_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint8m4_t bindex, size_t vl) { + return vluxei8_v_u16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei16_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei16_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei16_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei16_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei16_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_u16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv32i16.nxv32i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m8_t testuxei16_v_u16m8_m(vbool2_t mask, vuint16m8_t maskedoff, const uint16_t *base, vuint16m8_t bindex, size_t vl) { + return vluxei16_v_u16m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei32_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei32_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei32_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei32_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i16.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m4_t testuxei32_v_u16m4_m(vbool4_t mask, vuint16m4_t maskedoff, const uint16_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_u16m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i16.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf4_t testuxei64_v_u16mf4_m(vbool64_t mask, vuint16mf4_t maskedoff, const uint16_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u16mf4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i16.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16mf2_t testuxei64_v_u16mf2_m(vbool32_t mask, vuint16mf2_t maskedoff, const uint16_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u16mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i16.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m1_t testuxei64_v_u16m1_m(vbool16_t mask, vuint16m1_t maskedoff, const uint16_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u16m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i16.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint16m2_t testuxei64_v_u16m2_m(vbool8_t mask, vuint16m2_t maskedoff, const uint16_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u16m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei8_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei8_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei8_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei8_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei8_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_u32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei16_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei16_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei16_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei16_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei16_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_u32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei32_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei32_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei32_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei32_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16i32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m8_t testuxei32_v_u32m8_m(vbool4_t mask, vuint32m8_t maskedoff, const uint32_t *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_u32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32mf2_t testuxei64_v_u32mf2_m(vbool64_t mask, vuint32mf2_t maskedoff, const uint32_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m1_t testuxei64_v_u32m1_m(vbool32_t mask, vuint32m1_t maskedoff, const uint32_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m2_t testuxei64_v_u32m2_m(vbool16_t mask, vuint32m2_t maskedoff, const uint32_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint32m4_t testuxei64_v_u32m4_m(vbool8_t mask, vuint32m4_t maskedoff, const uint32_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei8_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei8_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei8_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei8_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei16_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei16_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei16_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei16_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei32_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei32_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei32_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei32_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1i64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m1_t testuxei64_v_u64m1_m(vbool64_t mask, vuint64m1_t maskedoff, const uint64_t *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_u64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2i64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m2_t testuxei64_v_u64m2_m(vbool32_t mask, vuint64m2_t maskedoff, const uint64_t *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_u64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4i64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m4_t testuxei64_v_u64m4_m(vbool16_t mask, vuint64m4_t maskedoff, const uint64_t *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_u64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8i64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vuint64m8_t testuxei64_v_u64m8_m(vbool8_t mask, vuint64m8_t maskedoff, const uint64_t *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_u64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei8_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei8_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei8_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei8_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei8_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint8m2_t bindex, size_t vl) { + return vluxei8_v_f32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei16_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei16_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei16_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei16_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei16_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint16m4_t bindex, size_t vl) { + return vluxei16_v_f32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei32_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei32_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei32_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei32_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv16f32.nxv16i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m8_t testuxei32_v_f32m8_m(vbool4_t mask, vfloat32m8_t maskedoff, const float *base, vuint32m8_t bindex, size_t vl) { + return vluxei32_v_f32m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f32.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32mf2_t testuxei64_v_f32mf2_m(vbool64_t mask, vfloat32mf2_t maskedoff, const float *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_f32mf2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f32.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m1_t testuxei64_v_f32m1_m(vbool32_t mask, vfloat32m1_t maskedoff, const float *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_f32m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f32.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m2_t testuxei64_v_f32m2_m(vbool16_t mask, vfloat32m2_t maskedoff, const float *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_f32m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f32.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat32m4_t testuxei64_v_f32m4_m(vbool8_t mask, vfloat32m4_t maskedoff, const float *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_f32m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei8_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint8mf8_t bindex, size_t vl) { + return vluxei8_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei8_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint8mf4_t bindex, size_t vl) { + return vluxei8_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei8_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint8mf2_t bindex, size_t vl) { + return vluxei8_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei8_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i8.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei8_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i8.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei8_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint8m1_t bindex, size_t vl) { + return vluxei8_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei16_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint16mf4_t bindex, size_t vl) { + return vluxei16_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei16_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint16mf2_t bindex, size_t vl) { + return vluxei16_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei16_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint16m1_t bindex, size_t vl) { + return vluxei16_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei16_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i16.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei16_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i16.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei16_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint16m2_t bindex, size_t vl) { + return vluxei16_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei32_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint32mf2_t bindex, size_t vl) { + return vluxei32_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei32_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint32m1_t bindex, size_t vl) { + return vluxei32_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei32_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint32m2_t bindex, size_t vl) { + return vluxei32_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei32_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i32.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei32_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i32.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei32_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint32m4_t bindex, size_t vl) { + return vluxei32_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv1f64.nxv1i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m1_t testuxei64_v_f64m1_m(vbool64_t mask, vfloat64m1_t maskedoff, const double *base, vuint64m1_t bindex, size_t vl) { + return vluxei64_v_f64m1_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv2f64.nxv2i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m2_t testuxei64_v_f64m2_m(vbool32_t mask, vfloat64m2_t maskedoff, const double *base, vuint64m2_t bindex, size_t vl) { + return vluxei64_v_f64m2_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv4f64.nxv4i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m4_t testuxei64_v_f64m4_m(vbool16_t mask, vfloat64m4_t maskedoff, const double *base, vuint64m4_t bindex, size_t vl) { + return vluxei64_v_f64m4_m(mask, maskedoff, base, bindex, vl); +} + +// CHECK-RV32-LABEL: @testuxei64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i64.i32( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret [[TMP1]] +// +// CHECK-RV64-LABEL: @testuxei64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call @llvm.riscv.vluxei.mask.nxv8f64.nxv8i64.i64( [[MASKEDOFF:%.*]], * [[TMP0]], [[BINDEX:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret [[TMP1]] +// +vfloat64m8_t testuxei64_v_f64m8_m(vbool8_t mask, vfloat64m8_t maskedoff, const double *base, vuint64m8_t bindex, size_t vl) { + return vluxei64_v_f64m8_m(mask, maskedoff, base, bindex, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vse.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vse.c new file mode 100644 index 000000000000..0f5d3170298b --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vse.c @@ -0,0 +1,1707 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +f -target-feature +d -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf8(int8_t *base, vint8mf8_t value, size_t vl) { + return vse8_v_i8mf8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf4(int8_t *base, vint8mf4_t value, size_t vl) { + return vse8_v_i8mf4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf2(int8_t *base, vint8mf2_t value, size_t vl) { + return vse8_v_i8mf2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m1(int8_t *base, vint8m1_t value, size_t vl) { + return vse8_v_i8m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m2(int8_t *base, vint8m2_t value, size_t vl) { + return vse8_v_i8m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m4(int8_t *base, vint8m4_t value, size_t vl) { + return vse8_v_i8m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m8(int8_t *base, vint8m8_t value, size_t vl) { + return vse8_v_i8m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf4(int16_t *base, vint16mf4_t value, size_t vl) { + return vse16_v_i16mf4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf2(int16_t *base, vint16mf2_t value, size_t vl) { + return vse16_v_i16mf2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m1(int16_t *base, vint16m1_t value, size_t vl) { + return vse16_v_i16m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m2(int16_t *base, vint16m2_t value, size_t vl) { + return vse16_v_i16m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m4(int16_t *base, vint16m4_t value, size_t vl) { + return vse16_v_i16m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m8(int16_t *base, vint16m8_t value, size_t vl) { + return vse16_v_i16m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32mf2(int32_t *base, vint32mf2_t value, size_t vl) { + return vse32_v_i32mf2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m1(int32_t *base, vint32m1_t value, size_t vl) { + return vse32_v_i32m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m2(int32_t *base, vint32m2_t value, size_t vl) { + return vse32_v_i32m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m4(int32_t *base, vint32m4_t value, size_t vl) { + return vse32_v_i32m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m8(int32_t *base, vint32m8_t value, size_t vl) { + return vse32_v_i32m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m1(int64_t *base, vint64m1_t value, size_t vl) { + return vse64_v_i64m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m2(int64_t *base, vint64m2_t value, size_t vl) { + return vse64_v_i64m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m4(int64_t *base, vint64m4_t value, size_t vl) { + return vse64_v_i64m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m8(int64_t *base, vint64m8_t value, size_t vl) { + return vse64_v_i64m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf8(uint8_t *base, vuint8mf8_t value, size_t vl) { + return vse8_v_u8mf8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf4(uint8_t *base, vuint8mf4_t value, size_t vl) { + return vse8_v_u8mf4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf2(uint8_t *base, vuint8mf2_t value, size_t vl) { + return vse8_v_u8mf2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m1(uint8_t *base, vuint8m1_t value, size_t vl) { + return vse8_v_u8m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m2(uint8_t *base, vuint8m2_t value, size_t vl) { + return vse8_v_u8m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m4(uint8_t *base, vuint8m4_t value, size_t vl) { + return vse8_v_u8m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m8(uint8_t *base, vuint8m8_t value, size_t vl) { + return vse8_v_u8m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf4(uint16_t *base, vuint16mf4_t value, size_t vl) { + return vse16_v_u16mf4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf2(uint16_t *base, vuint16mf2_t value, size_t vl) { + return vse16_v_u16mf2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m1(uint16_t *base, vuint16m1_t value, size_t vl) { + return vse16_v_u16m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m2(uint16_t *base, vuint16m2_t value, size_t vl) { + return vse16_v_u16m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m4(uint16_t *base, vuint16m4_t value, size_t vl) { + return vse16_v_u16m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m8(uint16_t *base, vuint16m8_t value, size_t vl) { + return vse16_v_u16m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32mf2(uint32_t *base, vuint32mf2_t value, size_t vl) { + return vse32_v_u32mf2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m1(uint32_t *base, vuint32m1_t value, size_t vl) { + return vse32_v_u32m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m2(uint32_t *base, vuint32m2_t value, size_t vl) { + return vse32_v_u32m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m4(uint32_t *base, vuint32m4_t value, size_t vl) { + return vse32_v_u32m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m8(uint32_t *base, vuint32m8_t value, size_t vl) { + return vse32_v_u32m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m1(uint64_t *base, vuint64m1_t value, size_t vl) { + return vse64_v_u64m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m2(uint64_t *base, vuint64m2_t value, size_t vl) { + return vse64_v_u64m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m4(uint64_t *base, vuint64m4_t value, size_t vl) { + return vse64_v_u64m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m8(uint64_t *base, vuint64m8_t value, size_t vl) { + return vse64_v_u64m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32mf2(float *base, vfloat32mf2_t value, size_t vl) { + return vse32_v_f32mf2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m1(float *base, vfloat32m1_t value, size_t vl) { + return vse32_v_f32m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m2(float *base, vfloat32m2_t value, size_t vl) { + return vse32_v_f32m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m4(float *base, vfloat32m4_t value, size_t vl) { + return vse32_v_f32m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv16f32.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv16f32.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m8(float *base, vfloat32m8_t value, size_t vl) { + return vse32_v_f32m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv1f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv1f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m1(double *base, vfloat64m1_t value, size_t vl) { + return vse64_v_f64m1(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv2f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv2f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m2(double *base, vfloat64m2_t value, size_t vl) { + return vse64_v_f64m2(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv4f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv4f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m4(double *base, vfloat64m4_t value, size_t vl) { + return vse64_v_f64m4(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.nxv8f64.i32( [[VALUE:%.*]], * [[TMP0]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.nxv8f64.i64( [[VALUE:%.*]], * [[TMP0]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m8(double *base, vfloat64m8_t value, size_t vl) { + return vse64_v_f64m8(base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf8_m(vbool64_t mask, int8_t *base, vint8mf8_t value, size_t vl) { + return vse8_v_i8mf8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf4_m(vbool32_t mask, int8_t *base, vint8mf4_t value, size_t vl) { + return vse8_v_i8mf4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8mf2_m(vbool16_t mask, int8_t *base, vint8mf2_t value, size_t vl) { + return vse8_v_i8mf2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m1_m(vbool8_t mask, int8_t *base, vint8m1_t value, size_t vl) { + return vse8_v_i8m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m2_m(vbool4_t mask, int8_t *base, vint8m2_t value, size_t vl) { + return vse8_v_i8m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m4_m(vbool2_t mask, int8_t *base, vint8m4_t value, size_t vl) { + return vse8_v_i8m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_i8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_i8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_i8m8_m(vbool1_t mask, int8_t *base, vint8m8_t value, size_t vl) { + return vse8_v_i8m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf4_m(vbool64_t mask, int16_t *base, vint16mf4_t value, size_t vl) { + return vse16_v_i16mf4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16mf2_m(vbool32_t mask, int16_t *base, vint16mf2_t value, size_t vl) { + return vse16_v_i16mf2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m1_m(vbool16_t mask, int16_t *base, vint16m1_t value, size_t vl) { + return vse16_v_i16m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m2_m(vbool8_t mask, int16_t *base, vint16m2_t value, size_t vl) { + return vse16_v_i16m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m4_m(vbool4_t mask, int16_t *base, vint16m4_t value, size_t vl) { + return vse16_v_i16m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_i16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_i16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_i16m8_m(vbool2_t mask, int16_t *base, vint16m8_t value, size_t vl) { + return vse16_v_i16m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32mf2_m(vbool64_t mask, int32_t *base, vint32mf2_t value, size_t vl) { + return vse32_v_i32mf2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m1_m(vbool32_t mask, int32_t *base, vint32m1_t value, size_t vl) { + return vse32_v_i32m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m2_m(vbool16_t mask, int32_t *base, vint32m2_t value, size_t vl) { + return vse32_v_i32m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m4_m(vbool8_t mask, int32_t *base, vint32m4_t value, size_t vl) { + return vse32_v_i32m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_i32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_i32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_i32m8_m(vbool4_t mask, int32_t *base, vint32m8_t value, size_t vl) { + return vse32_v_i32m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m1_m(vbool64_t mask, int64_t *base, vint64m1_t value, size_t vl) { + return vse64_v_i64m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m2_m(vbool32_t mask, int64_t *base, vint64m2_t value, size_t vl) { + return vse64_v_i64m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m4_m(vbool16_t mask, int64_t *base, vint64m4_t value, size_t vl) { + return vse64_v_i64m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_i64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_i64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_i64m8_m(vbool8_t mask, int64_t *base, vint64m8_t value, size_t vl) { + return vse64_v_i64m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf8_m(vbool64_t mask, uint8_t *base, vuint8mf8_t value, size_t vl) { + return vse8_v_u8mf8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf4_m(vbool32_t mask, uint8_t *base, vuint8mf4_t value, size_t vl) { + return vse8_v_u8mf4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8mf2_m(vbool16_t mask, uint8_t *base, vuint8mf2_t value, size_t vl) { + return vse8_v_u8mf2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m1_m(vbool8_t mask, uint8_t *base, vuint8m1_t value, size_t vl) { + return vse8_v_u8m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m2_m(vbool4_t mask, uint8_t *base, vuint8m2_t value, size_t vl) { + return vse8_v_u8m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m4_m(vbool2_t mask, uint8_t *base, vuint8m4_t value, size_t vl) { + return vse8_v_u8m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse8_v_u8m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse8_v_u8m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i8* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv64i8.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse8_v_u8m8_m(vbool1_t mask, uint8_t *base, vuint8m8_t value, size_t vl) { + return vse8_v_u8m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf4_m(vbool64_t mask, uint16_t *base, vuint16mf4_t value, size_t vl) { + return vse16_v_u16mf4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16mf2_m(vbool32_t mask, uint16_t *base, vuint16mf2_t value, size_t vl) { + return vse16_v_u16mf2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m1_m(vbool16_t mask, uint16_t *base, vuint16m1_t value, size_t vl) { + return vse16_v_u16m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m2_m(vbool8_t mask, uint16_t *base, vuint16m2_t value, size_t vl) { + return vse16_v_u16m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m4_m(vbool4_t mask, uint16_t *base, vuint16m4_t value, size_t vl) { + return vse16_v_u16m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse16_v_u16m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse16_v_u16m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i16* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv32i16.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse16_v_u16m8_m(vbool2_t mask, uint16_t *base, vuint16m8_t value, size_t vl) { + return vse16_v_u16m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32mf2_m(vbool64_t mask, uint32_t *base, vuint32mf2_t value, size_t vl) { + return vse32_v_u32mf2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m1_m(vbool32_t mask, uint32_t *base, vuint32m1_t value, size_t vl) { + return vse32_v_u32m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m2_m(vbool16_t mask, uint32_t *base, vuint32m2_t value, size_t vl) { + return vse32_v_u32m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m4_m(vbool8_t mask, uint32_t *base, vuint32m4_t value, size_t vl) { + return vse32_v_u32m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_u32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_u32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i32* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16i32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_u32m8_m(vbool4_t mask, uint32_t *base, vuint32m8_t value, size_t vl) { + return vse32_v_u32m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m1_m(vbool64_t mask, uint64_t *base, vuint64m1_t value, size_t vl) { + return vse64_v_u64m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m2_m(vbool32_t mask, uint64_t *base, vuint64m2_t value, size_t vl) { + return vse64_v_u64m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m4_m(vbool16_t mask, uint64_t *base, vuint64m4_t value, size_t vl) { + return vse64_v_u64m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_u64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_u64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast i64* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8i64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_u64m8_m(vbool8_t mask, uint64_t *base, vuint64m8_t value, size_t vl) { + return vse64_v_u64m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32mf2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32mf2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32mf2_m(vbool64_t mask, float *base, vfloat32mf2_t value, size_t vl) { + return vse32_v_f32mf2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m1_m(vbool32_t mask, float *base, vfloat32m1_t value, size_t vl) { + return vse32_v_f32m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m2_m(vbool16_t mask, float *base, vfloat32m2_t value, size_t vl) { + return vse32_v_f32m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m4_m(vbool8_t mask, float *base, vfloat32m4_t value, size_t vl) { + return vse32_v_f32m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse32_v_f32m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv16f32.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse32_v_f32m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast float* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv16f32.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse32_v_f32m8_m(vbool4_t mask, float *base, vfloat32m8_t value, size_t vl) { + return vse32_v_f32m8_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m1_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv1f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m1_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv1f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m1_m(vbool64_t mask, double *base, vfloat64m1_t value, size_t vl) { + return vse64_v_f64m1_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m2_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv2f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m2_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv2f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m2_m(vbool32_t mask, double *base, vfloat64m2_t value, size_t vl) { + return vse64_v_f64m2_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m4_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv4f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m4_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv4f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m4_m(vbool16_t mask, double *base, vfloat64m4_t value, size_t vl) { + return vse64_v_f64m4_m(mask, base, value, vl); +} + +// CHECK-RV32-LABEL: @test_vse64_v_f64m8_m( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV32-NEXT: call void @llvm.riscv.vse.mask.nxv8f64.i32( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i32 [[VL:%.*]]) +// CHECK-RV32-NEXT: ret void +// +// CHECK-RV64-LABEL: @test_vse64_v_f64m8_m( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = bitcast double* [[BASE:%.*]] to * +// CHECK-RV64-NEXT: call void @llvm.riscv.vse.mask.nxv8f64.i64( [[VALUE:%.*]], * [[TMP0]], [[MASK:%.*]], i64 [[VL:%.*]]) +// CHECK-RV64-NEXT: ret void +// +void test_vse64_v_f64m8_m(vbool8_t mask, double *base, vfloat64m8_t value, size_t vl) { + return vse64_v_f64m8_m(mask, base, value, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vsetvl.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vsetvl.c new file mode 100644 index 000000000000..5d68209d88a7 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vsetvl.c @@ -0,0 +1,451 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-v -emit-llvm -o - %s \ +// RUN: | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-v -emit-llvm -o - %s \ +// RUN: | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vsetvl_e8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 0, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 0, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e8m1(size_t avl) { + return vsetvl_e8m1(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 0, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 0, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e8m2(size_t avl) { + return vsetvl_e8m2(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 0, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 0, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e8m4(size_t avl) { + return vsetvl_e8m4(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 0, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 0, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e8m8(size_t avl) { + return vsetvl_e8m8(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 0, i32 7) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 0, i64 7) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e8mf2(size_t avl) { + return vsetvl_e8mf2(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 0, i32 6) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 0, i64 6) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e8mf4(size_t avl) { + return vsetvl_e8mf4(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 0, i32 5) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 0, i64 5) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e8mf8(size_t avl) { + return vsetvl_e8mf8(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 1, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 1, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e16m1(size_t avl) { + return vsetvl_e16m1(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 1, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 1, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e16m2(size_t avl) { + return vsetvl_e16m2(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 1, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 1, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e16m4(size_t avl) { + return vsetvl_e16m4(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 1, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 1, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e16m8(size_t avl) { + return vsetvl_e16m8(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 1, i32 7) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 1, i64 7) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e16mf2(size_t avl) { + return vsetvl_e16mf2(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 1, i32 6) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 1, i64 6) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e16mf4(size_t avl) { + return vsetvl_e16mf4(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 2, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 2, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e32m1(size_t avl) { + return vsetvl_e32m1(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 2, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 2, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e32m2(size_t avl) { + return vsetvl_e32m2(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 2, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 2, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e32m4(size_t avl) { + return vsetvl_e32m4(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 2, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 2, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e32m8(size_t avl) { + return vsetvl_e32m8(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 2, i32 7) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 2, i64 7) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e32mf2(size_t avl) { + return vsetvl_e32mf2(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 3, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 3, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e64m1(size_t avl) { + return vsetvl_e64m1(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 3, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 3, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e64m2(size_t avl) { + return vsetvl_e64m2(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 3, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 3, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e64m4(size_t avl) { + return vsetvl_e64m4(avl); +} + +// CHECK-RV32-LABEL: @test_vsetvl_e64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[AVL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[AVL:%.*]], i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, i32* [[AVL_ADDR]], align 4 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.vsetvli.i32(i32 [[TMP0]], i32 3, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP1]] +// +// CHECK-RV64-LABEL: @test_vsetvl_e64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[AVL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-RV64-NEXT: store i64 [[AVL:%.*]], i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, i64* [[AVL_ADDR]], align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[TMP0]], i64 3, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP1]] +// +size_t test_vsetvl_e64m8(size_t avl) { + return vsetvl_e64m8(avl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vsetvlmax.c b/clang/test/CodeGen/RISCV/rvv-intrinsics/vsetvlmax.c new file mode 100644 index 000000000000..447ca0595f0b --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vsetvlmax.c @@ -0,0 +1,319 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-v -emit-llvm -o - %s \ +// RUN: | FileCheck --check-prefix=CHECK-RV32 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-v -emit-llvm -o - %s \ +// RUN: | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +m -target-feature +experimental-v \ +// RUN: -Werror -Wall -o - %s -S >/dev/null 2>&1 | FileCheck --check-prefix=ASM --allow-empty %s + +// ASM-NOT: warning +#include + +// CHECK-RV32-LABEL: @test_vsetvlmax_e8m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 0, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e8m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e8m1() { + return vsetvlmax_e8m1(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e8m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 0, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e8m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e8m2() { + return vsetvlmax_e8m2(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e8m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 0, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e8m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e8m4() { + return vsetvlmax_e8m4(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e8m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 0, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e8m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e8m8() { + return vsetvlmax_e8m8(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e8mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 0, i32 7) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e8mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 7) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e8mf2() { + return vsetvlmax_e8mf2(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e8mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 0, i32 6) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e8mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 6) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e8mf4() { + return vsetvlmax_e8mf4(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e8mf8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 0, i32 5) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e8mf8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 5) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e8mf8() { + return vsetvlmax_e8mf8(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e16m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 1, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e16m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e16m1() { + return vsetvlmax_e16m1(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e16m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 1, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e16m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e16m2() { + return vsetvlmax_e16m2(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e16m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 1, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e16m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e16m4() { + return vsetvlmax_e16m4(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e16m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 1, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e16m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e16m8() { + return vsetvlmax_e16m8(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e16mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 1, i32 7) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e16mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 7) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e16mf2() { + return vsetvlmax_e16mf2(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e16mf4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 1, i32 6) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e16mf4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 6) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e16mf4() { + return vsetvlmax_e16mf4(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e32m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 2, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e32m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 2, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e32m1() { + return vsetvlmax_e32m1(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e32m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 2, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e32m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 2, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e32m2() { + return vsetvlmax_e32m2(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e32m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 2, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e32m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 2, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e32m4() { + return vsetvlmax_e32m4(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e32m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 2, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e32m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 2, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e32m8() { + return vsetvlmax_e32m8(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e32mf2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 2, i32 7) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e32mf2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 2, i64 7) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e32mf2() { + return vsetvlmax_e32mf2(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e64m1( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 3, i32 0) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e64m1( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 0) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e64m1() { + return vsetvlmax_e64m1(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e64m2( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 3, i32 1) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e64m2( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 1) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e64m2() { + return vsetvlmax_e64m2(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e64m4( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 3, i32 2) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e64m4( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 2) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e64m4() { + return vsetvlmax_e64m4(); +} + +// CHECK-RV32-LABEL: @test_vsetvlmax_e64m8( +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.vsetvlimax.i32(i32 3, i32 3) +// CHECK-RV32-NEXT: ret i32 [[TMP0]] +// +// CHECK-RV64-LABEL: @test_vsetvlmax_e64m8( +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 3) +// CHECK-RV64-NEXT: ret i64 [[TMP0]] +// +size_t test_vsetvlmax_e64m8() { + return vsetvlmax_e64m8(); +} diff --git a/clang/test/CodeGen/RISCV/vadd.c b/clang/test/CodeGen/RISCV/vadd.c deleted file mode 100644 index cc2e52f725a6..000000000000 --- a/clang/test/CodeGen/RISCV/vadd.c +++ /dev/null @@ -1,2648 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-v \ -// RUN: -O2 -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-RV64-O2 %s -// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-v \ -// RUN: -O2 -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-RV32-O2 %s - -#include -#include - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.nxv8i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.nxv8i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m1_t test_vadd_vv_i8m1_vl(__rvv_int8m1_t arg_0, __rvv_int8m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i8m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m1_t test_vadd_vv_i8m1_m_vl(__rvv_bool8_t arg_0, __rvv_int8m1_t arg_1, __rvv_int8m1_t arg_2, __rvv_int8m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i8m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.nxv4i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.nxv4i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m1_t test_vadd_vv_i16m1_vl(__rvv_int16m1_t arg_0, __rvv_int16m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i16m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m1_t test_vadd_vv_i16m1_m_vl(__rvv_bool16_t arg_0, __rvv_int16m1_t arg_1, __rvv_int16m1_t arg_2, __rvv_int16m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i16m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.nxv2i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.nxv2i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m1_t test_vadd_vv_i32m1_vl(__rvv_int32m1_t arg_0, __rvv_int32m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i32m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m1_t test_vadd_vv_i32m1_m_vl(__rvv_bool32_t arg_0, __rvv_int32m1_t arg_1, __rvv_int32m1_t arg_2, __rvv_int32m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i32m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.nxv1i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.nxv1i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m1_t test_vadd_vv_i64m1_vl(__rvv_int64m1_t arg_0, __rvv_int64m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i64m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m1_t test_vadd_vv_i64m1_m_vl(__rvv_bool64_t arg_0, __rvv_int64m1_t arg_1, __rvv_int64m1_t arg_2, __rvv_int64m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i64m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.nxv16i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.nxv16i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m2_t test_vadd_vv_i8m2_vl(__rvv_int8m2_t arg_0, __rvv_int8m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i8m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m2_t test_vadd_vv_i8m2_m_vl(__rvv_bool4_t arg_0, __rvv_int8m2_t arg_1, __rvv_int8m2_t arg_2, __rvv_int8m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i8m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.nxv8i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.nxv8i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m2_t test_vadd_vv_i16m2_vl(__rvv_int16m2_t arg_0, __rvv_int16m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i16m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m2_t test_vadd_vv_i16m2_m_vl(__rvv_bool8_t arg_0, __rvv_int16m2_t arg_1, __rvv_int16m2_t arg_2, __rvv_int16m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i16m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.nxv4i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.nxv4i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m2_t test_vadd_vv_i32m2_vl(__rvv_int32m2_t arg_0, __rvv_int32m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i32m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m2_t test_vadd_vv_i32m2_m_vl(__rvv_bool16_t arg_0, __rvv_int32m2_t arg_1, __rvv_int32m2_t arg_2, __rvv_int32m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i32m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.nxv2i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.nxv2i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m2_t test_vadd_vv_i64m2_vl(__rvv_int64m2_t arg_0, __rvv_int64m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i64m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m2_t test_vadd_vv_i64m2_m_vl(__rvv_bool32_t arg_0, __rvv_int64m2_t arg_1, __rvv_int64m2_t arg_2, __rvv_int64m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i64m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.nxv32i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.nxv32i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m4_t test_vadd_vv_i8m4_vl(__rvv_int8m4_t arg_0, __rvv_int8m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i8m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m4_t test_vadd_vv_i8m4_m_vl(__rvv_bool2_t arg_0, __rvv_int8m4_t arg_1, __rvv_int8m4_t arg_2, __rvv_int8m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i8m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.nxv16i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.nxv16i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m4_t test_vadd_vv_i16m4_vl(__rvv_int16m4_t arg_0, __rvv_int16m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i16m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m4_t test_vadd_vv_i16m4_m_vl(__rvv_bool4_t arg_0, __rvv_int16m4_t arg_1, __rvv_int16m4_t arg_2, __rvv_int16m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i16m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.nxv8i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.nxv8i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m4_t test_vadd_vv_i32m4_vl(__rvv_int32m4_t arg_0, __rvv_int32m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i32m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m4_t test_vadd_vv_i32m4_m_vl(__rvv_bool8_t arg_0, __rvv_int32m4_t arg_1, __rvv_int32m4_t arg_2, __rvv_int32m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i32m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.nxv4i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.nxv4i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m4_t test_vadd_vv_i64m4_vl(__rvv_int64m4_t arg_0, __rvv_int64m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i64m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m4_t test_vadd_vv_i64m4_m_vl(__rvv_bool16_t arg_0, __rvv_int64m4_t arg_1, __rvv_int64m4_t arg_2, __rvv_int64m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i64m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.nxv64i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.nxv64i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m8_t test_vadd_vv_i8m8_vl(__rvv_int8m8_t arg_0, __rvv_int8m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i8m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m8_t test_vadd_vv_i8m8_m_vl(__rvv_bool1_t arg_0, __rvv_int8m8_t arg_1, __rvv_int8m8_t arg_2, __rvv_int8m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i8m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.nxv32i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.nxv32i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m8_t test_vadd_vv_i16m8_vl(__rvv_int16m8_t arg_0, __rvv_int16m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i16m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m8_t test_vadd_vv_i16m8_m_vl(__rvv_bool2_t arg_0, __rvv_int16m8_t arg_1, __rvv_int16m8_t arg_2, __rvv_int16m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i16m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.nxv16i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.nxv16i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m8_t test_vadd_vv_i32m8_vl(__rvv_int32m8_t arg_0, __rvv_int32m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i32m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m8_t test_vadd_vv_i32m8_m_vl(__rvv_bool4_t arg_0, __rvv_int32m8_t arg_1, __rvv_int32m8_t arg_2, __rvv_int32m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i32m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.nxv8i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.nxv8i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m8_t test_vadd_vv_i64m8_vl(__rvv_int64m8_t arg_0, __rvv_int64m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i64m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i64m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i64m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m8_t test_vadd_vv_i64m8_m_vl(__rvv_bool8_t arg_0, __rvv_int64m8_t arg_1, __rvv_int64m8_t arg_2, __rvv_int64m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i64m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.nxv4i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.nxv4i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf2_t test_vadd_vv_i8mf2_vl(__rvv_int8mf2_t arg_0, __rvv_int8mf2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i8mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf2_t test_vadd_vv_i8mf2_m_vl(__rvv_bool16_t arg_0, __rvv_int8mf2_t arg_1, __rvv_int8mf2_t arg_2, __rvv_int8mf2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i8mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.nxv2i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.nxv2i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf2_t test_vadd_vv_i16mf2_vl(__rvv_int16mf2_t arg_0, __rvv_int16mf2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i16mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf2_t test_vadd_vv_i16mf2_m_vl(__rvv_bool32_t arg_0, __rvv_int16mf2_t arg_1, __rvv_int16mf2_t arg_2, __rvv_int16mf2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i16mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.nxv1i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.nxv1i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32mf2_t test_vadd_vv_i32mf2_vl(__rvv_int32mf2_t arg_0, __rvv_int32mf2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i32mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i32mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i32mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32mf2_t test_vadd_vv_i32mf2_m_vl(__rvv_bool64_t arg_0, __rvv_int32mf2_t arg_1, __rvv_int32mf2_t arg_2, __rvv_int32mf2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i32mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.nxv2i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.nxv2i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf4_t test_vadd_vv_i8mf4_vl(__rvv_int8mf4_t arg_0, __rvv_int8mf4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i8mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf4_t test_vadd_vv_i8mf4_m_vl(__rvv_bool32_t arg_0, __rvv_int8mf4_t arg_1, __rvv_int8mf4_t arg_2, __rvv_int8mf4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i8mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.nxv1i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.nxv1i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf4_t test_vadd_vv_i16mf4_vl(__rvv_int16mf4_t arg_0, __rvv_int16mf4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i16mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i16mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i16mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf4_t test_vadd_vv_i16mf4_m_vl(__rvv_bool64_t arg_0, __rvv_int16mf4_t arg_1, __rvv_int16mf4_t arg_2, __rvv_int16mf4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i16mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8mf8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.nxv1i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8mf8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.nxv1i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf8_t test_vadd_vv_i8mf8_vl(__rvv_int8mf8_t arg_0, __rvv_int8mf8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_i8mf8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_i8mf8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_i8mf8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf8_t test_vadd_vv_i8mf8_m_vl(__rvv_bool64_t arg_0, __rvv_int8mf8_t arg_1, __rvv_int8mf8_t arg_2, __rvv_int8mf8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_i8mf8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m1_t test_vadd_vx_i8m1_vl(__rvv_int8m1_t arg_0, int8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i8m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m1_t test_vadd_vx_i8m1_m_vl(__rvv_bool8_t arg_0, __rvv_int8m1_t arg_1, __rvv_int8m1_t arg_2, int8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i8m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m1_t test_vadd_vx_i16m1_vl(__rvv_int16m1_t arg_0, int16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i16m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m1_t test_vadd_vx_i16m1_m_vl(__rvv_bool16_t arg_0, __rvv_int16m1_t arg_1, __rvv_int16m1_t arg_2, int16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i16m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m1_t test_vadd_vx_i32m1_vl(__rvv_int32m1_t arg_0, int32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i32m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m1_t test_vadd_vx_i32m1_m_vl(__rvv_bool32_t arg_0, __rvv_int32m1_t arg_1, __rvv_int32m1_t arg_2, int32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i32m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m1_t test_vadd_vx_i64m1_vl(__rvv_int64m1_t arg_0, int64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i64m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m1_t test_vadd_vx_i64m1_m_vl(__rvv_bool64_t arg_0, __rvv_int64m1_t arg_1, __rvv_int64m1_t arg_2, int64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i64m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m2_t test_vadd_vx_i8m2_vl(__rvv_int8m2_t arg_0, int8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i8m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m2_t test_vadd_vx_i8m2_m_vl(__rvv_bool4_t arg_0, __rvv_int8m2_t arg_1, __rvv_int8m2_t arg_2, int8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i8m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m2_t test_vadd_vx_i16m2_vl(__rvv_int16m2_t arg_0, int16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i16m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m2_t test_vadd_vx_i16m2_m_vl(__rvv_bool8_t arg_0, __rvv_int16m2_t arg_1, __rvv_int16m2_t arg_2, int16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i16m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m2_t test_vadd_vx_i32m2_vl(__rvv_int32m2_t arg_0, int32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i32m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m2_t test_vadd_vx_i32m2_m_vl(__rvv_bool16_t arg_0, __rvv_int32m2_t arg_1, __rvv_int32m2_t arg_2, int32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i32m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m2_t test_vadd_vx_i64m2_vl(__rvv_int64m2_t arg_0, int64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i64m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m2_t test_vadd_vx_i64m2_m_vl(__rvv_bool32_t arg_0, __rvv_int64m2_t arg_1, __rvv_int64m2_t arg_2, int64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i64m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m4_t test_vadd_vx_i8m4_vl(__rvv_int8m4_t arg_0, int8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i8m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m4_t test_vadd_vx_i8m4_m_vl(__rvv_bool2_t arg_0, __rvv_int8m4_t arg_1, __rvv_int8m4_t arg_2, int8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i8m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m4_t test_vadd_vx_i16m4_vl(__rvv_int16m4_t arg_0, int16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i16m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m4_t test_vadd_vx_i16m4_m_vl(__rvv_bool4_t arg_0, __rvv_int16m4_t arg_1, __rvv_int16m4_t arg_2, int16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i16m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m4_t test_vadd_vx_i32m4_vl(__rvv_int32m4_t arg_0, int32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i32m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m4_t test_vadd_vx_i32m4_m_vl(__rvv_bool8_t arg_0, __rvv_int32m4_t arg_1, __rvv_int32m4_t arg_2, int32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i32m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m4_t test_vadd_vx_i64m4_vl(__rvv_int64m4_t arg_0, int64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i64m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m4_t test_vadd_vx_i64m4_m_vl(__rvv_bool16_t arg_0, __rvv_int64m4_t arg_1, __rvv_int64m4_t arg_2, int64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i64m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m8_t test_vadd_vx_i8m8_vl(__rvv_int8m8_t arg_0, int8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i8m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8m8_t test_vadd_vx_i8m8_m_vl(__rvv_bool1_t arg_0, __rvv_int8m8_t arg_1, __rvv_int8m8_t arg_2, int8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i8m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m8_t test_vadd_vx_i16m8_vl(__rvv_int16m8_t arg_0, int16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i16m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16m8_t test_vadd_vx_i16m8_m_vl(__rvv_bool2_t arg_0, __rvv_int16m8_t arg_1, __rvv_int16m8_t arg_2, int16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i16m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m8_t test_vadd_vx_i32m8_vl(__rvv_int32m8_t arg_0, int32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i32m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32m8_t test_vadd_vx_i32m8_m_vl(__rvv_bool4_t arg_0, __rvv_int32m8_t arg_1, __rvv_int32m8_t arg_2, int32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i32m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m8_t test_vadd_vx_i64m8_vl(__rvv_int64m8_t arg_0, int64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i64m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i64m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i64m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int64m8_t test_vadd_vx_i64m8_m_vl(__rvv_bool8_t arg_0, __rvv_int64m8_t arg_1, __rvv_int64m8_t arg_2, int64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i64m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf2_t test_vadd_vx_i8mf2_vl(__rvv_int8mf2_t arg_0, int8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i8mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf2_t test_vadd_vx_i8mf2_m_vl(__rvv_bool16_t arg_0, __rvv_int8mf2_t arg_1, __rvv_int8mf2_t arg_2, int8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i8mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf2_t test_vadd_vx_i16mf2_vl(__rvv_int16mf2_t arg_0, int16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i16mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf2_t test_vadd_vx_i16mf2_m_vl(__rvv_bool32_t arg_0, __rvv_int16mf2_t arg_1, __rvv_int16mf2_t arg_2, int16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i16mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32mf2_t test_vadd_vx_i32mf2_vl(__rvv_int32mf2_t arg_0, int32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i32mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i32mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i32mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int32mf2_t test_vadd_vx_i32mf2_m_vl(__rvv_bool64_t arg_0, __rvv_int32mf2_t arg_1, __rvv_int32mf2_t arg_2, int32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i32mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf4_t test_vadd_vx_i8mf4_vl(__rvv_int8mf4_t arg_0, int8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i8mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf4_t test_vadd_vx_i8mf4_m_vl(__rvv_bool32_t arg_0, __rvv_int8mf4_t arg_1, __rvv_int8mf4_t arg_2, int8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i8mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf4_t test_vadd_vx_i16mf4_vl(__rvv_int16mf4_t arg_0, int16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i16mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i16mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i16mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int16mf4_t test_vadd_vx_i16mf4_m_vl(__rvv_bool64_t arg_0, __rvv_int16mf4_t arg_1, __rvv_int16mf4_t arg_2, int16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i16mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8mf8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8mf8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf8_t test_vadd_vx_i8mf8_vl(__rvv_int8mf8_t arg_0, int8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_i8mf8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_i8mf8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_i8mf8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_int8mf8_t test_vadd_vx_i8mf8_m_vl(__rvv_bool64_t arg_0, __rvv_int8mf8_t arg_1, __rvv_int8mf8_t arg_2, int8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_i8mf8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.nxv8i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.nxv8i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m1_t test_vadd_vv_u8m1_vl(__rvv_uint8m1_t arg_0, __rvv_uint8m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u8m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m1_t test_vadd_vv_u8m1_m_vl(__rvv_bool8_t arg_0, __rvv_uint8m1_t arg_1, __rvv_uint8m1_t arg_2, __rvv_uint8m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u8m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.nxv4i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.nxv4i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m1_t test_vadd_vv_u16m1_vl(__rvv_uint16m1_t arg_0, __rvv_uint16m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u16m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.nxv4i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m1_t test_vadd_vv_u16m1_m_vl(__rvv_bool16_t arg_0, __rvv_uint16m1_t arg_1, __rvv_uint16m1_t arg_2, __rvv_uint16m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u16m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.nxv2i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.nxv2i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m1_t test_vadd_vv_u32m1_vl(__rvv_uint32m1_t arg_0, __rvv_uint32m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u32m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m1_t test_vadd_vv_u32m1_m_vl(__rvv_bool32_t arg_0, __rvv_uint32m1_t arg_1, __rvv_uint32m1_t arg_2, __rvv_uint32m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u32m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.nxv1i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.nxv1i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m1_t test_vadd_vv_u64m1_vl(__rvv_uint64m1_t arg_0, __rvv_uint64m1_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u64m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.nxv1i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m1_t test_vadd_vv_u64m1_m_vl(__rvv_bool64_t arg_0, __rvv_uint64m1_t arg_1, __rvv_uint64m1_t arg_2, __rvv_uint64m1_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u64m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.nxv16i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.nxv16i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m2_t test_vadd_vv_u8m2_vl(__rvv_uint8m2_t arg_0, __rvv_uint8m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u8m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.nxv16i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m2_t test_vadd_vv_u8m2_m_vl(__rvv_bool4_t arg_0, __rvv_uint8m2_t arg_1, __rvv_uint8m2_t arg_2, __rvv_uint8m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u8m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.nxv8i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.nxv8i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m2_t test_vadd_vv_u16m2_vl(__rvv_uint16m2_t arg_0, __rvv_uint16m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u16m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.nxv8i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m2_t test_vadd_vv_u16m2_m_vl(__rvv_bool8_t arg_0, __rvv_uint16m2_t arg_1, __rvv_uint16m2_t arg_2, __rvv_uint16m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u16m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.nxv4i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.nxv4i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m2_t test_vadd_vv_u32m2_vl(__rvv_uint32m2_t arg_0, __rvv_uint32m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u32m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m2_t test_vadd_vv_u32m2_m_vl(__rvv_bool16_t arg_0, __rvv_uint32m2_t arg_1, __rvv_uint32m2_t arg_2, __rvv_uint32m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u32m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.nxv2i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.nxv2i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m2_t test_vadd_vv_u64m2_vl(__rvv_uint64m2_t arg_0, __rvv_uint64m2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u64m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.nxv2i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m2_t test_vadd_vv_u64m2_m_vl(__rvv_bool32_t arg_0, __rvv_uint64m2_t arg_1, __rvv_uint64m2_t arg_2, __rvv_uint64m2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u64m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.nxv32i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.nxv32i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m4_t test_vadd_vv_u8m4_vl(__rvv_uint8m4_t arg_0, __rvv_uint8m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u8m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.nxv32i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m4_t test_vadd_vv_u8m4_m_vl(__rvv_bool2_t arg_0, __rvv_uint8m4_t arg_1, __rvv_uint8m4_t arg_2, __rvv_uint8m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u8m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.nxv16i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.nxv16i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m4_t test_vadd_vv_u16m4_vl(__rvv_uint16m4_t arg_0, __rvv_uint16m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u16m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m4_t test_vadd_vv_u16m4_m_vl(__rvv_bool4_t arg_0, __rvv_uint16m4_t arg_1, __rvv_uint16m4_t arg_2, __rvv_uint16m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u16m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.nxv8i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.nxv8i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m4_t test_vadd_vv_u32m4_vl(__rvv_uint32m4_t arg_0, __rvv_uint32m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u32m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.nxv8i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m4_t test_vadd_vv_u32m4_m_vl(__rvv_bool8_t arg_0, __rvv_uint32m4_t arg_1, __rvv_uint32m4_t arg_2, __rvv_uint32m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u32m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.nxv4i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.nxv4i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m4_t test_vadd_vv_u64m4_vl(__rvv_uint64m4_t arg_0, __rvv_uint64m4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u64m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.nxv4i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m4_t test_vadd_vv_u64m4_m_vl(__rvv_bool16_t arg_0, __rvv_uint64m4_t arg_1, __rvv_uint64m4_t arg_2, __rvv_uint64m4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u64m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.nxv64i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.nxv64i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m8_t test_vadd_vv_u8m8_vl(__rvv_uint8m8_t arg_0, __rvv_uint8m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u8m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m8_t test_vadd_vv_u8m8_m_vl(__rvv_bool1_t arg_0, __rvv_uint8m8_t arg_1, __rvv_uint8m8_t arg_2, __rvv_uint8m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u8m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.nxv32i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.nxv32i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m8_t test_vadd_vv_u16m8_vl(__rvv_uint16m8_t arg_0, __rvv_uint16m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u16m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.nxv32i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m8_t test_vadd_vv_u16m8_m_vl(__rvv_bool2_t arg_0, __rvv_uint16m8_t arg_1, __rvv_uint16m8_t arg_2, __rvv_uint16m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u16m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.nxv16i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.nxv16i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m8_t test_vadd_vv_u32m8_vl(__rvv_uint32m8_t arg_0, __rvv_uint32m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u32m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.nxv16i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m8_t test_vadd_vv_u32m8_m_vl(__rvv_bool4_t arg_0, __rvv_uint32m8_t arg_1, __rvv_uint32m8_t arg_2, __rvv_uint32m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u32m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.nxv8i64.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.nxv8i64.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m8_t test_vadd_vv_u64m8_vl(__rvv_uint64m8_t arg_0, __rvv_uint64m8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u64m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u64m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u64m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.nxv8i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m8_t test_vadd_vv_u64m8_m_vl(__rvv_bool8_t arg_0, __rvv_uint64m8_t arg_1, __rvv_uint64m8_t arg_2, __rvv_uint64m8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u64m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.nxv4i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.nxv4i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf2_t test_vadd_vv_u8mf2_vl(__rvv_uint8mf2_t arg_0, __rvv_uint8mf2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u8mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.nxv4i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf2_t test_vadd_vv_u8mf2_m_vl(__rvv_bool16_t arg_0, __rvv_uint8mf2_t arg_1, __rvv_uint8mf2_t arg_2, __rvv_uint8mf2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u8mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.nxv2i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.nxv2i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf2_t test_vadd_vv_u16mf2_vl(__rvv_uint16mf2_t arg_0, __rvv_uint16mf2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u16mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.nxv2i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf2_t test_vadd_vv_u16mf2_m_vl(__rvv_bool32_t arg_0, __rvv_uint16mf2_t arg_1, __rvv_uint16mf2_t arg_2, __rvv_uint16mf2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u16mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.nxv1i32.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.nxv1i32.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32mf2_t test_vadd_vv_u32mf2_vl(__rvv_uint32mf2_t arg_0, __rvv_uint32mf2_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u32mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u32mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u32mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32mf2_t test_vadd_vv_u32mf2_m_vl(__rvv_bool64_t arg_0, __rvv_uint32mf2_t arg_1, __rvv_uint32mf2_t arg_2, __rvv_uint32mf2_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u32mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.nxv2i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.nxv2i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf4_t test_vadd_vv_u8mf4_vl(__rvv_uint8mf4_t arg_0, __rvv_uint8mf4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u8mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.nxv2i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf4_t test_vadd_vv_u8mf4_m_vl(__rvv_bool32_t arg_0, __rvv_uint8mf4_t arg_1, __rvv_uint8mf4_t arg_2, __rvv_uint8mf4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u8mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.nxv1i16.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.nxv1i16.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf4_t test_vadd_vv_u16mf4_vl(__rvv_uint16mf4_t arg_0, __rvv_uint16mf4_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u16mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u16mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u16mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.nxv1i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf4_t test_vadd_vv_u16mf4_m_vl(__rvv_bool64_t arg_0, __rvv_uint16mf4_t arg_1, __rvv_uint16mf4_t arg_2, __rvv_uint16mf4_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u16mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8mf8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.nxv1i8.i64( [[ARG_0:%.*]], [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8mf8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.nxv1i8.i32( [[ARG_0:%.*]], [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf8_t test_vadd_vv_u8mf8_vl(__rvv_uint8mf8_t arg_0, __rvv_uint8mf8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vv_u8mf8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vv_u8mf8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vv_u8mf8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.nxv1i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf8_t test_vadd_vv_u8mf8_m_vl(__rvv_bool64_t arg_0, __rvv_uint8mf8_t arg_1, __rvv_uint8mf8_t arg_2, __rvv_uint8mf8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vv_u8mf8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m1_t test_vadd_vx_u8m1_vl(__rvv_uint8m1_t arg_0, uint8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u8m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m1_t test_vadd_vx_u8m1_m_vl(__rvv_bool8_t arg_0, __rvv_uint8m1_t arg_1, __rvv_uint8m1_t arg_2, uint8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u8m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m1_t test_vadd_vx_u16m1_vl(__rvv_uint16m1_t arg_0, uint16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u16m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m1_t test_vadd_vx_u16m1_m_vl(__rvv_bool16_t arg_0, __rvv_uint16m1_t arg_1, __rvv_uint16m1_t arg_2, uint16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u16m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m1_t test_vadd_vx_u32m1_vl(__rvv_uint32m1_t arg_0, uint32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u32m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m1_t test_vadd_vx_u32m1_m_vl(__rvv_bool32_t arg_0, __rvv_uint32m1_t arg_1, __rvv_uint32m1_t arg_2, uint32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u32m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m1_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m1_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m1_t test_vadd_vx_u64m1_vl(__rvv_uint64m1_t arg_0, uint64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u64m1_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m1_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m1_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m1_t test_vadd_vx_u64m1_m_vl(__rvv_bool64_t arg_0, __rvv_uint64m1_t arg_1, __rvv_uint64m1_t arg_2, uint64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u64m1_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m2_t test_vadd_vx_u8m2_vl(__rvv_uint8m2_t arg_0, uint8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u8m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m2_t test_vadd_vx_u8m2_m_vl(__rvv_bool4_t arg_0, __rvv_uint8m2_t arg_1, __rvv_uint8m2_t arg_2, uint8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u8m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m2_t test_vadd_vx_u16m2_vl(__rvv_uint16m2_t arg_0, uint16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u16m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m2_t test_vadd_vx_u16m2_m_vl(__rvv_bool8_t arg_0, __rvv_uint16m2_t arg_1, __rvv_uint16m2_t arg_2, uint16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u16m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m2_t test_vadd_vx_u32m2_vl(__rvv_uint32m2_t arg_0, uint32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u32m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m2_t test_vadd_vx_u32m2_m_vl(__rvv_bool16_t arg_0, __rvv_uint32m2_t arg_1, __rvv_uint32m2_t arg_2, uint32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u32m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m2_t test_vadd_vx_u64m2_vl(__rvv_uint64m2_t arg_0, uint64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u64m2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m2_t test_vadd_vx_u64m2_m_vl(__rvv_bool32_t arg_0, __rvv_uint64m2_t arg_1, __rvv_uint64m2_t arg_2, uint64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u64m2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m4_t test_vadd_vx_u8m4_vl(__rvv_uint8m4_t arg_0, uint8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u8m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m4_t test_vadd_vx_u8m4_m_vl(__rvv_bool2_t arg_0, __rvv_uint8m4_t arg_1, __rvv_uint8m4_t arg_2, uint8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u8m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m4_t test_vadd_vx_u16m4_vl(__rvv_uint16m4_t arg_0, uint16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u16m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m4_t test_vadd_vx_u16m4_m_vl(__rvv_bool4_t arg_0, __rvv_uint16m4_t arg_1, __rvv_uint16m4_t arg_2, uint16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u16m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m4_t test_vadd_vx_u32m4_vl(__rvv_uint32m4_t arg_0, uint32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u32m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m4_t test_vadd_vx_u32m4_m_vl(__rvv_bool8_t arg_0, __rvv_uint32m4_t arg_1, __rvv_uint32m4_t arg_2, uint32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u32m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m4_t test_vadd_vx_u64m4_vl(__rvv_uint64m4_t arg_0, uint64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u64m4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m4_t test_vadd_vx_u64m4_m_vl(__rvv_bool16_t arg_0, __rvv_uint64m4_t arg_1, __rvv_uint64m4_t arg_2, uint64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u64m4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv64i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m8_t test_vadd_vx_u8m8_vl(__rvv_uint8m8_t arg_0, uint8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u8m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv64i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8m8_t test_vadd_vx_u8m8_m_vl(__rvv_bool1_t arg_0, __rvv_uint8m8_t arg_1, __rvv_uint8m8_t arg_2, uint8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u8m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv32i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m8_t test_vadd_vx_u16m8_vl(__rvv_uint16m8_t arg_0, uint16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u16m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv32i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16m8_t test_vadd_vx_u16m8_m_vl(__rvv_bool2_t arg_0, __rvv_uint16m8_t arg_1, __rvv_uint16m8_t arg_2, uint16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u16m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv16i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m8_t test_vadd_vx_u32m8_vl(__rvv_uint32m8_t arg_0, uint32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u32m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv16i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32m8_t test_vadd_vx_u32m8_m_vl(__rvv_bool4_t arg_0, __rvv_uint32m8_t arg_1, __rvv_uint32m8_t arg_2, uint32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u32m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.i64.i64( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv8i64.i64.i32( [[ARG_0:%.*]], i64 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m8_t test_vadd_vx_u64m8_vl(__rvv_uint64m8_t arg_0, uint64_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u64m8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u64m8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.i64.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u64m8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv8i64.i64.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i64 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint64m8_t test_vadd_vx_u64m8_m_vl(__rvv_bool8_t arg_0, __rvv_uint64m8_t arg_1, __rvv_uint64m8_t arg_2, uint64_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u64m8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv4i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf2_t test_vadd_vx_u8mf2_vl(__rvv_uint8mf2_t arg_0, uint8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u8mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv4i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf2_t test_vadd_vx_u8mf2_m_vl(__rvv_bool16_t arg_0, __rvv_uint8mf2_t arg_1, __rvv_uint8mf2_t arg_2, uint8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u8mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf2_t test_vadd_vx_u16mf2_vl(__rvv_uint16mf2_t arg_0, uint16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u16mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf2_t test_vadd_vx_u16mf2_m_vl(__rvv_bool32_t arg_0, __rvv_uint16mf2_t arg_1, __rvv_uint16mf2_t arg_2, uint16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u16mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32mf2_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.i32.i64( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32mf2_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i32.i32.i32( [[ARG_0:%.*]], i32 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32mf2_t test_vadd_vx_u32mf2_vl(__rvv_uint32mf2_t arg_0, uint32_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u32mf2_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u32mf2_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.i32.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u32mf2_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i32.i32.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i32 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint32mf2_t test_vadd_vx_u32mf2_m_vl(__rvv_bool64_t arg_0, __rvv_uint32mf2_t arg_1, __rvv_uint32mf2_t arg_2, uint32_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u32mf2_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv2i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf4_t test_vadd_vx_u8mf4_vl(__rvv_uint8mf4_t arg_0, uint8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u8mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv2i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf4_t test_vadd_vx_u8mf4_m_vl(__rvv_bool32_t arg_0, __rvv_uint8mf4_t arg_1, __rvv_uint8mf4_t arg_2, uint8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u8mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16mf4_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.i16.i64( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16mf4_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i16.i16.i32( [[ARG_0:%.*]], i16 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf4_t test_vadd_vx_u16mf4_vl(__rvv_uint16mf4_t arg_0, uint16_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u16mf4_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u16mf4_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.i16.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u16mf4_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i16.i16.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i16 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint16mf4_t test_vadd_vx_u16mf4_m_vl(__rvv_bool64_t arg_0, __rvv_uint16mf4_t arg_1, __rvv_uint16mf4_t arg_2, uint16_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u16mf4_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8mf8_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.i8.i64( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i64 [[ARG_2:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8mf8_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.nxv1i8.i8.i32( [[ARG_0:%.*]], i8 [[ARG_1:%.*]], i32 [[ARG_2:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf8_t test_vadd_vx_u8mf8_vl(__rvv_uint8mf8_t arg_0, uint8_t arg_1, size_t arg_2) -{ - return __builtin_rvv_vadd_vx_u8mf8_vl(arg_0, arg_1, arg_2); -} - -// CHECK-RV64-O2-LABEL: @test_vadd_vx_u8mf8_m_vl( -// CHECK-RV64-O2-NEXT: entry: -// CHECK-RV64-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.i8.i64( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i64 [[ARG_4:%.*]]) -// CHECK-RV64-O2-NEXT: ret [[TMP0]] -// -// CHECK-RV32-O2-LABEL: @test_vadd_vx_u8mf8_m_vl( -// CHECK-RV32-O2-NEXT: entry: -// CHECK-RV32-O2-NEXT: [[TMP0:%.*]] = tail call @llvm.riscv.vadd.mask.nxv1i8.i8.i32( [[ARG_1:%.*]], [[ARG_2:%.*]], i8 [[ARG_3:%.*]], [[ARG_0:%.*]], i32 [[ARG_4:%.*]]) -// CHECK-RV32-O2-NEXT: ret [[TMP0]] -// -__rvv_uint8mf8_t test_vadd_vx_u8mf8_m_vl(__rvv_bool64_t arg_0, __rvv_uint8mf8_t arg_1, __rvv_uint8mf8_t arg_2, uint8_t arg_3, size_t arg_4) -{ - return __builtin_rvv_vadd_vx_u8mf8_m_vl(arg_0, arg_1, arg_2, arg_3, arg_4); -} diff --git a/clang/test/CodeGen/SystemZ/strictfp_builtins.c b/clang/test/CodeGen/SystemZ/strictfp_builtins.c index 2181da9b8637..58909f16a6dd 100644 --- a/clang/test/CodeGen/SystemZ/strictfp_builtins.c +++ b/clang/test/CodeGen/SystemZ/strictfp_builtins.c @@ -9,7 +9,7 @@ // CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 // CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4 -// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) [[ATTR2:#.*]] +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) #[[ATTR2:[0-9]+]] // CHECK-NEXT: ret i32 [[TMP1]] // int test_isnan_float(float f) { @@ -21,7 +21,7 @@ int test_isnan_float(float f) { // CHECK-NEXT: [[D_ADDR:%.*]] = alloca double, align 8 // CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) [[ATTR2]] +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) #[[ATTR2]] // CHECK-NEXT: ret i32 [[TMP1]] // int test_isnan_double(double d) { @@ -34,10 +34,84 @@ int test_isnan_double(double d) { // CHECK-NEXT: [[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8 // CHECK-NEXT: store fp128 [[LD]], fp128* [[LD_ADDR]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) [[ATTR2]] +// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) #[[ATTR2]] // CHECK-NEXT: ret i32 [[TMP2]] // int test_isnan_long_double(long double ld) { return __builtin_isnan(ld); } +// CHECK-LABEL: @test_isinf_float( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 48) #[[ATTR2]] +// CHECK-NEXT: ret i32 [[TMP1]] +// +int test_isinf_float(float f) { + return __builtin_isinf(f); +} + +// CHECK-LABEL: @test_isinf_double( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[D_ADDR:%.*]] = alloca double, align 8 +// CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 48) #[[ATTR2]] +// CHECK-NEXT: ret i32 [[TMP1]] +// +int test_isinf_double(double d) { + return __builtin_isinf(d); +} + +// CHECK-LABEL: @test_isinf_long_double( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca fp128, align 8 +// CHECK-NEXT: [[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8 +// CHECK-NEXT: store fp128 [[LD]], fp128* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 48) #[[ATTR2]] +// CHECK-NEXT: ret i32 [[TMP2]] +// +int test_isinf_long_double(long double ld) { + return __builtin_isinf(ld); +} + +// CHECK-LABEL: @test_isfinite_float( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 4032) #[[ATTR2]] +// CHECK-NEXT: ret i32 [[TMP1]] +// +int test_isfinite_float(float f) { + return __builtin_isfinite(f); +} + +// CHECK-LABEL: @test_isfinite_double( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[D_ADDR:%.*]] = alloca double, align 8 +// CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 4032) #[[ATTR2]] +// CHECK-NEXT: ret i32 [[TMP1]] +// +int test_isfinite_double(double d) { + return __builtin_isfinite(d); +} + +// CHECK-LABEL: @test_isfinite_long_double( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca fp128, align 8 +// CHECK-NEXT: [[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8 +// CHECK-NEXT: store fp128 [[LD]], fp128* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 4032) #[[ATTR2]] +// CHECK-NEXT: ret i32 [[TMP2]] +// +int test_isfinite_long_double(long double ld) { + return __builtin_isfinite(ld); +} + diff --git a/clang/test/CodeGen/SystemZ/zos-alignment.c b/clang/test/CodeGen/SystemZ/zos-alignment.c index 4b572fcac5a9..7b08f4bf7f4a 100644 --- a/clang/test/CodeGen/SystemZ/zos-alignment.c +++ b/clang/test/CodeGen/SystemZ/zos-alignment.c @@ -1,11 +1,41 @@ -// RUN: %clang_cc1 -emit-llvm-only -triple s390x-none-zos -fdump-record-layouts %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm-only -triple s390x-none-zos -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -emit-llvm -triple s390x-none-zos %s -o - | FileCheck %s --check-prefix=DECL + +static int __attribute__((aligned(32))) v0; +int __attribute__((aligned(32))) v1; +typedef int __attribute__((aligned(32))) int32; +static int32 v2; +int32 v3; +int f0() { return v0 + v1 + v2 + v3; } +// DECL: @v0 {{.*}} align 16 +// DECL-NEXT: @v1 {{.*}} align 32 +// DECL-NEXT: @v2 {{.*}} align 16 +// DECL-NEXT: @v3 {{.*}} align 32 + +const struct cs0 { + unsigned long : 0; + long long a; +} CS0 = {}; +// CHECK: 0 | struct cs0 +// CHECK-NEXT: 0:- | unsigned long +// CHECK-NEXT: 0 | long long a +// CHECK-NEXT: | [sizeof=8, align=8] + +volatile struct vs0 { + long : 0; + short a; +} VS0; +// CHECK: 0 | struct vs0 +// CHECK-NEXT: 0:- | long +// CHECK-NEXT: 0 | short a +// CHECK-NEXT: | [sizeof=2, align=2] struct s0 { - short a:3; - long b:5; - int c:1; - long d:10; - char e:5; + short a : 3; + long b : 5; + int c : 1; + long d : 10; + char e : 5; } S0; // CHECK: 0 | struct s0 // CHECK-NEXT: 0:0-2 | short a @@ -16,9 +46,9 @@ struct s0 { // CHECK-NEXT: | [sizeof=3, align=1] struct s1 { - char a:7; - long b:27; - int c:2; + char a : 7; + long b : 27; + int c : 2; } S1; // CHECK: 0 | struct s1 // CHECK-NEXT: 0:0-6 | char a @@ -27,10 +57,10 @@ struct s1 { // CHECK-NEXT: | [sizeof=5, align=1] struct s2 { - char a:7; - char :0; - short :0; - short :0; + char a : 7; + char : 0; + short : 0; + short : 0; } S2; // CHECK: 0 | struct s2 // CHECK-NEXT: 0:0-6 | char a @@ -41,9 +71,9 @@ struct s2 { struct s3 { int a; - int b:16; - char :0; - char c:1; + int b : 16; + char : 0; + char c : 1; } S3; // CHECK: 0 | struct s3 // CHECK-NEXT: 0 | int a @@ -53,7 +83,7 @@ struct s3 { // CHECK-NEXT: | [sizeof=12, align=4] struct s4 { - unsigned int __attribute__((aligned(32))) a; + unsigned int __attribute__((aligned(32))) a; } S4; // CHECK: 0 | struct s4 // CHECK-NEXT: 0 | unsigned int a @@ -61,10 +91,10 @@ struct s4 { struct s5 { char a; - int b:19 __attribute__((aligned(4))); - int c:22 __attribute__((aligned(8))); - int :0; - int d:10; + int b : 19 __attribute__((aligned(4))); + int c : 22 __attribute__((aligned(8))); + int : 0; + int d : 10; } S5; // CHECK: 0 | struct s5 // CHECK-NEXT: 0 | char a @@ -75,16 +105,45 @@ struct s5 { // CHECK-NEXT: | [sizeof=16, align=8] struct s6 { - char * a; - char * b[]; + char *a; + char *b[]; } S6; // CHECK: 0 | struct s6 // CHECK-NEXT: 0 | char * a // CHECK-NEXT: 8 | char *[] b // CHECK-NEXT: | [sizeof=8, align=8] +struct s7 { + long : 0; + short a; +} S7; +// CHECK: 0 | struct s7 +// CHECK-NEXT: 0:- | long +// CHECK-NEXT: 0 | short a +// CHECK-NEXT: | [sizeof=2, align=2] + +#pragma pack(2) +struct s8 { + unsigned long : 0; + long long a; +} S8; +#pragma pack() +// CHECK: 0 | struct s8 +// CHECK-NEXT: 0:- | unsigned long +// CHECK-NEXT: 0 | long long a +// CHECK-NEXT: | [sizeof=8, align=2] + +struct s9 { + unsigned int : 0; + unsigned short : 0; +} S9; +// CHECK: 0 | struct s9 +// CHECK-NEXT: 0:- | unsigned int +// CHECK-NEXT: 0:- | unsigned short +// CHECK-NEXT: | [sizeof=0, align=1] + struct s10 { - unsigned int __attribute__((aligned)) a; + unsigned int __attribute__((aligned)) a; } S10; // CHECK: 0 | struct s10 // CHECK-NEXT: 0 | unsigned int a @@ -92,7 +151,7 @@ struct s10 { struct s11 { char a; - long :0; + long : 0; char b; } S11; // CHECK: 0 | struct s11 @@ -102,9 +161,9 @@ struct s11 { // CHECK-NEXT: | [sizeof=16, align=8] union u0 { - unsigned short d1 __attribute__((packed)); - int d2:10; - long d3; + unsigned short d1 __attribute__((packed)); + int d2 : 10; + long d3; } U0 __attribute__((aligned(8))); // CHECK: 0 | union u0 // CHECK-NEXT: 0 | unsigned short d1 @@ -113,8 +172,8 @@ union u0 { // CHECK-NEXT: | [sizeof=8, align=8] union u1 { - unsigned int :0; - short a; + unsigned int : 0; + short a; } U1; // CHECK: 0 | union u1 // CHECK-NEXT: 0:- | unsigned int @@ -122,8 +181,8 @@ union u1 { // CHECK-NEXT: | [sizeof=4, align=4] union u2 { - long :0; - short a; + long : 0; + short a; } U2; // CHECK: 0 | union u2 // CHECK-NEXT: 0:- | long @@ -131,8 +190,8 @@ union u2 { // CHECK-NEXT: | [sizeof=8, align=8] union u3 { - unsigned char :0; - unsigned short :0; + unsigned char : 0; + unsigned short : 0; } U3; // CHECK: 0 | union u3 // CHECK-NEXT: 0:- | unsigned char diff --git a/clang/test/CodeGen/X86/amx_api.c b/clang/test/CodeGen/X86/amx_api.c index 824a3aec20ec..3bfe887c0445 100644 --- a/clang/test/CodeGen/X86/amx_api.c +++ b/clang/test/CodeGen/X86/amx_api.c @@ -81,9 +81,9 @@ void test_tile_zero(__tile1024i c) { __tile_zero(&c); } -void test_tile_tdpbf16ps(__tile1024i a, __tile1024i b, __tile1024i c) { - //CHECK-LABEL: @test_tile_tdpbf16ps +void test_tile_dpbf16ps(__tile1024i a, __tile1024i b, __tile1024i c) { + //CHECK-LABEL: @test_tile_dpbf16ps //CHECK: call x86_amx @llvm.x86.tdpbf16ps.internal //CHECK-NEXT: {{%.*}} = bitcast x86_amx {{%.*}} to <256 x i32> - __tile_tdpbf16ps(&a, b, c); + __tile_dpbf16ps(&a, b, c); } diff --git a/clang/test/CodeGen/X86/strictfp_builtins.c b/clang/test/CodeGen/X86/strictfp_builtins.c index d7eda34fb45e..c3c94164e04f 100644 --- a/clang/test/CodeGen/X86/strictfp_builtins.c +++ b/clang/test/CodeGen/X86/strictfp_builtins.c @@ -26,6 +26,42 @@ void p(char *str, int x) { #define P(n,args) p(#n #args, __builtin_##n args) +// CHECK-LABEL: @test_long_double_isinf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca x86_fp80, align 16 +// CHECK-NEXT: store x86_fp80 [[D:%.*]], x86_fp80* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load x86_fp80, x86_fp80* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast x86_fp80 [[TMP0]] to i80 +// CHECK-NEXT: [[SHL1:%.*]] = shl i80 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[SHL1]], -18446744073709551616 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.[[#STRID:1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_long_double_isinf(long double ld) { + P(isinf, (ld)); + + return; +} + +// CHECK-LABEL: @test_long_double_isfinite( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca x86_fp80, align 16 +// CHECK-NEXT: store x86_fp80 [[D:%.*]], x86_fp80* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load x86_fp80, x86_fp80* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast x86_fp80 [[TMP0]] to i80 +// CHECK-NEXT: [[SHL1:%.*]] = shl i80 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp ult i80 [[SHL1]], -18446744073709551616 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_long_double_isfinite(long double ld) { + P(isfinite, (ld)); + + return; +} + // CHECK-LABEL: @test_long_double_isnan( // CHECK-NEXT: entry: // CHECK-NEXT: [[LD_ADDR:%.*]] = alloca x86_fp80, align 16 @@ -36,7 +72,7 @@ void p(char *str, int x) { // CHECK-NEXT: [[TMP1:%.*]] = sub i80 604453686435277732577280, [[ABS]] // CHECK-NEXT: [[ISNAN:%.*]] = lshr i80 [[TMP1]], 79 // CHECK-NEXT: [[RES:%.*]] = trunc i80 [[ISNAN]] to i32 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] // CHECK-NEXT: ret void // void test_long_double_isnan(long double ld) { diff --git a/clang/test/CodeGen/aarch64-neon-intrinsics.c b/clang/test/CodeGen/aarch64-neon-intrinsics.c index a56080bace0f..76f5cfd3aaa8 100644 --- a/clang/test/CodeGen/aarch64-neon-intrinsics.c +++ b/clang/test/CodeGen/aarch64-neon-intrinsics.c @@ -18155,7 +18155,7 @@ float64x1_t test_vcvt_n_f64_u64(uint64x1_t a) { // CHECK-LABEL: @test_vrndn_f64( // CHECK: [[TMP0:%.*]] = bitcast <1 x double> %a to <8 x i8> -// CHECK: [[VRNDN1_I:%.*]] = call <1 x double> @llvm.aarch64.neon.frintn.v1f64(<1 x double> %a) +// CHECK: [[VRNDN1_I:%.*]] = call <1 x double> @llvm.roundeven.v1f64(<1 x double> %a) // CHECK: ret <1 x double> [[VRNDN1_I]] float64x1_t test_vrndn_f64(float64x1_t a) { return vrndn_f64(a); diff --git a/clang/test/CodeGen/aarch64-neon-misc.c b/clang/test/CodeGen/aarch64-neon-misc.c index 4f85f67cdaec..ed9af88b56c1 100644 --- a/clang/test/CodeGen/aarch64-neon-misc.c +++ b/clang/test/CodeGen/aarch64-neon-misc.c @@ -2287,7 +2287,7 @@ float64x2_t test_vcvt_high_f64_f32(float32x4_t a) { // CHECK-LABEL: @test_vrndnq_f64( // CHECK: [[TMP0:%.*]] = bitcast <2 x double> %a to <16 x i8> -// CHECK: [[VRNDN1_I:%.*]] = call <2 x double> @llvm.aarch64.neon.frintn.v2f64(<2 x double> %a) +// CHECK: [[VRNDN1_I:%.*]] = call <2 x double> @llvm.roundeven.v2f64(<2 x double> %a) // CHECK: ret <2 x double> [[VRNDN1_I]] float64x2_t test_vrndnq_f64(float64x2_t a) { return vrndnq_f64(a); diff --git a/clang/test/CodeGen/aarch64-strictfp-builtins.c b/clang/test/CodeGen/aarch64-strictfp-builtins.c index 14647c31e647..3b2a4e547f4a 100644 --- a/clang/test/CodeGen/aarch64-strictfp-builtins.c +++ b/clang/test/CodeGen/aarch64-strictfp-builtins.c @@ -15,7 +15,7 @@ int printf(const char *, ...); // CHECK-NEXT: store i32 [[X:%.*]], i32* [[X_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load i8*, i8** [[STR_ADDR]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[X_ADDR]], align 4 -// CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i8* [[TMP0]], i32 [[TMP1]]) +// CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i8* [[TMP0]], i32 [[TMP1]]) [[ATTR4:#.*]] // CHECK-NEXT: ret void // void p(char *str, int x) { @@ -24,6 +24,42 @@ void p(char *str, int x) { #define P(n,args) p(#n #args, __builtin_##n args) +// CHECK-LABEL: @test_long_double_isinf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca fp128, align 16 +// CHECK-NEXT: store fp128 [[D:%.*]], fp128* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load fp128, fp128* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast fp128 [[TMP0]] to i128 +// CHECK-NEXT: [[SHL1:%.*]] = shl i128 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp eq i128 [[SHL1]], -10384593717069655257060992658440192 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.[[#STRID:1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_long_double_isinf(long double ld) { + P(isinf, (ld)); + + return; +} + +// CHECK-LABEL: @test_long_double_isfinite( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca fp128, align 16 +// CHECK-NEXT: store fp128 [[D:%.*]], fp128* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load fp128, fp128* [[LD_ADDR]], align 16 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast fp128 [[TMP0]] to i128 +// CHECK-NEXT: [[SHL1:%.*]] = shl i128 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[SHL1]], -10384593717069655257060992658440192 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_long_double_isfinite(long double ld) { + P(isfinite, (ld)); + + return; +} + // CHECK-LABEL: @test_long_double_isnan( // CHECK-NEXT: entry: // CHECK-NEXT: [[LD_ADDR:%.*]] = alloca fp128, align 16 @@ -34,7 +70,7 @@ void p(char *str, int x) { // CHECK-NEXT: [[TMP1:%.*]] = sub i128 170135991163610696904058773219554885632, [[ABS]] // CHECK-NEXT: [[ISNAN:%.*]] = lshr i128 [[TMP1]], 127 // CHECK-NEXT: [[RES:%.*]] = trunc i128 [[ISNAN]] to i32 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0), i32 [[RES]]) +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) // CHECK-NEXT: ret void // void test_long_double_isnan(long double ld) { diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c index 6475b19ab653..6e3b32e1cc19 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c @@ -114,7 +114,7 @@ svint32_t test_svld1sh_gather_u32base_s32(svbool_t pg, svuint32_t bases) { svint64_t test_svld1sh_gather_u64base_s64(svbool_t pg, svuint64_t bases) { // CHECK-LABEL: test_svld1sh_gather_u64base_s64 - // CHECK: %[[PG.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld1.gather.scalar.offset.nxv2i16.nxv2i64( %[[PG]], %bases, i64 0) // CHECK: %[[SEXT:.*]] = sext %[[LOAD]] to // CHECK: ret %[[SEXT]] diff --git a/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c b/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c index 32161146ef45..01df5b0d1930 100644 --- a/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c +++ b/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c @@ -366,7 +366,7 @@ float16_t test_vrndmh_f16(float16_t a) { } // CHECK-LABEL: test_vrndnh_f16 -// CHECK: [[RND:%.*]] = call half @llvm.aarch64.neon.frintn.f16(half %a) +// CHECK: [[RND:%.*]] = call half @llvm.roundeven.f16(half %a) // CHECK: ret half [[RND]] float16_t test_vrndnh_f16(float16_t a) { return vrndnh_f16(a); diff --git a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c index 5c4f9053a9ae..401aa4da8d5c 100644 --- a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c +++ b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c @@ -348,14 +348,14 @@ float16x8_t test_vrndmq_f16(float16x8_t a) { } // CHECK-LABEL: test_vrndn_f16 -// CHECK: [[RND:%.*]] = call <4 x half> @llvm.aarch64.neon.frintn.v4f16(<4 x half> %a) +// CHECK: [[RND:%.*]] = call <4 x half> @llvm.roundeven.v4f16(<4 x half> %a) // CHECK: ret <4 x half> [[RND]] float16x4_t test_vrndn_f16(float16x4_t a) { return vrndn_f16(a); } // CHECK-LABEL: test_vrndnq_f16 -// CHECK: [[RND:%.*]] = call <8 x half> @llvm.aarch64.neon.frintn.v8f16(<8 x half> %a) +// CHECK: [[RND:%.*]] = call <8 x half> @llvm.roundeven.v8f16(<8 x half> %a) // CHECK: ret <8 x half> [[RND]] float16x8_t test_vrndnq_f16(float16x8_t a) { return vrndnq_f16(a); diff --git a/clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c b/clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c new file mode 100644 index 000000000000..b57e92187129 --- /dev/null +++ b/clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +v8.5a\ +// RUN: -flax-vector-conversions=none -S -disable-O0-optnone -emit-llvm -o - %s \ +// RUN: | opt -S -mem2reg \ +// RUN: | FileCheck %s + +// REQUIRES: aarch64-registered-target + +#include + +// CHECK-LABEL: test_frint32zf +// CHECK: [[RND:%.*]] = call float @llvm.aarch64.frint32z.f32(float %a) +// CHECK: ret float [[RND]] +float test_frint32zf(float a) { + return __frint32zf(a); +} + +// CHECK-LABEL: test_frint32z +// CHECK: [[RND:%.*]] = call double @llvm.aarch64.frint32z.f64(double %a) +// CHECK: ret double [[RND]] +double test_frint32z(double a) { + return __frint32z(a); +} + +// CHECK-LABEL: test_frint64zf +// CHECK: [[RND:%.*]] = call float @llvm.aarch64.frint64z.f32(float %a) +// CHECK: ret float [[RND]] +float test_frint64zf(float a) { + return __frint64zf(a); +} + +// CHECK-LABEL: test_frint64z +// CHECK: [[RND:%.*]] = call double @llvm.aarch64.frint64z.f64(double %a) +// CHECK: ret double [[RND]] +double test_frint64z(double a) { + return __frint64z(a); +} + +// CHECK-LABEL: test_frint32xf +// CHECK: [[RND:%.*]] = call float @llvm.aarch64.frint32x.f32(float %a) +// CHECK: ret float [[RND]] +float test_frint32xf(float a) { + return __frint32xf(a); +} + +// CHECK-LABEL: test_frint32x +// CHECK: [[RND:%.*]] = call double @llvm.aarch64.frint32x.f64(double %a) +// CHECK: ret double [[RND]] +double test_frint32x(double a) { + return __frint32x(a); +} + +// CHECK-LABEL: test_frint64xf +// CHECK: [[RND:%.*]] = call float @llvm.aarch64.frint64x.f32(float %a) +// CHECK: ret float [[RND]] +float test_frint64xf(float a) { + return __frint64xf(a); +} + +// CHECK-LABEL: test_frint64x +// CHECK: [[RND:%.*]] = call double @llvm.aarch64.frint64x.f64(double %a) +// CHECK: ret double [[RND]] +double test_frint64x(double a) { + return __frint64x(a); +} diff --git a/clang/test/CodeGen/aix-ignore-xcoff-visibility.cpp b/clang/test/CodeGen/aix-ignore-xcoff-visibility.cpp index c0341b8c5a70..721a3df1e0e7 100644 --- a/clang/test/CodeGen/aix-ignore-xcoff-visibility.cpp +++ b/clang/test/CodeGen/aix-ignore-xcoff-visibility.cpp @@ -1,26 +1,19 @@ -// REQUIRES: powerpc-registered-target -// RUN: %clang_cc1 -triple powerpc-unknown-aix -o - -x c++ -S %s |\ -// RUN: FileCheck --check-prefix=IGNOREVISIBILITY-ASM %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=NOVISIBILITY-IR %s -// RUN: %clang_cc1 -triple powerpc-unknown-aix -mignore-xcoff-visibility -o - -x c++ -S %s | \ -// RUN: FileCheck -check-prefix=IGNOREVISIBILITY-ASM %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -round-trip-args -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=NOVISIBILITY-IR %s -// RUN: %clang_cc1 -triple powerpc-unknown-aix -mignore-xcoff-visibility -fvisibility default -o - -x c++ -S %s | \ -// RUN: FileCheck -check-prefix=IGNOREVISIBILITY-ASM %s - -// RUN: %clang_cc1 -triple powerpc-unknown-aix -fvisibility default -o - -x c++ -S %s | \ -// RUN: FileCheck -check-prefix=VISIBILITY-ASM %s - -// RUN: %clang_cc1 -triple powerpc-unknown-aix -mignore-xcoff-visibility -fvisibility default -o - -x c++ -S %s | \ -// RUN: FileCheck -check-prefix=IGNOREVISIBILITY-ASM %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix -mignore-xcoff-visibility -fvisibility default -emit-llvm -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=NOVISIBILITY-IR %s -// RUN: %clang_cc1 -triple powerpc-unknown-aix -fvisibility default -o - -x c++ -S %s | \ -// RUN: FileCheck -check-prefix=VISIBILITY-ASM %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix -mignore-xcoff-visibility -fvisibility default -emit-llvm -round-trip-args -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=NOVISIBILITY-IR %s -// RUN: %clang_cc1 -triple powerpc-unknown-aix -mignore-xcoff-visibility -fvisibility default -emit-llvm -o - -x c++ %s | \ +// RUN: %clang_cc1 -triple powerpc-unknown-aix -fvisibility default -emit-llvm -o - -x c++ %s | \ // RUN: FileCheck -check-prefix=VISIBILITY-IR %s -// RUN: %clang_cc1 -triple powerpc-unknown-aix -fvisibility default -emit-llvm -o - -x c++ %s | \ +// RUN: %clang_cc1 -triple powerpc-unknown-aix -fvisibility default -round-trip-args -emit-llvm -o - -x c++ %s | \ // RUN: FileCheck -check-prefix=VISIBILITY-IR %s __attribute__((visibility("hidden"))) void foo_h(int *p) { @@ -70,28 +63,11 @@ void prambar() {} // VISIBILITY-IR: define weak_odr protected i32 @_ZN5basicIiE7getdataEv(%class.basic* {{[^,]*}} %this) // VISIBILITY-IR: define hidden void @_Z7prambarv() -// VISIBILITY-ASM: .globl _Z5foo_hPi[DS],hidden -// VISIBILITY-ASM: .globl ._Z5foo_hPi,hidden -// VISIBILITY-ASM: .globl _Z3barv[DS],protected -// VISIBILITY-ASM: .globl ._Z3barv,protected -// VISIBILITY-ASM: .weak _ZNK9TestClass5valueEv[DS],hidden -// VISIBILITY-ASM: .weak ._ZNK9TestClass5valueEv,hidden -// VISIBILITY-ASM: .weak _ZN5basicIiE7getdataEv[DS],protected -// VISIBILITY-ASM: .weak ._ZN5basicIiE7getdataEv,protected -// VISIBILITY-ASM: .globl _Z7prambarv[DS],hidden -// VISIBILITY-ASM: .globl ._Z7prambarv,hidden -// VISIBILITY-ASM: .globl b,protected -// VISIBILITY-ASM: .globl pramb,hidden - -// IGNOREVISIBILITY-ASM: .globl _Z5foo_hPi[DS] -// IGNOREVISIBILITY-ASM: .globl ._Z5foo_hPi -// IGNOREVISIBILITY-ASM: .globl _Z3barv[DS] -// IGNOREVISIBILITY-ASM: .globl ._Z3barv -// IGNOREVISIBILITY-ASM: .weak _ZNK9TestClass5valueEv[DS] -// IGNOREVISIBILITY-ASM: .weak ._ZNK9TestClass5valueEv -// IGNOREVISIBILITY-ASM: .weak _ZN5basicIiE7getdataEv[DS] -// IGNOREVISIBILITY-ASM: .weak ._ZN5basicIiE7getdataEv -// IGNOREVISIBILITY-ASM: .globl _Z7prambarv[DS] -// IGNOREVISIBILITY-ASM: .globl ._Z7prambarv -// IGNOREVISIBILITY-ASM: .globl b -// IGNOREVISIBILITY-ASM: .globl pramb +// NOVISIBILITY-IR: @b = global i32 0 +// NOVISIBILITY-IR: @pramb = global i32 0 +// NOVISIBILITY-IR: define void @_Z5foo_hPi(i32* %p) +// NOVISIBILITY-IR: declare void @_Z12zoo_extern_hv() +// NOVISIBILITY-IR: define void @_Z3barv() +// NOVISIBILITY-IR: define linkonce_odr i32 @_ZNK9TestClass5valueEv(%class.TestClass* {{[^,]*}} %this) +// NOVISIBILITY-IR: define weak_odr i32 @_ZN5basicIiE7getdataEv(%class.basic* {{[^,]*}} %this) +// NOVISIBILITY-IR: define void @_Z7prambarv() diff --git a/clang/test/CodeGen/aix-visibility-inlines-hidden.cpp b/clang/test/CodeGen/aix-visibility-inlines-hidden.cpp new file mode 100644 index 000000000000..aadca2984300 --- /dev/null +++ b/clang/test/CodeGen/aix-visibility-inlines-hidden.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple powerpc-unknown-aix -mcmodel=large -emit-llvm -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=NOVISIBILITY-IR %s + +// RUN: %clang_cc1 -triple powerpc-unknown-aix -mcmodel=large \ +// RUN: -fvisibility-inlines-hidden -emit-llvm -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=NOVISIBILITY-IR %s + +// RUN: %clang_cc1 -triple powerpc-unknown-aix -mcmodel=large -fvisibility-inlines-hidden \ +// RUN: -fvisibility default -emit-llvm -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=VISIBILITY-IR %s + +// RUN: %clang_cc1 -triple powerpc-unknown-aix -mcmodel=large -mignore-xcoff-visibility -emit-llvm \ +// RUN: -fvisibility-inlines-hidden -fvisibility default -o - -x c++ %s | \ +// RUN: FileCheck -check-prefix=NOVISIBILITY-IR %s + +int x = 66; +__attribute__((__noinline__)) inline void f() { + x = 55; +} + +#pragma GCC visibility push(hidden) +__attribute__((__noinline__)) inline void foo() { + x = 55; +} +#pragma GCC visibility pop + +int bar() { + f(); + foo(); + return x; +} + +// VISIBILITY-IR: define linkonce_odr hidden void @_Z1fv() +// NOVISIBILITY-IR: define linkonce_odr void @_Z1fv() + +// VISIBILITY-IR: define linkonce_odr hidden void @_Z3foov() +// NOVISIBILITY-IR: define linkonce_odr void @_Z3foov() diff --git a/clang/test/CodeGen/arm-neon-directed-rounding.c b/clang/test/CodeGen/arm-neon-directed-rounding.c index f329c669ba56..c493e3897ab6 100644 --- a/clang/test/CodeGen/arm-neon-directed-rounding.c +++ b/clang/test/CodeGen/arm-neon-directed-rounding.c @@ -41,7 +41,7 @@ float32x4_t test_vrndmq_f32(float32x4_t a) { // CHECK-LABEL: define{{.*}} <2 x float> @test_vrndn_f32(<2 x float> %a) // CHECK-A32: [[VRNDN_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrintn.v2f32(<2 x float> %a) -// CHECK-A64: [[VRNDN_V1_I:%.*]] = call <2 x float> @llvm.aarch64.neon.frintn.v2f32(<2 x float> %a) +// CHECK-A64: [[VRNDN_V1_I:%.*]] = call <2 x float> @llvm.roundeven.v2f32(<2 x float> %a) // CHECK: ret <2 x float> [[VRNDN_V1_I]] float32x2_t test_vrndn_f32(float32x2_t a) { return vrndn_f32(a); @@ -49,7 +49,7 @@ float32x2_t test_vrndn_f32(float32x2_t a) { // CHECK-LABEL: define{{.*}} <4 x float> @test_vrndnq_f32(<4 x float> %a) // CHECK-A32: [[VRNDNQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrintn.v4f32(<4 x float> %a) -// CHECK-A64: [[VRNDNQ_V1_I:%.*]] = call <4 x float> @llvm.aarch64.neon.frintn.v4f32(<4 x float> %a) +// CHECK-A64: [[VRNDNQ_V1_I:%.*]] = call <4 x float> @llvm.roundeven.v4f32(<4 x float> %a) // CHECK: ret <4 x float> [[VRNDNQ_V1_I]] float32x4_t test_vrndnq_f32(float32x4_t a) { return vrndnq_f32(a); @@ -105,7 +105,7 @@ float32x4_t test_vrndq_f32(float32x4_t a) { // CHECK-LABEL: define{{.*}} float @test_vrndns_f32(float %a) // CHECK-A32: [[VRNDN_I:%.*]] = call float @llvm.arm.neon.vrintn.f32(float %a) -// CHECK-A64: [[VRNDN_I:%.*]] = call float @llvm.aarch64.neon.frintn.f32(float %a) +// CHECK-A64: [[VRNDN_I:%.*]] = call float @llvm.roundeven.f32(float %a) // CHECK: ret float [[VRNDN_I]] float32_t test_vrndns_f32(float32_t a) { return vrndns_f32(a); diff --git a/clang/test/CodeGen/arm-sve-vector-bits-vscale-range.c b/clang/test/CodeGen/arm-sve-vector-bits-vscale-range.c new file mode 100644 index 000000000000..84541f9cb12d --- /dev/null +++ b/clang/test/CodeGen/arm-sve-vector-bits-vscale-range.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=128 -S -emit-llvm -o - %s | FileCheck %s -D#VBITS=128 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=256 -S -emit-llvm -o - %s | FileCheck %s -D#VBITS=256 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -S -emit-llvm -o - %s | FileCheck %s -D#VBITS=512 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=1024 -S -emit-llvm -o - %s | FileCheck %s -D#VBITS=1024 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=2048 -S -emit-llvm -o - %s | FileCheck %s -D#VBITS=2048 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=scalable -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-NONE +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-NONE + +// CHECK-LABEL: @func() #0 +// CHECK: attributes #0 = { {{.*}} vscale_range([[#div(VBITS,128)]],[[#div(VBITS,128)]]) {{.*}} } +// CHECK-NONE-NOT: vscale_range +void func() {} diff --git a/clang/test/CodeGen/arm64-vrnd.c b/clang/test/CodeGen/arm64-vrnd.c index c710caedf181..24298f896d31 100644 --- a/clang/test/CodeGen/arm64-vrnd.c +++ b/clang/test/CodeGen/arm64-vrnd.c @@ -6,7 +6,7 @@ float64x2_t rnd5(float64x2_t a) { return vrndq_f64(a); } // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> float64x2_t rnd9(float64x2_t a) { return vrndnq_f64(a); } -// CHECK: call <2 x double> @llvm.aarch64.neon.frintn.v2f64(<2 x double> +// CHECK: call <2 x double> @llvm.roundeven.v2f64(<2 x double> float64x2_t rnd13(float64x2_t a) { return vrndmq_f64(a); } // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> diff --git a/clang/test/CodeGen/arm_acle.c b/clang/test/CodeGen/arm_acle.c index 9f0ad22bda4f..9be0e50136fe 100644 --- a/clang/test/CodeGen/arm_acle.c +++ b/clang/test/CodeGen/arm_acle.c @@ -1,125 +1,231 @@ -// RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O2 -fno-experimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 -check-prefix=ARM-LEGACY -check-prefix=AArch32-LEGACY -// RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 -check-prefix=ARM-NEWPM -check-prefix=AArch32-NEWPM -// RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O2 -fno-experimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 -check-prefix=ARM-LEGACY -check-prefix=AArch64-LEGACY -// RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 -check-prefix=ARM-NEWPM -check-prefix=AArch64-NEWPM -// RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.3a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3 -// RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.4a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3 -// RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.5a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3 - -// REQUIRES: rewrite +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -ffreestanding -triple armv8a-none-eabi -target-feature +crc -target-feature +dsp -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch32 +// RUN: %clang_cc1 -ffreestanding -triple aarch64-none-eabi -target-feature +neon -target-feature +crc -target-feature +crypto -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch64 +// RUN: %clang_cc1 -ffreestanding -triple aarch64-none-eabi -target-feature +v8.3a -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483 +// RUN: %clang_cc1 -ffreestanding -triple aarch64-none-eabi -target-feature +v8.5a -target-feature +rand -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483,AArch6485 #include +// REQUIRES: arm-registered-target,aarch64-registered-target + /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ /* 8.3 Memory Barriers */ -// ARM-LABEL: test_dmb -// AArch32: call void @llvm.arm.dmb(i32 1) -// AArch64: call void @llvm.aarch64.dmb(i32 1) + +// AArch32-LABEL: @test_dmb( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.dmb(i32 1) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_dmb( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.dmb(i32 1) +// AArch64-NEXT: ret void +// void test_dmb(void) { __dmb(1); } -// ARM-LABEL: test_dsb -// AArch32: call void @llvm.arm.dsb(i32 2) -// AArch64: call void @llvm.aarch64.dsb(i32 2) +// AArch32-LABEL: @test_dsb( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.dsb(i32 2) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_dsb( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.dsb(i32 2) +// AArch64-NEXT: ret void +// void test_dsb(void) { __dsb(2); } -// ARM-LABEL: test_isb -// AArch32: call void @llvm.arm.isb(i32 3) -// AArch64: call void @llvm.aarch64.isb(i32 3) +// AArch32-LABEL: @test_isb( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.isb(i32 3) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_isb( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.isb(i32 3) +// AArch64-NEXT: ret void +// void test_isb(void) { __isb(3); } /* 8.4 Hints */ -// ARM-LABEL: test_yield -// AArch32: call void @llvm.arm.hint(i32 1) -// AArch64: call void @llvm.aarch64.hint(i32 1) +// AArch32-LABEL: @test_yield( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.hint(i32 1) [[ATTR1:#.*]] +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_yield( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.hint(i32 1) [[ATTR3:#.*]] +// AArch64-NEXT: ret void +// void test_yield(void) { __yield(); } -// ARM-LABEL: test_wfe -// AArch32: call void @llvm.arm.hint(i32 2) -// AArch64: call void @llvm.aarch64.hint(i32 2) +// AArch32-LABEL: @test_wfe( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.hint(i32 2) [[ATTR1]] +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_wfe( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.hint(i32 2) [[ATTR3]] +// AArch64-NEXT: ret void +// void test_wfe(void) { __wfe(); } -// ARM-LABEL: test_wfi -// AArch32: call void @llvm.arm.hint(i32 3) -// AArch64: call void @llvm.aarch64.hint(i32 3) +// AArch32-LABEL: @test_wfi( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.hint(i32 3) [[ATTR1]] +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_wfi( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.hint(i32 3) [[ATTR3]] +// AArch64-NEXT: ret void +// void test_wfi(void) { __wfi(); } -// ARM-LABEL: test_sev -// AArch32: call void @llvm.arm.hint(i32 4) -// AArch64: call void @llvm.aarch64.hint(i32 4) +// AArch32-LABEL: @test_sev( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.hint(i32 4) [[ATTR1]] +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_sev( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.hint(i32 4) [[ATTR3]] +// AArch64-NEXT: ret void +// void test_sev(void) { __sev(); } -// ARM-LABEL: test_sevl -// AArch32: call void @llvm.arm.hint(i32 5) -// AArch64: call void @llvm.aarch64.hint(i32 5) +// AArch32-LABEL: @test_sevl( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.hint(i32 5) [[ATTR1]] +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_sevl( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.hint(i32 5) [[ATTR3]] +// AArch64-NEXT: ret void +// void test_sevl(void) { __sevl(); } #if __ARM_32BIT_STATE -// AArch32-LABEL: test_dbg -// AArch32: call void @llvm.arm.dbg(i32 0) +// AArch32-LABEL: @test_dbg( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.dbg(i32 0) +// AArch32-NEXT: ret void +// void test_dbg(void) { __dbg(0); } #endif /* 8.5 Swap */ -// ARM-LABEL: test_swp -// AArch32: call i32 @llvm.arm.ldrex -// AArch32: call i32 @llvm.arm.strex -// AArch64: call i64 @llvm.aarch64.ldxr -// AArch64: call i32 @llvm.aarch64.stxr +// AArch32-LABEL: @test_swp( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = bitcast i8* [[P:%.*]] to i32* +// AArch32-NEXT: br label [[DO_BODY_I:%.*]] +// AArch32: do.body.i: +// AArch32-NEXT: [[LDREX_I:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: [[STREX_I:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[X:%.*]], i32* [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STREX_I]], 0 +// AArch32-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], [[LOOP3:!llvm.loop !.*]] +// AArch32: __swp.exit: +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_swp( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = bitcast i8* [[P:%.*]] to i32* +// AArch64-NEXT: br label [[DO_BODY_I:%.*]] +// AArch64: do.body.i: +// AArch64-NEXT: [[LDXR_I:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* [[TMP0]]) [[ATTR3]] +// AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[LDXR_I]] to i32 +// AArch64-NEXT: [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64 +// AArch64-NEXT: [[STXR_I:%.*]] = call i32 @llvm.aarch64.stxr.p0i32(i64 [[TMP2]], i32* [[TMP0]]) [[ATTR3]] +// AArch64-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STXR_I]], 0 +// AArch64-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], [[LOOP6:!llvm.loop !.*]] +// AArch64: __swp.exit: +// AArch64-NEXT: ret void +// void test_swp(uint32_t x, volatile void *p) { __swp(x, p); } /* 8.6 Memory prefetch intrinsics */ /* 8.6.1 Data prefetch */ -// ARM-LABEL: test_pld -// ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 1) +// ARM-LABEL: @test_pld( +// ARM-NEXT: entry: +// ARM-NEXT: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 1) +// ARM-NEXT: ret void +// void test_pld() { __pld(0); } -// ARM-LABEL: test_pldx -// AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 3, i32 1) -// AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 1, i32 1) +// AArch32-LABEL: @test_pldx( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 3, i32 1) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_pldx( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 1, i32 1) +// AArch64-NEXT: ret void +// void test_pldx() { __pldx(1, 2, 0, 0); } /* 8.6.2 Instruction prefetch */ -// ARM-LABEL: test_pli -// ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0) +// ARM-LABEL: @test_pli( +// ARM-NEXT: entry: +// ARM-NEXT: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0) +// ARM-NEXT: ret void +// void test_pli() { __pli(0); } -// ARM-LABEL: test_plix -// AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0) -// AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 1, i32 0) +// AArch32-LABEL: @test_plix( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_plix( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 1, i32 0) +// AArch64-NEXT: ret void +// void test_plix() { __plix(2, 0, 0); } /* 8.7 NOP */ -// ARM-LABEL: test_nop -// AArch32: call void @llvm.arm.hint(i32 0) -// AArch64: call void @llvm.aarch64.hint(i32 0) +// AArch32-LABEL: @test_nop( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.arm.hint(i32 0) [[ATTR1]] +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_nop( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.aarch64.hint(i32 0) [[ATTR3]] +// AArch64-NEXT: ret void +// void test_nop(void) { __nop(); } @@ -127,174 +233,465 @@ void test_nop(void) { /* 9 DATA-PROCESSING INTRINSICS */ /* 9.2 Miscellaneous data-processing intrinsics */ -// ARM-LABEL: test_ror -// ARM-LEGACY: lshr -// ARM-LEGACY: sub -// ARM-LEGACY: shl -// ARM-LEGACY: or -// ARM-NEWPM: call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y) +// ARM-LABEL: @test_ror( +// ARM-NEXT: entry: +// ARM-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 32 +// ARM-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 +// ARM-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] +// ARM: if.then.i: +// ARM-NEXT: br label [[__ROR_EXIT:%.*]] +// ARM: if.end.i: +// ARM-NEXT: [[SHR_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I]] +// ARM-NEXT: [[SUB_I:%.*]] = sub i32 32, [[REM_I]] +// ARM-NEXT: [[SHL_I:%.*]] = shl i32 [[X]], [[SUB_I]] +// ARM-NEXT: [[OR_I:%.*]] = or i32 [[SHR_I]], [[SHL_I]] +// ARM-NEXT: br label [[__ROR_EXIT]] +// ARM: __ror.exit: +// ARM-NEXT: [[RETVAL_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] +// ARM-NEXT: ret i32 [[RETVAL_I_0]] +// uint32_t test_ror(uint32_t x, uint32_t y) { return __ror(x, y); } -// ARM-LABEL: test_rorl -// ARM-LEGACY: lshr -// ARM-LEGACY: sub -// ARM-LEGACY: shl -// ARM-LEGACY: or -// AArch32-NEWPM: call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y) +// AArch32-LABEL: @test_rorl( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[REM_I_I:%.*]] = urem i32 [[Y:%.*]], 32 +// AArch32-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0 +// AArch32-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]] +// AArch32: if.then.i.i: +// AArch32-NEXT: br label [[__RORL_EXIT:%.*]] +// AArch32: if.end.i.i: +// AArch32-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I_I]] +// AArch32-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]] +// AArch32-NEXT: [[SHL_I_I:%.*]] = shl i32 [[X]], [[SUB_I_I]] +// AArch32-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]] +// AArch32-NEXT: br label [[__RORL_EXIT]] +// AArch32: __rorl.exit: +// AArch32-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ] +// AArch32-NEXT: ret i32 [[RETVAL_I_I_0]] +// +// AArch64-LABEL: @test_rorl( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64 +// AArch64-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 +// AArch64-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] +// AArch64: if.then.i: +// AArch64-NEXT: br label [[__RORLL_EXIT:%.*]] +// AArch64: if.end.i: +// AArch64-NEXT: [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64 +// AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]] +// AArch64-NEXT: [[SUB_I:%.*]] = sub i32 64, [[REM_I]] +// AArch64-NEXT: [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64 +// AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]] +// AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]] +// AArch64-NEXT: br label [[__RORLL_EXIT]] +// AArch64: __rorll.exit: +// AArch64-NEXT: [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] +// AArch64-NEXT: ret i64 [[RETVAL_I_0]] +// unsigned long test_rorl(unsigned long x, uint32_t y) { return __rorl(x, y); } -// ARM-LABEL: test_rorll -// ARM: lshr -// ARM: sub -// ARM: shl -// ARM: or +// ARM-LABEL: @test_rorll( +// ARM-NEXT: entry: +// ARM-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64 +// ARM-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 +// ARM-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] +// ARM: if.then.i: +// ARM-NEXT: br label [[__RORLL_EXIT:%.*]] +// ARM: if.end.i: +// ARM-NEXT: [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64 +// ARM-NEXT: [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]] +// ARM-NEXT: [[SUB_I:%.*]] = sub i32 64, [[REM_I]] +// ARM-NEXT: [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64 +// ARM-NEXT: [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]] +// ARM-NEXT: [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]] +// ARM-NEXT: br label [[__RORLL_EXIT]] +// ARM: __rorll.exit: +// ARM-NEXT: [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] +// ARM-NEXT: ret i64 [[RETVAL_I_0]] +// uint64_t test_rorll(uint64_t x, uint32_t y) { return __rorll(x, y); } -// ARM-LABEL: test_clz -// ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false) +// AArch32-LABEL: @test_clz( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// +// AArch64-LABEL: @test_clz( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP0]] +// uint32_t test_clz(uint32_t t) { return __clz(t); } -// ARM-LABEL: test_clzl -// AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false) -// AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false) +// AArch32-LABEL: @test_clzl( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// +// AArch64-LABEL: @test_clzl( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) [[ATTR3]] +// AArch64-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 +// AArch64-NEXT: [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64 +// AArch64-NEXT: ret i64 [[CONV_I]] +// long test_clzl(long t) { return __clzl(t); } -// ARM-LABEL: test_clzll -// ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false) +// AArch32-LABEL: @test_clzll( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) [[ATTR1]] +// AArch32-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 +// AArch32-NEXT: [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64 +// AArch32-NEXT: ret i64 [[CONV_I]] +// +// AArch64-LABEL: @test_clzll( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) [[ATTR3]] +// AArch64-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 +// AArch64-NEXT: [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64 +// AArch64-NEXT: ret i64 [[CONV_I]] +// uint64_t test_clzll(uint64_t t) { return __clzll(t); } -// ARM-LABEL: test_cls -// ARM: call i32 @llvm.arm.cls(i32 %t) +// AArch32-LABEL: @test_cls( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[CLS_I]] +// +// AArch64-LABEL: @test_cls( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls(i32 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[CLS_I]] +// unsigned test_cls(uint32_t t) { return __cls(t); } -// ARM-LABEL: test_clsl -// AArch32: call i32 @llvm.arm.cls(i32 %t) -// AArch64: call i32 @llvm.arm.cls64(i64 %t) +// AArch32-LABEL: @test_clsl( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[CLS_I]] +// +// AArch64-LABEL: @test_clsl( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[CLS_I]] +// unsigned test_clsl(unsigned long t) { return __clsl(t); } -// ARM-LABEL: test_clsll -// ARM: call i32 @llvm.arm.cls64(i64 %t) + +// AArch32-LABEL: @test_clsll( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls64(i64 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[CLS_I]] +// +// AArch64-LABEL: @test_clsll( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[CLS_I]] +// unsigned test_clsll(uint64_t t) { return __clsll(t); } -// ARM-LABEL: test_rev -// ARM: call i32 @llvm.bswap.i32(i32 %t) +// AArch32-LABEL: @test_rev( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// +// AArch64-LABEL: @test_rev( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP0]] +// uint32_t test_rev(uint32_t t) { return __rev(t); } -// ARM-LABEL: test_revl -// AArch32: call i32 @llvm.bswap.i32(i32 %t) -// AArch64: call i64 @llvm.bswap.i64(i64 %t) +// AArch32-LABEL: @test_revl( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// +// AArch64-LABEL: @test_revl( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i64 [[TMP0]] +// long test_revl(long t) { return __revl(t); } -// ARM-LABEL: test_revll -// ARM: call i64 @llvm.bswap.i64(i64 %t) +// AArch32-LABEL: @test_revll( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i64 [[TMP0]] +// +// AArch64-LABEL: @test_revll( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i64 [[TMP0]] +// uint64_t test_revll(uint64_t t) { return __revll(t); } -// ARM-LABEL: test_rev16 -// ARM: llvm.bswap -// ARM-LEGACY: lshr {{.*}}, 16 -// ARM-LEGACY: shl {{.*}}, 16 -// ARM-LEGACY: or -// ARM-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16) +// AArch32-LABEL: @test_rev16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: [[REM_I_I:%.*]] = urem i32 16, 32 +// AArch32-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0 +// AArch32-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]] +// AArch32: if.then.i.i: +// AArch32-NEXT: br label [[__REV16_EXIT:%.*]] +// AArch32: if.end.i.i: +// AArch32-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]] +// AArch32-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]] +// AArch32-NEXT: [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]] +// AArch32-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]] +// AArch32-NEXT: br label [[__REV16_EXIT]] +// AArch32: __rev16.exit: +// AArch32-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ] +// AArch32-NEXT: ret i32 [[RETVAL_I_I_0]] +// +// AArch64-LABEL: @test_rev16( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: [[REM_I_I:%.*]] = urem i32 16, 32 +// AArch64-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0 +// AArch64-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]] +// AArch64: if.then.i.i: +// AArch64-NEXT: br label [[__REV16_EXIT:%.*]] +// AArch64: if.end.i.i: +// AArch64-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]] +// AArch64-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]] +// AArch64-NEXT: [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]] +// AArch64-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]] +// AArch64-NEXT: br label [[__REV16_EXIT]] +// AArch64: __rev16.exit: +// AArch64-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ] +// AArch64-NEXT: ret i32 [[RETVAL_I_I_0]] +// uint32_t test_rev16(uint32_t t) { return __rev16(t); } -// ARM-LABEL: test_rev16l -// AArch32: llvm.bswap -// AArch32-LEGACY: lshr {{.*}}, 16 -// AArch32-LEGACY: shl {{.*}}, 16 -// AArch32-LEGACY: or -// AArch32-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16) -// AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 -// AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32 -// AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) -// AArch64-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16 -// AArch64-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16 -// AArch64-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]] -// AArch64-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16) -// AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64 -// AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32 -// AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32 -// AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) -// AArch64-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16 -// AArch64-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16 -// AArch64-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]] -// AArch64-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16) -// AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64 -// AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]] +// AArch32-LABEL: @test_rev16l( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32 +// AArch32-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 +// AArch32-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] +// AArch32: if.then.i.i.i: +// AArch32-NEXT: br label [[__REV16L_EXIT:%.*]] +// AArch32: if.end.i.i.i: +// AArch32-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I_I]] +// AArch32-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] +// AArch32-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I_I]] +// AArch32-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] +// AArch32-NEXT: br label [[__REV16L_EXIT]] +// AArch32: __rev16l.exit: +// AArch32-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] +// AArch32-NEXT: ret i32 [[RETVAL_I_I_I_0]] +// +// AArch64-LABEL: @test_rev16l( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32 +// AArch64-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32 +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) [[ATTR3]] +// AArch64-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32 +// AArch64-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0 +// AArch64-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]] +// AArch64: if.then.i.i12.i: +// AArch64-NEXT: br label [[__REV16_EXIT18_I:%.*]] +// AArch64: if.end.i.i17.i: +// AArch64-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]] +// AArch64-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]] +// AArch64-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]] +// AArch64-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]] +// AArch64-NEXT: br label [[__REV16_EXIT18_I]] +// AArch64: __rev16.exit18.i: +// AArch64-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ] +// AArch64-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64 +// AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 +// AArch64-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32 +// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) [[ATTR3]] +// AArch64-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32 +// AArch64-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 +// AArch64-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] +// AArch64: if.then.i.i.i: +// AArch64-NEXT: br label [[__REV16LL_EXIT:%.*]] +// AArch64: if.end.i.i.i: +// AArch64-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]] +// AArch64-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] +// AArch64-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]] +// AArch64-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] +// AArch64-NEXT: br label [[__REV16LL_EXIT]] +// AArch64: __rev16ll.exit: +// AArch64-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] +// AArch64-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64 +// AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] +// AArch64-NEXT: ret i64 [[OR_I]] +// long test_rev16l(long t) { return __rev16l(t); } -// ARM-LABEL: test_rev16ll -// ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 -// ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32 -// ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) -// ARM-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16 -// ARM-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16 -// ARM-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]] -// ARM-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16) -// ARM: [[T7:%.*]] = zext i32 [[T6]] to i64 -// ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32 -// ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32 -// ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) -// ARM-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16 -// ARM-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16 -// ARM-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]] -// ARM-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16) -// ARM: [[T14:%.*]] = zext i32 [[T13]] to i64 -// ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]] +// AArch32-LABEL: @test_rev16ll( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32 +// AArch32-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32 +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) [[ATTR1]] +// AArch32-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32 +// AArch32-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0 +// AArch32-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]] +// AArch32: if.then.i.i12.i: +// AArch32-NEXT: br label [[__REV16_EXIT18_I:%.*]] +// AArch32: if.end.i.i17.i: +// AArch32-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]] +// AArch32-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]] +// AArch32-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]] +// AArch32-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]] +// AArch32-NEXT: br label [[__REV16_EXIT18_I]] +// AArch32: __rev16.exit18.i: +// AArch32-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ] +// AArch32-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64 +// AArch32-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 +// AArch32-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32 +// AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) [[ATTR1]] +// AArch32-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32 +// AArch32-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 +// AArch32-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] +// AArch32: if.then.i.i.i: +// AArch32-NEXT: br label [[__REV16LL_EXIT:%.*]] +// AArch32: if.end.i.i.i: +// AArch32-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]] +// AArch32-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] +// AArch32-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]] +// AArch32-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] +// AArch32-NEXT: br label [[__REV16LL_EXIT]] +// AArch32: __rev16ll.exit: +// AArch32-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] +// AArch32-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64 +// AArch32-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] +// AArch32-NEXT: ret i64 [[OR_I]] +// +// AArch64-LABEL: @test_rev16ll( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32 +// AArch64-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32 +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) [[ATTR3]] +// AArch64-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32 +// AArch64-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0 +// AArch64-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]] +// AArch64: if.then.i.i12.i: +// AArch64-NEXT: br label [[__REV16_EXIT18_I:%.*]] +// AArch64: if.end.i.i17.i: +// AArch64-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]] +// AArch64-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]] +// AArch64-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]] +// AArch64-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]] +// AArch64-NEXT: br label [[__REV16_EXIT18_I]] +// AArch64: __rev16.exit18.i: +// AArch64-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ] +// AArch64-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64 +// AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 +// AArch64-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32 +// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) [[ATTR3]] +// AArch64-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32 +// AArch64-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 +// AArch64-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] +// AArch64: if.then.i.i.i: +// AArch64-NEXT: br label [[__REV16LL_EXIT:%.*]] +// AArch64: if.end.i.i.i: +// AArch64-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]] +// AArch64-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] +// AArch64-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]] +// AArch64-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] +// AArch64-NEXT: br label [[__REV16LL_EXIT]] +// AArch64: __rev16ll.exit: +// AArch64-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] +// AArch64-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64 +// AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] +// AArch64-NEXT: ret i64 [[OR_I]] +// uint64_t test_rev16ll(uint64_t t) { return __rev16ll(t); } -// ARM-LABEL: test_revsh -// ARM: call i16 @llvm.bswap.i16(i16 %t) +// AArch32-LABEL: @test_revsh( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i16 [[TMP0]] +// +// AArch64-LABEL: @test_revsh( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i16 [[TMP0]] +// int16_t test_revsh(int16_t t) { return __revsh(t); } -// ARM-LABEL: test_rbit -// AArch32: call i32 @llvm.bitreverse.i32 -// AArch64: call i32 @llvm.bitreverse.i32 +// AArch32-LABEL: @test_rbit( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[RBIT_I]] +// +// AArch64-LABEL: @test_rbit( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[RBIT_I]] +// uint32_t test_rbit(uint32_t t) { return __rbit(t); } -// ARM-LABEL: test_rbitl -// AArch32: call i32 @llvm.bitreverse.i32 -// AArch64: call i64 @llvm.bitreverse.i64 +// AArch32-LABEL: @test_rbitl( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[RBIT_I_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[RBIT_I_I]] +// +// AArch64-LABEL: @test_rbitl( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i64 [[RBIT_I]] +// long test_rbitl(long t) { return __rbitl(t); } -// ARM-LABEL: test_rbitll -// AArch32: call i32 @llvm.bitreverse.i32 -// AArch32: call i32 @llvm.bitreverse.i32 -// AArch64: call i64 @llvm.bitreverse.i64 +// AArch32-LABEL: @test_rbitll( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[CONV_I:%.*]] = trunc i64 [[T:%.*]] to i32 +// AArch32-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV_I]]) [[ATTR1]] +// AArch32-NEXT: [[CONV1_I:%.*]] = zext i32 [[RBIT_I]] to i64 +// AArch32-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 +// AArch32-NEXT: [[SHR_I:%.*]] = lshr i64 [[T]], 32 +// AArch32-NEXT: [[CONV2_I:%.*]] = trunc i64 [[SHR_I]] to i32 +// AArch32-NEXT: [[RBIT3_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV2_I]]) [[ATTR1]] +// AArch32-NEXT: [[CONV4_I:%.*]] = zext i32 [[RBIT3_I]] to i64 +// AArch32-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] +// AArch32-NEXT: ret i64 [[OR_I]] +// +// AArch64-LABEL: @test_rbitll( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i64 [[RBIT_I]] +// uint64_t test_rbitll(uint64_t t) { return __rbitll(t); } @@ -302,14 +699,20 @@ uint64_t test_rbitll(uint64_t t) { /* 9.4 Saturating intrinsics */ #ifdef __ARM_FEATURE_SAT /* 9.4.1 Width-specified saturation intrinsics */ -// AArch32-LABEL: test_ssat -// AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1) +// AArch32-LABEL: @test_ssat( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat(i32 [[T:%.*]], i32 1) +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_ssat(int32_t t) { return __ssat(t, 1); } -// AArch32-LABEL: test_usat -// AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2) +// AArch32-LABEL: @test_usat( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat(i32 [[T:%.*]], i32 2) +// AArch32-NEXT: ret i32 [[TMP0]] +// uint32_t test_usat(int32_t t) { return __usat(t, 2); } @@ -317,23 +720,31 @@ uint32_t test_usat(int32_t t) { /* 9.4.2 Saturating addition and subtraction intrinsics */ #ifdef __ARM_FEATURE_DSP -// AArch32-LABEL: test_qadd -// AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b) +// AArch32-LABEL: @test_qadd( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_qadd(int32_t a, int32_t b) { return __qadd(a, b); } -// AArch32-LABEL: test_qsub -// AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b) +// AArch32-LABEL: @test_qsub( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_qsub(int32_t a, int32_t b) { return __qsub(a, b); } extern int32_t f(); -// AArch32-LABEL: test_qdbl -// AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f -// AArch32-NOT: call {{.*}} @f -// AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]]) +// AArch32-LABEL: @test_qdbl( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() [[ATTR7:#.*]] +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[CALL]], i32 [[CALL]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_qdbl() { return __qdbl(f()); } @@ -343,33 +754,56 @@ int32_t test_qdbl() { * 9.3 16-bit multiplications */ #if __ARM_FEATURE_DSP -// AArch32-LABEL: test_smulbb -// AArch32: call i32 @llvm.arm.smulbb +// AArch32-LABEL: @test_smulbb( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbb(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smulbb(int32_t a, int32_t b) { return __smulbb(a, b); } -// AArch32-LABEL: test_smulbt -// AArch32: call i32 @llvm.arm.smulbt + +// AArch32-LABEL: @test_smulbt( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbt(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smulbt(int32_t a, int32_t b) { return __smulbt(a, b); } -// AArch32-LABEL: test_smultb -// AArch32: call i32 @llvm.arm.smultb + +// AArch32-LABEL: @test_smultb( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultb(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smultb(int32_t a, int32_t b) { return __smultb(a, b); } -// AArch32-LABEL: test_smultt -// AArch32: call i32 @llvm.arm.smultt + +// AArch32-LABEL: @test_smultt( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultt(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smultt(int32_t a, int32_t b) { return __smultt(a, b); } -// AArch32-LABEL: test_smulwb -// AArch32: call i32 @llvm.arm.smulwb + +// AArch32-LABEL: @test_smulwb( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwb(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smulwb(int32_t a, int32_t b) { return __smulwb(a, b); } -// AArch32-LABEL: test_smulwt -// AArch32: call i32 @llvm.arm.smulwt + +// AArch32-LABEL: @test_smulwt( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwt(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smulwt(int32_t a, int32_t b) { return __smulwt(a, b); } @@ -377,33 +811,56 @@ int32_t test_smulwt(int32_t a, int32_t b) { /* 9.4.3 Accumultating multiplications */ #if __ARM_FEATURE_DSP -// AArch32-LABEL: test_smlabb -// AArch32: call i32 @llvm.arm.smlabb(i32 %a, i32 %b, i32 %c) +// AArch32-LABEL: @test_smlabb( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlabb(int32_t a, int32_t b, int32_t c) { return __smlabb(a, b, c); } -// AArch32-LABEL: test_smlabt -// AArch32: call i32 @llvm.arm.smlabt(i32 %a, i32 %b, i32 %c) + +// AArch32-LABEL: @test_smlabt( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlabt(int32_t a, int32_t b, int32_t c) { return __smlabt(a, b, c); } -// AArch32-LABEL: test_smlatb -// AArch32: call i32 @llvm.arm.smlatb(i32 %a, i32 %b, i32 %c) + +// AArch32-LABEL: @test_smlatb( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlatb(int32_t a, int32_t b, int32_t c) { return __smlatb(a, b, c); } -// AArch32-LABEL: test_smlatt -// AArch32: call i32 @llvm.arm.smlatt(i32 %a, i32 %b, i32 %c) + +// AArch32-LABEL: @test_smlatt( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlatt(int32_t a, int32_t b, int32_t c) { return __smlatt(a, b, c); } -// AArch32-LABEL: test_smlawb -// AArch32: call i32 @llvm.arm.smlawb(i32 %a, i32 %b, i32 %c) + +// AArch32-LABEL: @test_smlawb( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlawb(int32_t a, int32_t b, int32_t c) { return __smlawb(a, b, c); } -// AArch32-LABEL: test_smlawt -// AArch32: call i32 @llvm.arm.smlawt(i32 %a, i32 %b, i32 %c) + +// AArch32-LABEL: @test_smlawt( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlawt(int32_t a, int32_t b, int32_t c) { return __smlawt(a, b, c); } @@ -411,13 +868,20 @@ int32_t test_smlawt(int32_t a, int32_t b, int32_t c) { /* 9.5.4 Parallel 16-bit saturation */ #if __ARM_FEATURE_SIMD32 -// AArch32-LABEL: test_ssat16 -// AArch32: call i32 @llvm.arm.ssat16 +// AArch32-LABEL: @test_ssat16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat16(i32 [[A:%.*]], i32 15) +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_ssat16(int16x2_t a) { return __ssat16(a, 15); } -// AArch32-LABEL: test_usat16 -// AArch32: call i32 @llvm.arm.usat16 + +// AArch32-LABEL: @test_usat16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat16(i32 [[A:%.*]], i32 15) +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_usat16(int16x2_t a) { return __usat16(a, 15); } @@ -425,23 +889,38 @@ uint16x2_t test_usat16(int16x2_t a) { /* 9.5.5 Packing and unpacking */ #if __ARM_FEATURE_SIMD32 -// AArch32-LABEL: test_sxtab16 -// AArch32: call i32 @llvm.arm.sxtab16 +// AArch32-LABEL: @test_sxtab16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) { return __sxtab16(a, b); } -// AArch32-LABEL: test_sxtb16 -// AArch32: call i32 @llvm.arm.sxtb16 + +// AArch32-LABEL: @test_sxtb16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtb16(i32 [[A:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_sxtb16(int8x4_t a) { return __sxtb16(a); } -// AArch32-LABEL: test_uxtab16 -// AArch32: call i32 @llvm.arm.uxtab16 + +// AArch32-LABEL: @test_uxtab16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) { return __uxtab16(a, b); } -// AArch32-LABEL: test_uxtb16 -// AArch32: call i32 @llvm.arm.uxtb16 + +// AArch32-LABEL: @test_uxtb16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtb16(i32 [[A:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_uxtb16(int8x4_t a) { return __uxtb16(a); } @@ -449,8 +928,11 @@ int16x2_t test_uxtb16(int8x4_t a) { /* 9.5.6 Parallel selection */ #if __ARM_FEATURE_SIMD32 -// AArch32-LABEL: test_sel -// AArch32: call i32 @llvm.arm.sel +// AArch32-LABEL: @test_sel( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sel(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) { return __sel(a, b); } @@ -458,63 +940,110 @@ uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) { /* 9.5.7 Parallel 8-bit addition and subtraction */ #if __ARM_FEATURE_SIMD32 -// AArch32-LABEL: test_qadd8 -// AArch32: call i32 @llvm.arm.qadd8 +// AArch32-LABEL: @test_qadd8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_qadd8(int8x4_t a, int8x4_t b) { return __qadd8(a, b); } -// AArch32-LABEL: test_qsub8 -// AArch32: call i32 @llvm.arm.qsub8 + +// AArch32-LABEL: @test_qsub8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int8x4_t test_qsub8(int8x4_t a, int8x4_t b) { return __qsub8(a, b); } -// AArch32-LABEL: test_sadd8 -// AArch32: call i32 @llvm.arm.sadd8 + +// AArch32-LABEL: @test_sadd8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int8x4_t test_sadd8(int8x4_t a, int8x4_t b) { return __sadd8(a, b); } -// AArch32-LABEL: test_shadd8 -// AArch32: call i32 @llvm.arm.shadd8 + +// AArch32-LABEL: @test_shadd8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int8x4_t test_shadd8(int8x4_t a, int8x4_t b) { return __shadd8(a, b); } -// AArch32-LABEL: test_shsub8 -// AArch32: call i32 @llvm.arm.shsub8 + +// AArch32-LABEL: @test_shsub8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int8x4_t test_shsub8(int8x4_t a, int8x4_t b) { return __shsub8(a, b); } -// AArch32-LABEL: test_ssub8 -// AArch32: call i32 @llvm.arm.ssub8 + +// AArch32-LABEL: @test_ssub8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int8x4_t test_ssub8(int8x4_t a, int8x4_t b) { return __ssub8(a, b); } -// AArch32-LABEL: test_uadd8 -// AArch32: call i32 @llvm.arm.uadd8 + +// AArch32-LABEL: @test_uadd8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) { return __uadd8(a, b); } -// AArch32-LABEL: test_uhadd8 -// AArch32: call i32 @llvm.arm.uhadd8 + +// AArch32-LABEL: @test_uhadd8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) { return __uhadd8(a, b); } -// AArch32-LABEL: test_uhsub8 -// AArch32: call i32 @llvm.arm.uhsub8 + +// AArch32-LABEL: @test_uhsub8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) { return __uhsub8(a, b); } -// AArch32-LABEL: test_uqadd8 -// AArch32: call i32 @llvm.arm.uqadd8 + +// AArch32-LABEL: @test_uqadd8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) { return __uqadd8(a, b); } -// AArch32-LABEL: test_uqsub8 -// AArch32: call i32 @llvm.arm.uqsub8 + +// AArch32-LABEL: @test_uqsub8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) { return __uqsub8(a, b); } -// AArch32-LABEL: test_usub8 -// AArch32: call i32 @llvm.arm.usub8 + +// AArch32-LABEL: @test_usub8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) { return __usub8(a, b); } @@ -522,13 +1051,23 @@ uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) { /* 9.5.8 Sum of 8-bit absolute differences */ #if __ARM_FEATURE_SIMD32 -// AArch32-LABEL: test_usad8 -// AArch32: call i32 @llvm.arm.usad8 +// AArch32-LABEL: @test_usad8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usad8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint32_t test_usad8(uint8x4_t a, uint8x4_t b) { return __usad8(a, b); } -// AArch32-LABEL: test_usada8 -// AArch32: call i32 @llvm.arm.usada8 + +// AArch32-LABEL: @test_usada8( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 +// AArch32-NEXT: [[CONV1:%.*]] = zext i8 [[B:%.*]] to i32 +// AArch32-NEXT: [[CONV2:%.*]] = zext i8 [[C:%.*]] to i32 +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usada8(i32 [[CONV]], i32 [[CONV1]], i32 [[CONV2]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) { return __usada8(a, b, c); } @@ -536,123 +1075,218 @@ uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) { /* 9.5.9 Parallel 16-bit addition and subtraction */ #if __ARM_FEATURE_SIMD32 -// AArch32-LABEL: test_qadd16 -// AArch32: call i32 @llvm.arm.qadd16 +// AArch32-LABEL: @test_qadd16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_qadd16(int16x2_t a, int16x2_t b) { return __qadd16(a, b); } -// AArch32-LABEL: test_qasx -// AArch32: call i32 @llvm.arm.qasx + +// AArch32-LABEL: @test_qasx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_qasx(int16x2_t a, int16x2_t b) { return __qasx(a, b); } -// AArch32-LABEL: test_qsax -// AArch32: call i32 @llvm.arm.qsax + +// AArch32-LABEL: @test_qsax( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_qsax(int16x2_t a, int16x2_t b) { return __qsax(a, b); } -// AArch32-LABEL: test_qsub16 -// AArch32: call i32 @llvm.arm.qsub16 + +// AArch32-LABEL: @test_qsub16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_qsub16(int16x2_t a, int16x2_t b) { return __qsub16(a, b); } -// AArch32-LABEL: test_sadd16 -// AArch32: call i32 @llvm.arm.sadd16 + +// AArch32-LABEL: @test_sadd16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_sadd16(int16x2_t a, int16x2_t b) { return __sadd16(a, b); } -// AArch32-LABEL: test_sasx -// AArch32: call i32 @llvm.arm.sasx + +// AArch32-LABEL: @test_sasx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_sasx(int16x2_t a, int16x2_t b) { return __sasx(a, b); } -// AArch32-LABEL: test_shadd16 -// AArch32: call i32 @llvm.arm.shadd16 + +// AArch32-LABEL: @test_shadd16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_shadd16(int16x2_t a, int16x2_t b) { return __shadd16(a, b); } -// AArch32-LABEL: test_shasx -// AArch32: call i32 @llvm.arm.shasx + +// AArch32-LABEL: @test_shasx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_shasx(int16x2_t a, int16x2_t b) { return __shasx(a, b); } -// AArch32-LABEL: test_shsax -// AArch32: call i32 @llvm.arm.shsax + +// AArch32-LABEL: @test_shsax( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_shsax(int16x2_t a, int16x2_t b) { return __shsax(a, b); } -// AArch32-LABEL: test_shsub16 -// AArch32: call i32 @llvm.arm.shsub16 + +// AArch32-LABEL: @test_shsub16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_shsub16(int16x2_t a, int16x2_t b) { return __shsub16(a, b); } -// AArch32-LABEL: test_ssax -// AArch32: call i32 @llvm.arm.ssax + +// AArch32-LABEL: @test_ssax( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_ssax(int16x2_t a, int16x2_t b) { return __ssax(a, b); } -// AArch32-LABEL: test_ssub16 -// AArch32: call i32 @llvm.arm.ssub16 + +// AArch32-LABEL: @test_ssub16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int16x2_t test_ssub16(int16x2_t a, int16x2_t b) { return __ssub16(a, b); } -// AArch32-LABEL: test_uadd16 -// AArch32: call i32 @llvm.arm.uadd16 + +// AArch32-LABEL: @test_uadd16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) { return __uadd16(a, b); } -// AArch32-LABEL: test_uasx -// AArch32: call i32 @llvm.arm.uasx + +// AArch32-LABEL: @test_uasx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) { return __uasx(a, b); } -// AArch32-LABEL: test_uhadd16 -// AArch32: call i32 @llvm.arm.uhadd16 + +// AArch32-LABEL: @test_uhadd16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) { return __uhadd16(a, b); } -// AArch32-LABEL: test_uhasx -// AArch32: call i32 @llvm.arm.uhasx + +// AArch32-LABEL: @test_uhasx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) { return __uhasx(a, b); } -// AArch32-LABEL: test_uhsax -// AArch32: call i32 @llvm.arm.uhsax + +// AArch32-LABEL: @test_uhsax( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) { return __uhsax(a, b); } -// AArch32-LABEL: test_uhsub16 -// AArch32: call i32 @llvm.arm.uhsub16 + +// AArch32-LABEL: @test_uhsub16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) { return __uhsub16(a, b); } -// AArch32-LABEL: test_uqadd16 -// AArch32: call i32 @llvm.arm.uqadd16 + +// AArch32-LABEL: @test_uqadd16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) { return __uqadd16(a, b); } -// AArch32-LABEL: test_uqasx -// AArch32: call i32 @llvm.arm.uqasx + +// AArch32-LABEL: @test_uqasx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) { return __uqasx(a, b); } -// AArch32-LABEL: test_uqsax -// AArch32: call i32 @llvm.arm.uqsax + +// AArch32-LABEL: @test_uqsax( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) { return __uqsax(a, b); } -// AArch32-LABEL: test_uqsub16 -// AArch32: call i32 @llvm.arm.uqsub16 + +// AArch32-LABEL: @test_uqsub16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) { return __uqsub16(a, b); } -// AArch32-LABEL: test_usax -// AArch32: call i32 @llvm.arm.usax + +// AArch32-LABEL: @test_usax( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) { return __usax(a, b); } -// AArch32-LABEL: test_usub16 -// AArch32: call i32 @llvm.arm.usub16 + +// AArch32-LABEL: @test_usub16( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) { return __usub16(a, b); } @@ -660,131 +1294,256 @@ uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) { /* 9.5.10 Parallel 16-bit multiplications */ #if __ARM_FEATURE_SIMD32 -// AArch32-LABEL: test_smlad -// AArch32: call i32 @llvm.arm.smlad +// AArch32-LABEL: @test_smlad( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlad(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) { return __smlad(a, b, c); } -// AArch32-LABEL: test_smladx -// AArch32: call i32 @llvm.arm.smladx + +// AArch32-LABEL: @test_smladx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smladx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) { return __smladx(a, b, c); } -// AArch32-LABEL: test_smlald -// AArch32: call i64 @llvm.arm.smlald + +// AArch32-LABEL: @test_smlald( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlald(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i64 [[TMP0]] +// int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) { return __smlald(a, b, c); } -// AArch32-LABEL: test_smlaldx -// AArch32: call i64 @llvm.arm.smlaldx + +// AArch32-LABEL: @test_smlaldx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i64 [[TMP0]] +// int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) { return __smlaldx(a, b, c); } -// AArch32-LABEL: test_smlsd -// AArch32: call i32 @llvm.arm.smlsd + +// AArch32-LABEL: @test_smlsd( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsd(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) { return __smlsd(a, b, c); } -// AArch32-LABEL: test_smlsdx -// AArch32: call i32 @llvm.arm.smlsdx + +// AArch32-LABEL: @test_smlsdx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsdx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) { return __smlsdx(a, b, c); } -// AArch32-LABEL: test_smlsld -// AArch32: call i64 @llvm.arm.smlsld + +// AArch32-LABEL: @test_smlsld( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsld(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i64 [[TMP0]] +// int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) { return __smlsld(a, b, c); } -// AArch32-LABEL: test_smlsldx -// AArch32: call i64 @llvm.arm.smlsldx + +// AArch32-LABEL: @test_smlsldx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i64 [[TMP0]] +// int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) { return __smlsldx(a, b, c); } -// AArch32-LABEL: test_smuad -// AArch32: call i32 @llvm.arm.smuad + +// AArch32-LABEL: @test_smuad( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuad(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smuad(int16x2_t a, int16x2_t b) { return __smuad(a, b); } -// AArch32-LABEL: test_smuadx -// AArch32: call i32 @llvm.arm.smuadx + +// AArch32-LABEL: @test_smuadx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuadx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smuadx(int16x2_t a, int16x2_t b) { return __smuadx(a, b); } -// AArch32-LABEL: test_smusd -// AArch32: call i32 @llvm.arm.smusd + +// AArch32-LABEL: @test_smusd( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusd(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smusd(int16x2_t a, int16x2_t b) { return __smusd(a, b); } -// AArch32-LABEL: test_smusdx -// AArch32: call i32 @llvm.arm.smusdx + +// AArch32-LABEL: @test_smusdx( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusdx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// int32_t test_smusdx(int16x2_t a, int16x2_t b) { return __smusdx(a, b); } #endif /* 9.7 CRC32 intrinsics */ -// ARM-LABEL: test_crc32b -// AArch32: call i32 @llvm.arm.crc32b -// AArch64: call i32 @llvm.aarch64.crc32b +// AArch32-LABEL: @test_crc32b( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 +// AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP1]] +// +// AArch64-LABEL: @test_crc32b( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 +// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP1]] +// uint32_t test_crc32b(uint32_t a, uint8_t b) { return __crc32b(a, b); } -// ARM-LABEL: test_crc32h -// AArch32: call i32 @llvm.arm.crc32h -// AArch64: call i32 @llvm.aarch64.crc32h +// AArch32-LABEL: @test_crc32h( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 +// AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP1]] +// +// AArch64-LABEL: @test_crc32h( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 +// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP1]] +// uint32_t test_crc32h(uint32_t a, uint16_t b) { return __crc32h(a, b); } -// ARM-LABEL: test_crc32w -// AArch32: call i32 @llvm.arm.crc32w -// AArch64: call i32 @llvm.aarch64.crc32w +// AArch32-LABEL: @test_crc32w( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// +// AArch64-LABEL: @test_crc32w( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP0]] +// uint32_t test_crc32w(uint32_t a, uint32_t b) { return __crc32w(a, b); } -// ARM-LABEL: test_crc32d -// AArch32: call i32 @llvm.arm.crc32w -// AArch32: call i32 @llvm.arm.crc32w -// AArch64: call i32 @llvm.aarch64.crc32x +// AArch32-LABEL: @test_crc32d( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32 +// AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32 +// AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +// AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32w(i32 [[TMP3]], i32 [[TMP2]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP4]] +// +// AArch64-LABEL: @test_crc32d( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32x(i32 [[A:%.*]], i64 [[B:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP0]] +// uint32_t test_crc32d(uint32_t a, uint64_t b) { return __crc32d(a, b); } -// ARM-LABEL: test_crc32cb -// AArch32: call i32 @llvm.arm.crc32cb -// AArch64: call i32 @llvm.aarch64.crc32cb +// AArch32-LABEL: @test_crc32cb( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 +// AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP1]] +// +// AArch64-LABEL: @test_crc32cb( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 +// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP1]] +// uint32_t test_crc32cb(uint32_t a, uint8_t b) { return __crc32cb(a, b); } -// ARM-LABEL: test_crc32ch -// AArch32: call i32 @llvm.arm.crc32ch -// AArch64: call i32 @llvm.aarch64.crc32ch +// AArch32-LABEL: @test_crc32ch( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 +// AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP1]] +// +// AArch64-LABEL: @test_crc32ch( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 +// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP1]] +// uint32_t test_crc32ch(uint32_t a, uint16_t b) { return __crc32ch(a, b); } -// ARM-LABEL: test_crc32cw -// AArch32: call i32 @llvm.arm.crc32cw -// AArch64: call i32 @llvm.aarch64.crc32cw +// AArch32-LABEL: @test_crc32cw( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP0]] +// +// AArch64-LABEL: @test_crc32cw( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP0]] +// uint32_t test_crc32cw(uint32_t a, uint32_t b) { return __crc32cw(a, b); } -// ARM-LABEL: test_crc32cd -// AArch32: call i32 @llvm.arm.crc32cw -// AArch32: call i32 @llvm.arm.crc32cw -// AArch64: call i32 @llvm.aarch64.crc32cx +// AArch32-LABEL: @test_crc32cd( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32 +// AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32 +// AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +// AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[TMP3]], i32 [[TMP2]]) [[ATTR1]] +// AArch32-NEXT: ret i32 [[TMP4]] +// +// AArch64-LABEL: @test_crc32cd( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cx(i32 [[A:%.*]], i64 [[B:%.*]]) [[ATTR3]] +// AArch64-NEXT: ret i32 [[TMP0]] +// uint32_t test_crc32cd(uint32_t a, uint64_t b) { return __crc32cd(a, b); } /* 10.1 Special register intrinsics */ -// ARM-LABEL: test_rsr -// AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) -// AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]]) +// AArch32-LABEL: @test_rsr( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata !5) +// AArch32-NEXT: ret i32 [[TMP0]] +// +// AArch64-LABEL: @test_rsr( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8) +// AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +// AArch64-NEXT: ret i32 [[TMP1]] +// uint32_t test_rsr() { #ifdef __ARM_32BIT_STATE return __arm_rsr("cp1:2:c3:c4:5"); @@ -793,9 +1552,16 @@ uint32_t test_rsr() { #endif } -// ARM-LABEL: test_rsr64 -// AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) -// AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]]) +// AArch32-LABEL: @test_rsr64( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !6) +// AArch32-NEXT: ret i64 [[TMP0]] +// +// AArch64-LABEL: @test_rsr64( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8) +// AArch64-NEXT: ret i64 [[TMP0]] +// uint64_t test_rsr64() { #ifdef __ARM_32BIT_STATE return __arm_rsr64("cp1:2:c3"); @@ -804,16 +1570,33 @@ uint64_t test_rsr64() { #endif } -// ARM-LABEL: test_rsrp -// AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]]) -// AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]]) +// AArch32-LABEL: @test_rsrp( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata !7) +// AArch32-NEXT: [[TMP1:%.*]] = inttoptr i32 [[TMP0]] to i8* +// AArch32-NEXT: ret i8* [[TMP1]] +// +// AArch64-LABEL: @test_rsrp( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !9) +// AArch64-NEXT: [[TMP1:%.*]] = inttoptr i64 [[TMP0]] to i8* +// AArch64-NEXT: ret i8* [[TMP1]] +// void *test_rsrp() { return __arm_rsrp("sysreg"); } -// ARM-LABEL: test_wsr -// AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) -// AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}}) +// AArch32-LABEL: @test_wsr( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.write_register.i32(metadata !5, i32 [[V:%.*]]) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_wsr( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = zext i32 [[V:%.*]] to i64 +// AArch64-NEXT: call void @llvm.write_register.i64(metadata !8, i64 [[TMP0]]) +// AArch64-NEXT: ret void +// void test_wsr(uint32_t v) { #ifdef __ARM_32BIT_STATE __arm_wsr("cp1:2:c3:c4:5", v); @@ -822,9 +1605,16 @@ void test_wsr(uint32_t v) { #endif } -// ARM-LABEL: test_wsr64 -// AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) -// AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}}) +// AArch32-LABEL: @test_wsr64( +// AArch32-NEXT: entry: +// AArch32-NEXT: call void @llvm.write_register.i64(metadata !6, i64 [[V:%.*]]) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_wsr64( +// AArch64-NEXT: entry: +// AArch64-NEXT: call void @llvm.write_register.i64(metadata !8, i64 [[V:%.*]]) +// AArch64-NEXT: ret void +// void test_wsr64(uint64_t v) { #ifdef __ARM_32BIT_STATE __arm_wsr64("cp1:2:c3", v); @@ -833,18 +1623,41 @@ void test_wsr64(uint64_t v) { #endif } -// ARM-LABEL: test_wsrp -// AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}}) -// AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}}) +// AArch32-LABEL: @test_wsrp( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[TMP0:%.*]] = ptrtoint i8* [[V:%.*]] to i32 +// AArch32-NEXT: call void @llvm.write_register.i32(metadata !7, i32 [[TMP0]]) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_wsrp( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[TMP0:%.*]] = ptrtoint i8* [[V:%.*]] to i64 +// AArch64-NEXT: call void @llvm.write_register.i64(metadata !9, i64 [[TMP0]]) +// AArch64-NEXT: ret void +// void test_wsrp(void *v) { __arm_wsrp("sysreg", v); } -// ARM-LABEL: test_rsrf -// AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) -// AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]]) -// ARM-NOT: uitofp -// ARM: bitcast +// AArch32-LABEL: @test_rsrf( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4 +// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata !5) +// AArch32-NEXT: store i32 [[TMP0]], i32* [[REF_TMP]], align 4 +// AArch32-NEXT: [[TMP1:%.*]] = bitcast i32* [[REF_TMP]] to float* +// AArch32-NEXT: [[TMP2:%.*]] = load float, float* [[TMP1]], align 4 +// AArch32-NEXT: ret float [[TMP2]] +// +// AArch64-LABEL: @test_rsrf( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4 +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8) +// AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +// AArch64-NEXT: store i32 [[TMP1]], i32* [[REF_TMP]], align 4 +// AArch64-NEXT: [[TMP2:%.*]] = bitcast i32* [[REF_TMP]] to float* +// AArch64-NEXT: [[TMP3:%.*]] = load float, float* [[TMP2]], align 4 +// AArch64-NEXT: ret float [[TMP3]] +// float test_rsrf() { #ifdef __ARM_32BIT_STATE return __arm_rsrf("cp1:2:c3:c4:5"); @@ -852,11 +1665,25 @@ float test_rsrf() { return __arm_rsrf("1:2:3:4:5"); #endif } -// ARM-LABEL: test_rsrf64 -// AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) -// AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]]) -// ARM-NOT: uitofp -// ARM: bitcast + +// AArch32-LABEL: @test_rsrf64( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8 +// AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !6) +// AArch32-NEXT: store i64 [[TMP0]], i64* [[REF_TMP]], align 8 +// AArch32-NEXT: [[TMP1:%.*]] = bitcast i64* [[REF_TMP]] to double* +// AArch32-NEXT: [[TMP2:%.*]] = load double, double* [[TMP1]], align 8 +// AArch32-NEXT: ret double [[TMP2]] +// +// AArch64-LABEL: @test_rsrf64( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8 +// AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8) +// AArch64-NEXT: store i64 [[TMP0]], i64* [[REF_TMP]], align 8 +// AArch64-NEXT: [[TMP1:%.*]] = bitcast i64* [[REF_TMP]] to double* +// AArch64-NEXT: [[TMP2:%.*]] = load double, double* [[TMP1]], align 8 +// AArch64-NEXT: ret double [[TMP2]] +// double test_rsrf64() { #ifdef __ARM_32BIT_STATE return __arm_rsrf64("cp1:2:c3"); @@ -864,11 +1691,26 @@ double test_rsrf64() { return __arm_rsrf64("1:2:3:4:5"); #endif } -// ARM-LABEL: test_wsrf -// ARM-NOT: fptoui -// ARM: bitcast -// AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) -// AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}}) + +// AArch32-LABEL: @test_wsrf( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[V_ADDR:%.*]] = alloca float, align 4 +// AArch32-NEXT: store float [[V:%.*]], float* [[V_ADDR]], align 4 +// AArch32-NEXT: [[TMP0:%.*]] = bitcast float* [[V_ADDR]] to i32* +// AArch32-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +// AArch32-NEXT: call void @llvm.write_register.i32(metadata !5, i32 [[TMP1]]) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_wsrf( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[V_ADDR:%.*]] = alloca float, align 4 +// AArch64-NEXT: store float [[V:%.*]], float* [[V_ADDR]], align 4 +// AArch64-NEXT: [[TMP0:%.*]] = bitcast float* [[V_ADDR]] to i32* +// AArch64-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +// AArch64-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 +// AArch64-NEXT: call void @llvm.write_register.i64(metadata !8, i64 [[TMP2]]) +// AArch64-NEXT: ret void +// void test_wsrf(float v) { #ifdef __ARM_32BIT_STATE __arm_wsrf("cp1:2:c3:c4:5", v); @@ -876,11 +1718,25 @@ void test_wsrf(float v) { __arm_wsrf("1:2:3:4:5", v); #endif } -// ARM-LABEL: test_wsrf64 -// ARM-NOT: fptoui -// ARM: bitcast -// AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) -// AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}}) + +// AArch32-LABEL: @test_wsrf64( +// AArch32-NEXT: entry: +// AArch32-NEXT: [[V_ADDR:%.*]] = alloca double, align 8 +// AArch32-NEXT: store double [[V:%.*]], double* [[V_ADDR]], align 8 +// AArch32-NEXT: [[TMP0:%.*]] = bitcast double* [[V_ADDR]] to i64* +// AArch32-NEXT: [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 8 +// AArch32-NEXT: call void @llvm.write_register.i64(metadata !6, i64 [[TMP1]]) +// AArch32-NEXT: ret void +// +// AArch64-LABEL: @test_wsrf64( +// AArch64-NEXT: entry: +// AArch64-NEXT: [[V_ADDR:%.*]] = alloca double, align 8 +// AArch64-NEXT: store double [[V:%.*]], double* [[V_ADDR]], align 8 +// AArch64-NEXT: [[TMP0:%.*]] = bitcast double* [[V_ADDR]] to i64* +// AArch64-NEXT: [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 8 +// AArch64-NEXT: call void @llvm.write_register.i64(metadata !8, i64 [[TMP1]]) +// AArch64-NEXT: ret void +// void test_wsrf64(double v) { #ifdef __ARM_32BIT_STATE __arm_wsrf64("cp1:2:c3", v); @@ -889,17 +1745,50 @@ void test_wsrf64(double v) { #endif } -// AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"} -// AArch32: ![[M3]] = !{!"cp1:2:c3"} -// AArch32: ![[M4]] = !{!"sysreg"} - -// AArch64: ![[M0]] = !{!"1:2:3:4:5"} -// AArch64: ![[M1]] = !{!"sysreg"} - -// AArch64-v8_3-LABEL: @test_jcvt( -// AArch64-v8_3: call i32 @llvm.aarch64.fjcvtzs #ifdef __ARM_64BIT_STATE +// AArch6483-LABEL: @test_jcvt( +// AArch6483-NEXT: entry: +// AArch6483-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.fjcvtzs(double [[V:%.*]]) [[ATTR3:#.*]] +// AArch6483-NEXT: ret i32 [[TMP0]] +// int32_t test_jcvt(double v) { return __jcvt(v); } #endif + + +#if __ARM_64BIT_STATE && defined(__ARM_FEATURE_RNG) + +// AArch6485-LABEL: @test_rndr( +// AArch6485-NEXT: entry: +// AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndr() [[ATTR3:#.*]] +// AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 +// AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 +// AArch6485-NEXT: store i64 [[TMP1]], i64* [[__ADDR:%.*]], align 8 +// AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +// AArch6485-NEXT: ret i32 [[TMP3]] +// +int test_rndr(uint64_t *__addr) { + return __rndr(__addr); +} + +// AArch6485-LABEL: @test_rndrrs( +// AArch6485-NEXT: entry: +// AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndrrs() [[ATTR3:#.*]] +// AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 +// AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 +// AArch6485-NEXT: store i64 [[TMP1]], i64* [[__ADDR:%.*]], align 8 +// AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +// AArch6485-NEXT: ret i32 [[TMP3]] +// +int test_rndrrs(uint64_t *__addr) { + return __rndrrs(__addr); +} +#endif + +// AArch32: !5 = !{!"cp1:2:c3:c4:5"} +// AArch32: !6 = !{!"cp1:2:c3"} +// AArch32: !7 = !{!"sysreg"} + +// AArch64: !8 = !{!"1:2:3:4:5"} +// AArch64: !9 = !{!"sysreg"} diff --git a/clang/test/CodeGen/atomic-ops.c b/clang/test/CodeGen/atomic-ops.c index 4deb1322e0ff..269406fc3c50 100644 --- a/clang/test/CodeGen/atomic-ops.c +++ b/clang/test/CodeGen/atomic-ops.c @@ -500,6 +500,7 @@ void generalFailureOrder(_Atomic(int) *ptr, int *ptr2, int success, int fail) { // CHECK: [[RELEASE]] // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [ + // CHECK-NEXT: i32 2, label %[[RELEASE_ACQUIRE:[0-9a-zA-Z._]+]] // CHECK-NEXT: ] // CHECK: [[ACQREL]] @@ -527,6 +528,14 @@ void generalFailureOrder(_Atomic(int) *ptr, int *ptr2, int success, int fail) { // CHECK: cmpxchg {{.*}} acquire acquire, align // CHECK: br + // CHECK: [[RELEASE_MONOTONIC]] + // CHECK: cmpxchg {{.*}} release monotonic, align + // CHECK: br + + // CHECK: [[RELEASE_ACQUIRE]] + // CHECK: cmpxchg {{.*}} release acquire, align + // CHECK: br + // CHECK: [[ACQREL_MONOTONIC]] // CHECK: cmpxchg {{.*}} acq_rel monotonic, align // CHECK: br @@ -562,6 +571,20 @@ void generalWeakness(int *ptr, int *ptr2, _Bool weak) { // CHECK-NOT: br // CHECK: cmpxchg weak {{.*}} seq_cst seq_cst, align // CHECK: br + + __atomic_compare_exchange_n(ptr, ptr2, 42, weak, memory_order_release, memory_order_acquire); + // CHECK: switch i1 {{.*}}, label %[[WEAK:[0-9a-zA-Z._]+]] [ + // CHECK-NEXT: i1 false, label %[[STRONG:[0-9a-zA-Z._]+]] + + // CHECK: [[STRONG]] + // CHECK-NOT: br + // CHECK: cmpxchg {{.*}} release acquire + // CHECK: br + + // CHECK: [[WEAK]] + // CHECK-NOT: br + // CHECK: cmpxchg weak {{.*}} release acquire + // CHECK: br } // Having checked the flow in the previous two cases, we'll trust clang to @@ -576,7 +599,9 @@ void EMIT_ALL_THE_THINGS(int *ptr, int *ptr2, int new, _Bool weak, int success, // CHECK: = cmpxchg weak {{.*}} acquire monotonic, align // CHECK: = cmpxchg weak {{.*}} acquire acquire, align // CHECK: = cmpxchg {{.*}} release monotonic, align + // CHECK: = cmpxchg {{.*}} release acquire, align // CHECK: = cmpxchg weak {{.*}} release monotonic, align + // CHECK: = cmpxchg weak {{.*}} release acquire, align // CHECK: = cmpxchg {{.*}} acq_rel monotonic, align // CHECK: = cmpxchg {{.*}} acq_rel acquire, align // CHECK: = cmpxchg weak {{.*}} acq_rel monotonic, align diff --git a/clang/test/CodeGen/attr-speculative-load-hardening.c b/clang/test/CodeGen/attr-speculative-load-hardening.c index 97bccd03585c..784640f93932 100644 --- a/clang/test/CodeGen/attr-speculative-load-hardening.c +++ b/clang/test/CodeGen/attr-speculative-load-hardening.c @@ -12,4 +12,4 @@ int test1() { // NOSLH: @{{.*}}test1{{.*}}[[NOSLH:#[0-9]+]] -// NOSLH-NOT: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} } +// NOSLH-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} } diff --git a/clang/test/CodeGen/attr-weak-import.c b/clang/test/CodeGen/attr-weak-import.c index 85989f03a277..f02d09e81509 100644 --- a/clang/test/CodeGen/attr-weak-import.c +++ b/clang/test/CodeGen/attr-weak-import.c @@ -18,9 +18,9 @@ extern int E __attribute__((weak_import)); int E; extern int E __attribute__((weak_import)); -// CHECK: @A = dso_local global i32 +// CHECK: @A = global i32 // CHECK-NOT: @B = -// CHECK: @C = dso_local global i32 -// CHECK: @D = dso_local global i32 -// CHECK: @E = dso_local global i32 +// CHECK: @C = global i32 +// CHECK: @D = global i32 +// CHECK: @E = global i32 diff --git a/clang/test/CodeGen/builtin_float_strictfp.c b/clang/test/CodeGen/builtin_float_strictfp.c index 001d136c8bd6..8536f52e4823 100644 --- a/clang/test/CodeGen/builtin_float_strictfp.c +++ b/clang/test/CodeGen/builtin_float_strictfp.c @@ -16,8 +16,19 @@ void test_half(__fp16 *H, __fp16 *H2) { // CHECK: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"ogt", metadata !"fpexcept.strict") // CHECK-NEXT: zext i1 (void)__builtin_isinf(*H); - // NOFP16: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") - // FP16: call i1 @llvm.experimental.constrained.fcmp.f16(half %{{.*}}, half 0xH7C00, metadata !"oeq", metadata !"fpexcept.strict") + // NOFP16: [[LDADDR:%.*]] = load i16*, i16** %{{.*}}, align 8 + // NOFP16-NEXT: [[IHALF:%.*]] = load i16, i16* [[LDADDR]], align 2 + // NOFP16-NEXT: [[CONV:%.*]] = call float @llvm.convert.from.fp16.f32(i16 [[IHALF]]) + // NOFP16-NEXT: [[IFLOAT:%.*]] = bitcast float [[CONV]] to i32 + // NOFP16-NEXT: [[SHL:%.*]] = shl i32 [[IFLOAT]], 1 + // NOFP16-NEXT: [[RES1:%.*]] = icmp eq i32 [[SHL]], -16777216 + // NOFP16-NEXT: zext i1 [[RES1]] to i32 + // FP16: [[LDADDR:%.*]] = load half*, half** %{{.*}}, align 8 + // FP16-NEXT: [[HALF:%.*]] = load half, half* [[LDADDR]], align 2 + // FP16-NEXT: [[IHALF:%.*]] = bitcast half [[HALF]] to i16 + // FP16-NEXT: [[SHL:%.*]] = shl i16 [[IHALF]], 1 + // FP16-NEXT: [[RES1:%.*]] = icmp eq i16 [[SHL]], -2048 + // FP16-NEXT: zext i1 [[RES1]] to i32 } // CHECK-LABEL: @test_mixed diff --git a/clang/test/CodeGen/builtins-arm64.c b/clang/test/CodeGen/builtins-arm64.c index 35dbb09ea7ff..9590627d17d4 100644 --- a/clang/test/CodeGen/builtins-arm64.c +++ b/clang/test/CodeGen/builtins-arm64.c @@ -124,4 +124,30 @@ unsigned int clsll(uint64_t v) { return __builtin_arm_cls64(v); } +// CHECK-LABEL: @rndr( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndr() +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 +// CHECK-NEXT: store i64 [[TMP1]], i64* [[__ADDR:%.*]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +// CHECK-NEXT: ret i32 [[TMP3]] +// +int rndr(uint64_t *__addr) { + return __builtin_arm_rndr(__addr); +} + +// CHECK-LABEL: @rndrrs( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndrrs() +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 +// CHECK-NEXT: store i64 [[TMP1]], i64* [[__ADDR:%.*]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +// CHECK-NEXT: ret i32 [[TMP3]] +// +int rndrrs(uint64_t *__addr) { + return __builtin_arm_rndrrs(__addr); +} + // CHECK: ![[M0]] = !{!"1:2:3:4:5"} diff --git a/clang/test/CodeGen/builtins-ppc-p8vector.c b/clang/test/CodeGen/builtins-ppc-p8vector.c index 8f9c62b875db..07494c22f23b 100644 --- a/clang/test/CodeGen/builtins-ppc-p8vector.c +++ b/clang/test/CodeGen/builtins-ppc-p8vector.c @@ -84,6 +84,10 @@ void test1() { // CHECK-LE: add <2 x i64> // CHECK-PPC: error: call to 'vec_add' is ambiguous + res_vuc = vec_add_u128(vuc, vuc); +// CHECK: add <1 x i128> +// CHECK-LE: add <1 x i128> + /* vec_addc */ res_vsi = vec_addc(vsi, vsi); // CHECK: @llvm.ppc.altivec.vaddcuw @@ -99,6 +103,10 @@ void test1() { res_vux = vec_addc(vux, vux); // CHECK: @llvm.ppc.altivec.vaddcuq +// CHECK-LE: @llvm.ppc.altivec.vaddcuq + + res_vuc = vec_addc_u128(vuc, vuc); +// CHECK: @llvm.ppc.altivec.vaddcuq // CHECK-LE: @llvm.ppc.altivec.vaddcuq /* vec_adde */ @@ -108,11 +116,19 @@ void test1() { res_vux = vec_adde(vux, vux, vux); // CHECK: @llvm.ppc.altivec.vaddeuqm +// CHECK-LE: @llvm.ppc.altivec.vaddeuqm + + res_vuc = vec_adde_u128(vuc, vuc, vuc); +// CHECK: @llvm.ppc.altivec.vaddeuqm // CHECK-LE: @llvm.ppc.altivec.vaddeuqm /* vec_addec */ res_vsx = vec_addec(vsx, vsx, vsx); // CHECK: @llvm.ppc.altivec.vaddecuq +// CHECK-LE: @llvm.ppc.altivec.vaddecuq + + res_vuc = vec_addec_u128(vuc, vuc, vuc); +// CHECK: @llvm.ppc.altivec.vaddecuq // CHECK-LE: @llvm.ppc.altivec.vaddecuq /* vec_mergee */ @@ -1606,6 +1622,14 @@ void test1() { // CHECK-LE: llvm.ppc.altivec.vgbbd // CHECK-PPC: warning: implicit declaration of function 'vec_gb' + res_vsll = vec_gbb(vsll); +// CHECK: llvm.ppc.altivec.vgbbd +// CHECK-LE: llvm.ppc.altivec.vgbbd + + res_vull = vec_gbb(vull); +// CHECK: llvm.ppc.altivec.vgbbd +// CHECK-LE: llvm.ppc.altivec.vgbbd + res_vull = vec_bperm(vux, vux); // CHECK: llvm.ppc.altivec.vbpermq // CHECK-LE: llvm.ppc.altivec.vbpermq diff --git a/clang/test/CodeGen/builtins-ppc-quadword-noi128.c b/clang/test/CodeGen/builtins-ppc-quadword-noi128.c new file mode 100644 index 000000000000..bc97db2be1e9 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-quadword-noi128.c @@ -0,0 +1,178 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -O2 -target-feature +altivec -target-feature +power8-vector \ +// RUN: -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck \ +// RUN: %s -check-prefix=CHECK-LE +// RUN: %clang_cc1 -O2 -target-feature +altivec -target-feature +power8-vector \ +// RUN: -triple powerpc64-aix-unknown -emit-llvm %s -o - | FileCheck \ +// RUN: %s -check-prefix=CHECK-AIX +#include +// CHECK-LE-LABEL: @test_subc( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP2:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vsubcuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]]) #[[ATTR3:[0-9]+]] +// CHECK-LE-NEXT: [[TMP3:%.*]] = bitcast <1 x i128> [[TMP2]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP3]] +// +// CHECK-AIX-LABEL: @test_subc( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP2:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vsubcuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]]) #[[ATTR3:[0-9]+]] +// CHECK-AIX-NEXT: [[TMP3:%.*]] = bitcast <1 x i128> [[TMP2]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP3]] +// +vector unsigned char test_subc(vector unsigned char a, vector unsigned char b) { + return vec_subc_u128(a, b); +} +// CHECK-LE-LABEL: @test_subec( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vsubecuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-LE-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP4]] +// +// CHECK-AIX-LABEL: @test_subec( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vsubecuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-AIX-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP4]] +// +vector unsigned char test_subec(vector unsigned char a, vector unsigned char b, + vector unsigned char c) { + return vec_subec_u128(a, b, c); +} +// CHECK-LE-LABEL: @test_sube( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vsubeuqm(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-LE-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP4]] +// +// CHECK-AIX-LABEL: @test_sube( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vsubeuqm(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-AIX-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP4]] +// +vector unsigned char test_sube(vector unsigned char a, vector unsigned char b, + vector unsigned char c) { + return vec_sube_u128(a, b, c); +} +// CHECK-LE-LABEL: @test_sub( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[VADDUQM_I_NEG:%.*]] = sub <1 x i128> [[TMP2]], [[TMP0]] +// CHECK-LE-NEXT: [[VSUBUQM_I:%.*]] = sub <1 x i128> [[VADDUQM_I_NEG]], [[TMP1]] +// CHECK-LE-NEXT: [[TMP3:%.*]] = bitcast <1 x i128> [[VSUBUQM_I]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP3]] +// +// CHECK-AIX-LABEL: @test_sub( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[VADDUQM_I_NEG:%.*]] = sub <1 x i128> [[TMP2]], [[TMP0]] +// CHECK-AIX-NEXT: [[VSUBUQM_I:%.*]] = sub <1 x i128> [[VADDUQM_I_NEG]], [[TMP1]] +// CHECK-AIX-NEXT: [[TMP3:%.*]] = bitcast <1 x i128> [[VSUBUQM_I]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP3]] +// +vector unsigned char test_sub(vector unsigned char a, vector unsigned char b, + vector unsigned char c) { + return vec_sub_u128(a, vec_add_u128(b, c)); +} +// CHECK-LE-LABEL: @test_addc( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP2:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vaddcuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]]) #[[ATTR3]] +// CHECK-LE-NEXT: [[TMP3:%.*]] = bitcast <1 x i128> [[TMP2]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP3]] +// +// CHECK-AIX-LABEL: @test_addc( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP2:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vaddcuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]]) #[[ATTR3]] +// CHECK-AIX-NEXT: [[TMP3:%.*]] = bitcast <1 x i128> [[TMP2]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP3]] +// +vector unsigned char test_addc(vector unsigned char a, vector unsigned char b) { + return vec_addc_u128(a, b); +} +// CHECK-LE-LABEL: @test_addec( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vaddecuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-LE-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP4]] +// +// CHECK-AIX-LABEL: @test_addec( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vaddecuq(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-AIX-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP4]] +// +vector unsigned char test_addec(vector unsigned char a, vector unsigned char b, + vector unsigned char c) { + return vec_addec_u128(a, b, c); +} +// CHECK-LE-LABEL: @test_adde( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vaddeuqm(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-LE-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP4]] +// +// CHECK-AIX-LABEL: @test_adde( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[C:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP3:%.*]] = tail call <1 x i128> @llvm.ppc.altivec.vaddeuqm(<1 x i128> [[TMP0]], <1 x i128> [[TMP1]], <1 x i128> [[TMP2]]) #[[ATTR3]] +// CHECK-AIX-NEXT: [[TMP4:%.*]] = bitcast <1 x i128> [[TMP3]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP4]] +// +vector unsigned char test_adde(vector unsigned char a, vector unsigned char b, + vector unsigned char c) { + return vec_adde_u128(a, b, c); +} +// CHECK-LE-LABEL: @test_add( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-LE-NEXT: [[VADDUQM_I:%.*]] = add <1 x i128> [[TMP1]], [[TMP0]] +// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast <1 x i128> [[VADDUQM_I]] to <16 x i8> +// CHECK-LE-NEXT: ret <16 x i8> [[TMP2]] +// +// CHECK-AIX-LABEL: @test_add( +// CHECK-AIX-NEXT: entry: +// CHECK-AIX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[B:%.*]] to <1 x i128> +// CHECK-AIX-NEXT: [[VADDUQM_I:%.*]] = add <1 x i128> [[TMP1]], [[TMP0]] +// CHECK-AIX-NEXT: [[TMP2:%.*]] = bitcast <1 x i128> [[VADDUQM_I]] to <16 x i8> +// CHECK-AIX-NEXT: ret <16 x i8> [[TMP2]] +// +vector unsigned char test_add(vector unsigned char a, vector unsigned char b) { + return vec_add_u128(a, b); +} diff --git a/clang/test/CodeGen/builtins-ppc-quadword.c b/clang/test/CodeGen/builtins-ppc-quadword.c index 66cc9e8c7a88..561f0c28f225 100644 --- a/clang/test/CodeGen/builtins-ppc-quadword.c +++ b/clang/test/CodeGen/builtins-ppc-quadword.c @@ -14,6 +14,7 @@ vector signed __int128 vlll = { -1 }; // CHECK-PPC: error: __int128 is not supported on this target vector unsigned __int128 vulll = { 1 }; +vector unsigned char vuc; signed long long param_sll; // CHECK-PPC: error: __int128 is not supported on this target @@ -25,6 +26,7 @@ unsigned __int128 param_ulll; vector signed __int128 res_vlll; // CHECK-PPC: error: __int128 is not supported on this target vector unsigned __int128 res_vulll; +vector unsigned char res_vuc; // CHECK-LABEL: define{{.*}} void @test1 @@ -119,6 +121,10 @@ void test1() { // CHECK-LE: sub <1 x i128> // CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + res_vuc = vec_sub_u128(vuc, vuc); +// CHECK: sub <1 x i128> +// CHECK-LE: sub <1 x i128> + /* vec_vsubeuqm */ res_vlll = vec_vsubeuqm(vlll, vlll, vlll); // CHECK: @llvm.ppc.altivec.vsubeuqm @@ -151,6 +157,10 @@ void test1() { // CHECK-LE: @llvm.ppc.altivec.vsubeuqm // CHECK-PPC: error: call to 'vec_sube' is ambiguous + res_vuc = vec_sube_u128(vuc, vuc, vuc); +// CHECK: @llvm.ppc.altivec.vsubeuqm +// CHECK-LE: @llvm.ppc.altivec.vsubeuqm + /* vec_subc */ res_vlll = vec_subc(vlll, vlll); // CHECK: @llvm.ppc.altivec.vsubcuq @@ -162,6 +172,10 @@ void test1() { // CHECK-LE: @llvm.ppc.altivec.vsubcuq // KCHECK-PPC: error: call to 'vec_subc' is ambiguous + res_vuc = vec_subc_u128(vuc, vuc); +// CHECK: @llvm.ppc.altivec.vsubcuq +// CHECK-LE: @llvm.ppc.altivec.vsubcuq + /* vec_vsubcuq */ res_vlll = vec_vsubcuq(vlll, vlll); // CHECK: @llvm.ppc.altivec.vsubcuq @@ -194,6 +208,10 @@ void test1() { // CHECK-LE: @llvm.ppc.altivec.vsubecuq // CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + res_vuc = vec_subec_u128(vuc, vuc, vuc); +// CHECK: @llvm.ppc.altivec.vsubecuq +// CHECK-LE: @llvm.ppc.altivec.vsubecuq + res_vulll = vec_revb(vulll); // CHECK: store <16 x i8> , <16 x i8>* {{%.+}}, align 16 // CHECK: call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> {{%.+}}, <4 x i32> {{%.+}}, <16 x i8> {{%.+}}) diff --git a/clang/test/CodeGen/builtins-ppc-vsx.c b/clang/test/CodeGen/builtins-ppc-vsx.c index 398a5023eaf3..f6157cf46778 100644 --- a/clang/test/CodeGen/builtins-ppc-vsx.c +++ b/clang/test/CodeGen/builtins-ppc-vsx.c @@ -93,6 +93,74 @@ void test1() { // CHECK: fadd <2 x double> // CHECK-LE: fadd <2 x double> + res_i = vec_any_ne(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpeqsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqsp.p + + res_i = vec_any_ne(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + + res_i = vec_any_nle(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpgesp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgesp.p + + res_i = vec_any_nle(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + + res_i = vec_any_nlt(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpgtsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtsp.p + + res_i = vec_any_nlt(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + + res_i = vec_any_nge(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpgesp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgesp.p + + res_i = vec_any_nge(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + + res_i = vec_any_ngt(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpgtsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtsp.p + + res_i = vec_any_ngt(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + + res_i = vec_any_nan(vf); +// CHECK: @llvm.ppc.vsx.xvcmpeqsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqsp.p + + res_i = vec_any_nan(vd); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + + res_i = vec_any_numeric(vf); +// CHECK: @llvm.ppc.vsx.xvcmpeqsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqsp.p + + res_i = vec_any_numeric(vd); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + + dummy(); +// CHECK: call void @dummy() +// CHECK-LE: call void @dummy() + + res_i = vec_all_ne(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpeqsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqsp.p + + res_i = vec_all_ne(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + res_i = vec_all_nle(vf, vf); // CHECK: @llvm.ppc.vsx.xvcmpgesp.p // CHECK-LE: @llvm.ppc.vsx.xvcmpgesp.p @@ -109,6 +177,30 @@ void test1() { // CHECK: @llvm.ppc.vsx.xvcmpgtdp.p // CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + res_i = vec_all_nge(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpgesp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgesp.p + + res_i = vec_all_nge(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + + res_i = vec_all_ngt(vf, vf); +// CHECK: @llvm.ppc.vsx.xvcmpgtsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtsp.p + + res_i = vec_all_ngt(vd, vd); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + + res_i = vec_all_nan(vf); +// CHECK: @llvm.ppc.vsx.xvcmpeqsp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqsp.p + + res_i = vec_all_nan(vd); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + res_i = vec_all_numeric(vf); // CHECK: @llvm.ppc.vsx.xvcmpeqsp.p // CHECK-LE: @llvm.ppc.vsx.xvcmpeqsp.p @@ -1202,6 +1294,32 @@ void test1() { // CHECK-LE: uitofp <2 x i64> %{{.*}} to <2 x double> // CHECK-LE: fmul <2 x double> + res_vd = vec_ctd(vsll, 2); +// CHECK: sitofp <2 x i64> %{{.*}} to <2 x double> +// CHECK: fmul <2 x double> {{.*}} +// CHECK-LE: sitofp <2 x i64> %{{.*}} to <2 x double> +// CHECK-LE: fmul <2 x double> {{.*}} + + res_vd = vec_ctd(vull, 2); +// CHECK: uitofp <2 x i64> %{{.*}} to <2 x double> +// CHECK: fmul <2 x double> {{.*}} +// CHECK-LE: uitofp <2 x i64> %{{.*}} to <2 x double> +// CHECK-LE: fmul <2 x double> {{.*}} + + res_vd = vec_ctd(vsi, 2); +// CHECK: call <2 x double> @llvm.ppc.vsx.xvcvsxwdp(<4 x i32> +// CHECK: fmul <2 x double> {{.*}} +// CHECK-LE: vperm +// CHECK-LE: call <2 x double> @llvm.ppc.vsx.xvcvsxwdp(<4 x i32> +// CHECK-LE: fmul <2 x double> {{.*}} + + res_vd = vec_ctd(vui, 2); +// CHECK: call <2 x double> @llvm.ppc.vsx.xvcvuxwdp(<4 x i32> +// CHECK: fmul <2 x double> {{.*}} +// CHECK-LE: vperm +// CHECK-LE: call <2 x double> @llvm.ppc.vsx.xvcvuxwdp(<4 x i32> +// CHECK-LE: fmul <2 x double> {{.*}} + res_vsll = vec_signed(vd); // CHECK: fptosi <2 x double> // CHECK-LE: fptosi <2 x double> @@ -1401,6 +1519,15 @@ void test1() { // CHECK-LE: sub nsw i32 17 // CHECK-LE: sub nsw i32 18 // CHECK-LE: sub nsw i32 31 +// CHECK-LE: @llvm.ppc.altivec.vperm + + res_vf = vec_cvf(vd); +// CHECK: @llvm.ppc.vsx.xvcvdpsp +// CHECK-LE: @llvm.ppc.vsx.xvcvdpsp +// CHECK-LE: sub nsw i32 16 +// CHECK-LE: sub nsw i32 17 +// CHECK-LE: sub nsw i32 18 +// CHECK-LE: sub nsw i32 31 // CHECK-LE: @llvm.ppc.altivec.vperm res_vf = vec_floato(vsll); @@ -1463,6 +1590,15 @@ void test1() { // CHECK-LE: sub nsw i32 18 // CHECK-LE: sub nsw i32 31 // CHECK-LE: @llvm.ppc.altivec.vperm +// CHECK-LE: @llvm.ppc.vsx.xvcvspdp(<4 x float + + res_vd = vec_cvf(vf); +// CHECK: @llvm.ppc.vsx.xvcvspdp(<4 x float +// CHECK-LE: sub nsw i32 16 +// CHECK-LE: sub nsw i32 17 +// CHECK-LE: sub nsw i32 18 +// CHECK-LE: sub nsw i32 31 +// CHECK-LE: @llvm.ppc.altivec.vperm // CHECK-LE: @llvm.ppc.vsx.xvcvspdp(<4 x float res_vd = vec_doubleh(vsi); @@ -1840,6 +1976,22 @@ res_vuc = vec_xxpermdi(vuc, vuc, 1); // CHECK: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> // CHECK-LE: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> +res_vd = vec_permi(vd, vd, 0); +// CHECK: shufflevector <2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x i32> +// CHECK-LE: shufflevector <2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x i32> + +res_vsll = vec_permi(vsll, vsll, 2); +// CHECK: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> +// CHECK-LE: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> + +res_vull = vec_permi(vull, vull, 3); +// CHECK: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> +// CHECK-LE: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> + +res_vull = vec_permi(vbll, vbll, 3); +// CHECK: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> +// CHECK-LE: shufflevector <2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}}, <2 x i32> + res_vd = vec_xxsldwi(vd, vd, 0); // CHECK: shufflevector <4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}}, <4 x i32> // CHECK-LE: shufflevector <4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}}, <4 x i32> diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c index 771764c85d6b..c27be6d909c0 100644 --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32 -// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64 +// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32 +// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64 // RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD // SIMD convenience types @@ -340,44 +340,44 @@ void store64_lane(long long *p, i64x2 v) { // WEBASSEMBLY-NEXT: ret } -i8x16 add_saturate_s_i8x16(i8x16 x, i8x16 y) { - return __builtin_wasm_add_saturate_s_i8x16(x, y); +i8x16 add_sat_s_i8x16(i8x16 x, i8x16 y) { + return __builtin_wasm_add_sat_s_i8x16(x, y); // WEBASSEMBLY: call <16 x i8> @llvm.sadd.sat.v16i8( // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y) // WEBASSEMBLY-NEXT: ret } -u8x16 add_saturate_u_i8x16(u8x16 x, u8x16 y) { - return __builtin_wasm_add_saturate_u_i8x16(x, y); +u8x16 add_sat_u_i8x16(u8x16 x, u8x16 y) { + return __builtin_wasm_add_sat_u_i8x16(x, y); // WEBASSEMBLY: call <16 x i8> @llvm.uadd.sat.v16i8( // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y) // WEBASSEMBLY-NEXT: ret } -i16x8 add_saturate_s_i16x8(i16x8 x, i16x8 y) { - return __builtin_wasm_add_saturate_s_i16x8(x, y); +i16x8 add_sat_s_i16x8(i16x8 x, i16x8 y) { + return __builtin_wasm_add_sat_s_i16x8(x, y); // WEBASSEMBLY: call <8 x i16> @llvm.sadd.sat.v8i16( // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y) // WEBASSEMBLY-NEXT: ret } -u16x8 add_saturate_u_i16x8(u16x8 x, u16x8 y) { - return __builtin_wasm_add_saturate_u_i16x8(x, y); +u16x8 add_sat_u_i16x8(u16x8 x, u16x8 y) { + return __builtin_wasm_add_sat_u_i16x8(x, y); // WEBASSEMBLY: call <8 x i16> @llvm.uadd.sat.v8i16( // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y) // WEBASSEMBLY-NEXT: ret } -i8x16 sub_saturate_s_i8x16(i8x16 x, i8x16 y) { - return __builtin_wasm_sub_saturate_s_i8x16(x, y); - // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.saturate.signed.v16i8( +i8x16 sub_sat_s_i8x16(i8x16 x, i8x16 y) { + return __builtin_wasm_sub_sat_s_i8x16(x, y); + // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.sat.signed.v16i8( // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y) // WEBASSEMBLY-NEXT: ret } -u8x16 sub_saturate_u_i8x16(u8x16 x, u8x16 y) { - return __builtin_wasm_sub_saturate_u_i8x16(x, y); - // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.saturate.unsigned.v16i8( +u8x16 sub_sat_u_i8x16(u8x16 x, u8x16 y) { + return __builtin_wasm_sub_sat_u_i8x16(x, y); + // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.sat.unsigned.v16i8( // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y) // WEBASSEMBLY-NEXT: ret } @@ -484,16 +484,16 @@ u32x4 max_u_i32x4(u32x4 x, u32x4 y) { // WEBASSEMBLY-NEXT: ret <4 x i32> %1 } -i16x8 sub_saturate_s_i16x8(i16x8 x, i16x8 y) { - return __builtin_wasm_sub_saturate_s_i16x8(x, y); - // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.saturate.signed.v8i16( +i16x8 sub_sat_s_i16x8(i16x8 x, i16x8 y) { + return __builtin_wasm_sub_sat_s_i16x8(x, y); + // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.sat.signed.v8i16( // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y) // WEBASSEMBLY-NEXT: ret } -u16x8 sub_saturate_u_i16x8(u16x8 x, u16x8 y) { - return __builtin_wasm_sub_saturate_u_i16x8(x, y); - // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.saturate.unsigned.v8i16( +u16x8 sub_sat_u_i16x8(u16x8 x, u16x8 y) { + return __builtin_wasm_sub_sat_u_i16x8(x, y); + // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.sat.unsigned.v8i16( // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y) // WEBASSEMBLY-NEXT: ret } @@ -512,9 +512,9 @@ u16x8 avgr_u_i16x8(u16x8 x, u16x8 y) { // WEBASSEMBLY-NEXT: ret } -i16x8 q15mulr_saturate_s_i16x8(i16x8 x, i16x8 y) { - return __builtin_wasm_q15mulr_saturate_s_i16x8(x, y); - // WEBASSEMBLY: call <8 x i16> @llvm.wasm.q15mulr.saturate.signed( +i16x8 q15mulr_sat_s_i16x8(i16x8 x, i16x8 y) { + return __builtin_wasm_q15mulr_sat_s_i16x8(x, y); + // WEBASSEMBLY: call <8 x i16> @llvm.wasm.q15mulr.sat.signed( // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y) // WEBASSEMBLY-NEXT: ret } @@ -644,46 +644,12 @@ i32x4 bitselect(i32x4 x, i32x4 y, i32x4 c) { // WEBASSEMBLY-NEXT: ret } -i8x16 signselect_i8x16(i8x16 x, i8x16 y, i8x16 c) { - return __builtin_wasm_signselect_i8x16(x, y, c); - // WEBASSEMBLY: call <16 x i8> @llvm.wasm.signselect.v16i8( - // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y, <16 x i8> %c) - // WEBASSEMBLY-NEXT: ret -} - -i16x8 signselect_i16x8(i16x8 x, i16x8 y, i16x8 c) { - return __builtin_wasm_signselect_i16x8(x, y, c); - // WEBASSEMBLY: call <8 x i16> @llvm.wasm.signselect.v8i16( - // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y, <8 x i16> %c) - // WEBASSEMBLY-NEXT: ret -} - -i32x4 signselect_i32x4(i32x4 x, i32x4 y, i32x4 c) { - return __builtin_wasm_signselect_i32x4(x, y, c); - // WEBASSEMBLY: call <4 x i32> @llvm.wasm.signselect.v4i32( - // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y, <4 x i32> %c) - // WEBASSEMBLY-NEXT: ret -} - -i64x2 signselect_i64x2(i64x2 x, i64x2 y, i64x2 c) { - return __builtin_wasm_signselect_i64x2(x, y, c); - // WEBASSEMBLY: call <2 x i64> @llvm.wasm.signselect.v2i64( - // WEBASSEMBLY-SAME: <2 x i64> %x, <2 x i64> %y, <2 x i64> %c) - // WEBASSEMBLY-NEXT: ret -} - i8x16 popcnt(i8x16 x) { return __builtin_wasm_popcnt_i8x16(x); // WEBASSEMBLY: call <16 x i8> @llvm.wasm.popcnt(<16 x i8> %x) // WEBASSEMBLY-NEXT: ret } -i64x2 eq_i64x2(i64x2 x, i64x2 y) { - return __builtin_wasm_eq_i64x2(x, y); - // WEBASSEMBLY: call <2 x i64> @llvm.wasm.eq(<2 x i64> %x, <2 x i64> %y) - // WEBASSEMBLY-NEXT: ret -} - int any_true_i8x16(i8x16 x) { return __builtin_wasm_any_true_i8x16(x); // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x) @@ -884,34 +850,6 @@ f64x2 sqrt_f64x2(f64x2 x) { // WEBASSEMBLY: ret } -f32x4 qfma_f32x4(f32x4 a, f32x4 b, f32x4 c) { - return __builtin_wasm_qfma_f32x4(a, b, c); - // WEBASSEMBLY: call <4 x float> @llvm.wasm.qfma.v4f32( - // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b, <4 x float> %c) - // WEBASSEMBLY-NEXT: ret -} - -f32x4 qfms_f32x4(f32x4 a, f32x4 b, f32x4 c) { - return __builtin_wasm_qfms_f32x4(a, b, c); - // WEBASSEMBLY: call <4 x float> @llvm.wasm.qfms.v4f32( - // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b, <4 x float> %c) - // WEBASSEMBLY-NEXT: ret -} - -f64x2 qfma_f64x2(f64x2 a, f64x2 b, f64x2 c) { - return __builtin_wasm_qfma_f64x2(a, b, c); - // WEBASSEMBLY: call <2 x double> @llvm.wasm.qfma.v2f64( - // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b, <2 x double> %c) - // WEBASSEMBLY-NEXT: ret -} - -f64x2 qfms_f64x2(f64x2 a, f64x2 b, f64x2 c) { - return __builtin_wasm_qfms_f64x2(a, b, c); - // WEBASSEMBLY: call <2 x double> @llvm.wasm.qfms.v2f64( - // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b, <2 x double> %c) - // WEBASSEMBLY-NEXT: ret -} - i32x4 trunc_saturate_s_i32x4_f32x4(f32x4 f) { return __builtin_wasm_trunc_saturate_s_i32x4_f32x4(f); // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.signed.v4i32.v4f32(<4 x float> %f) @@ -952,39 +890,27 @@ u16x8 narrow_u_i16x8_i32x4(u32x4 low, u32x4 high) { // WEBASSEMBLY: ret } -i64x2 widen_low_s_i32x4_i64x2(i32x4 x) { - return __builtin_wasm_widen_low_s_i32x4_i64x2(x); - // WEBASSEMBLY: call <2 x i64> @llvm.wasm.widen.low.signed(<4 x i32> %x) +i64x2 extend_low_s_i32x4_i64x2(i32x4 x) { + return __builtin_wasm_extend_low_s_i32x4_i64x2(x); + // WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.low.signed(<4 x i32> %x) // WEBASSEMBLY: ret } -i64x2 widen_high_s_i32x4_i64x2(i32x4 x) { - return __builtin_wasm_widen_high_s_i32x4_i64x2(x); - // WEBASSEMBLY: call <2 x i64> @llvm.wasm.widen.high.signed(<4 x i32> %x) +i64x2 extend_high_s_i32x4_i64x2(i32x4 x) { + return __builtin_wasm_extend_high_s_i32x4_i64x2(x); + // WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.high.signed(<4 x i32> %x) // WEBASSEMBLY: ret } -u64x2 widen_low_u_i32x4_i64x2(u32x4 x) { - return __builtin_wasm_widen_low_u_i32x4_i64x2(x); - // WEBASSEMBLY: call <2 x i64> @llvm.wasm.widen.low.unsigned(<4 x i32> %x) +u64x2 extend_low_u_i32x4_i64x2(u32x4 x) { + return __builtin_wasm_extend_low_u_i32x4_i64x2(x); + // WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.low.unsigned(<4 x i32> %x) // WEBASSEMBLY: ret } -u64x2 widen_high_u_i32x4_i64x2(u32x4 x) { - return __builtin_wasm_widen_high_u_i32x4_i64x2(x); - // WEBASSEMBLY: call <2 x i64> @llvm.wasm.widen.high.unsigned(<4 x i32> %x) - // WEBASSEMBLY: ret -} - -i32x4 widen_s_i8x16_i32x4(i8x16 x) { - return __builtin_wasm_widen_s_i8x16_i32x4(x, 3); - // WEBASSEMBLY: call <4 x i32> @llvm.wasm.widen.signed(<16 x i8> %x, i32 3) - // WEBASSEMBLY: ret -} - -u32x4 widen_u_i8x16_i32x4(u8x16 x) { - return __builtin_wasm_widen_u_i8x16_i32x4(x, 3); - // WEBASSEMBLY: call <4 x i32> @llvm.wasm.widen.unsigned(<16 x i8> %x, i32 3) +u64x2 extend_high_u_i32x4_i64x2(u32x4 x) { + return __builtin_wasm_extend_high_u_i32x4_i64x2(x); + // WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.high.unsigned(<4 x i32> %x) // WEBASSEMBLY: ret } @@ -1000,15 +926,15 @@ f64x2 convert_low_u_i32x4_f64x2(u32x4 x) { // WEBASSEMBLY: ret } -i32x4 trunc_saturate_zero_s_f64x2_i32x4(f64x2 x) { - return __builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4(x); - // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double> %x) +i32x4 trunc_sat_zero_s_f64x2_i32x4(f64x2 x) { + return __builtin_wasm_trunc_sat_zero_s_f64x2_i32x4(x); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.sat.zero.signed(<2 x double> %x) // WEBASSEMBLY: ret } -u32x4 trunc_saturate_zero_u_f64x2_i32x4(f64x2 x) { - return __builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4(x); - // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double> %x) +u32x4 trunc_sat_zero_u_f64x2_i32x4(f64x2 x) { + return __builtin_wasm_trunc_sat_zero_u_f64x2_i32x4(x); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.sat.zero.unsigned(<2 x double> %x) // WEBASSEMBLY: ret } @@ -1050,13 +976,3 @@ i8x16 shuffle(i8x16 x, i8x16 y) { // WEBASSEMBLY-SAME: i32 15 // WEBASSEMBLY-NEXT: ret } - -void prefetch_t(void *p) { - return __builtin_wasm_prefetch_t(p); - // WEBASSEMBLY: call void @llvm.wasm.prefetch.t(i8* %p) -} - -void prefetch_nt(void *p) { - return __builtin_wasm_prefetch_nt(p); - // WEBASSEMBLY: call void @llvm.wasm.prefetch.nt(i8* %p) -} diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp index f49b5088641c..122c621b4cbc 100644 --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -212,8 +212,7 @@ float fun_default FUN(1) #endif float y(); class ON { - // Settings for top level class initializer revert to command line - // source pragma's do not pertain. + // Settings for top level class initializer use program source setting. float z = 2 + y() * 7; //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} #if DEFAULT @@ -224,11 +223,10 @@ class ON { //CHECK-DEBSTRICT: call float {{.*}}llvm.fmuladd #endif #if NOHONOR -//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} +//CHECK-NOHONOR: call float {{.*}}llvm.fmuladd #endif #if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float +//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} #endif }; ON on; @@ -236,18 +234,28 @@ ON on; class OFF { float w = 2 + y() * 7; //CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: call float {{.*}}llvm.fmuladd -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: call float {{.*}}llvm.fmuladd -#endif -#if NOHONOR -//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif +//CHECK: call float {{.*}}llvm.fmuladd }; OFF off; + +#pragma clang fp reassociate(on) +struct MyComplex { + float xx; + float yy; + MyComplex(float x, float y) { + xx = x; + yy = y; + } + MyComplex() {} + const MyComplex operator+(const MyComplex other) const { +//CHECK-LABEL: define {{.*}} @_ZNK9MyComplexplES_ +//CHECK: fadd reassoc float +//CHECK: fadd reassoc float + return MyComplex(xx + other.xx, yy + other.yy); + } +}; +MyComplex useAdd() { + MyComplex a (1, 3); + MyComplex b (2, 4); + return a + b; +} diff --git a/clang/test/CodeGen/hidden-visibility.c b/clang/test/CodeGen/hidden-visibility.c index 65e6616ef19f..585939081cb5 100644 --- a/clang/test/CodeGen/hidden-visibility.c +++ b/clang/test/CodeGen/hidden-visibility.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -fvisibility default -emit-llvm -o - | FileCheck %s // CHECK: hidden global int X __attribute__ ((__visibility__ ("hidden"))) = 123; diff --git a/clang/test/CodeGen/matrix-type-operators.c b/clang/test/CodeGen/matrix-type-operators.c index 3af1662c534f..7d43276ca72a 100644 --- a/clang/test/CodeGen/matrix-type-operators.c +++ b/clang/test/CodeGen/matrix-type-operators.c @@ -729,6 +729,102 @@ void multiply_compound_int_matrix_constant(ix9x3_t a) { a *= 5; } +// CHECK-LABEL: @divide_double_matrix_scalar_float( +// CHECK: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 +// CHECK-NEXT: [[S:%.*]] = load float, float* %s.addr, align 4 +// CHECK-NEXT: [[S_EXT:%.*]] = fpext float [[S]] to double +// CHECK-NEXT: [[VECINSERT:%.*]] = insertelement <25 x double> poison, double [[S_EXT]], i32 0 +// CHECK-NEXT: [[VECSPLAT:%.*]] = shufflevector <25 x double> [[VECINSERT]], <25 x double> poison, <25 x i32> zeroinitializer +// CHECK-NEXT: [[RES:%.*]] = fdiv <25 x double> [[A]], [[VECSPLAT]] +// CHECK-NEXT: store <25 x double> [[RES]], <25 x double>* {{.*}}, align 8 +// CHECK-NEXT: ret void +// +void divide_double_matrix_scalar_float(dx5x5_t a, float s) { + a = a / s; +} + +// CHECK-LABEL: @divide_double_matrix_scalar_double( +// CHECK: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 +// CHECK-NEXT: [[S:%.*]] = load double, double* %s.addr, align 8 +// CHECK-NEXT: [[VECINSERT:%.*]] = insertelement <25 x double> poison, double [[S]], i32 0 +// CHECK-NEXT: [[VECSPLAT:%.*]] = shufflevector <25 x double> [[VECINSERT]], <25 x double> poison, <25 x i32> zeroinitializer +// CHECK-NEXT: [[RES:%.*]] = fdiv <25 x double> [[A]], [[VECSPLAT]] +// CHECK-NEXT: store <25 x double> [[RES]], <25 x double>* {{.*}}, align 8 +// CHECK-NEXT: ret void +// +void divide_double_matrix_scalar_double(dx5x5_t a, double s) { + a = a / s; +} + +// CHECK-LABEL: @divide_float_matrix_scalar_double( +// CHECK: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR:%.*]], align 4 +// CHECK-NEXT: [[S:%.*]] = load double, double* %s.addr, align 8 +// CHECK-NEXT: [[S_TRUNC:%.*]] = fptrunc double [[S]] to float +// CHECK-NEXT: [[VECINSERT:%.*]] = insertelement <6 x float> poison, float [[S_TRUNC]], i32 0 +// CHECK-NEXT: [[VECSPLAT:%.*]] = shufflevector <6 x float> [[VECINSERT]], <6 x float> poison, <6 x i32> zeroinitializer +// CHECK-NEXT: [[RES:%.*]] = fdiv <6 x float> [[MAT]], [[VECSPLAT]] +// CHECK-NEXT: store <6 x float> [[RES]], <6 x float>* [[MAT_ADDR]], align 4 +// CHECK-NEXT: ret void +// +void divide_float_matrix_scalar_double(fx2x3_t b, double s) { + b = b / s; +} + +// CHECK-LABEL: @divide_int_matrix_scalar_short( +// CHECK: [[MAT:%.*]] = load <27 x i32>, <27 x i32>* [[MAT_ADDR:%.*]], align 4 +// CHECK-NEXT: [[S:%.*]] = load i16, i16* %s.addr, align 2 +// CHECK-NEXT: [[S_EXT:%.*]] = sext i16 [[S]] to i32 +// CHECK-NEXT: [[VECINSERT:%.*]] = insertelement <27 x i32> poison, i32 [[S_EXT]], i32 0 +// CHECK-NEXT: [[VECSPLAT:%.*]] = shufflevector <27 x i32> [[VECINSERT]], <27 x i32> poison, <27 x i32> zeroinitializer +// CHECK-NEXT: [[RES:%.*]] = sdiv <27 x i32> [[MAT]], [[VECSPLAT]] +// CHECK-NEXT: store <27 x i32> [[RES]], <27 x i32>* [[MAT_ADDR]], align 4 +// CHECK-NEXT: ret void +// +void divide_int_matrix_scalar_short(ix9x3_t b, short s) { + b = b / s; +} + +// CHECK-LABEL: @divide_int_matrix_scalar_ull( +// CHECK: [[MAT:%.*]] = load <27 x i32>, <27 x i32>* [[MAT_ADDR:%.*]], align 4 +// CHECK-NEXT: [[S:%.*]] = load i64, i64* %s.addr, align 8 +// CHECK-NEXT: [[S_TRUNC:%.*]] = trunc i64 [[S]] to i32 +// CHECK-NEXT: [[VECINSERT:%.*]] = insertelement <27 x i32> poison, i32 [[S_TRUNC]], i32 0 +// CHECK-NEXT: [[VECSPLAT:%.*]] = shufflevector <27 x i32> [[VECINSERT]], <27 x i32> poison, <27 x i32> zeroinitializer +// CHECK-NEXT: [[RES:%.*]] = sdiv <27 x i32> [[MAT]], [[VECSPLAT]] +// CHECK-NEXT: store <27 x i32> [[RES]], <27 x i32>* [[MAT_ADDR]], align 4 +// CHECK-NEXT: ret void +// +void divide_int_matrix_scalar_ull(ix9x3_t b, unsigned long long s) { + b = b / s; +} + +// CHECK-LABEL: @divide_ull_matrix_scalar_ull( +// CHECK: [[MAT:%.*]] = load <8 x i64>, <8 x i64>* [[MAT_ADDR:%.*]], align 8 +// CHECK-NEXT: [[S:%.*]] = load i64, i64* %s.addr, align 8 +// CHECK-NEXT: [[VECINSERT:%.*]] = insertelement <8 x i64> poison, i64 [[S]], i32 0 +// CHECK-NEXT: [[VECSPLAT:%.*]] = shufflevector <8 x i64> [[VECINSERT]], <8 x i64> poison, <8 x i32> zeroinitializer +// CHECK-NEXT: [[RES:%.*]] = udiv <8 x i64> [[MAT]], [[VECSPLAT]] +// CHECK-NEXT: store <8 x i64> [[RES]], <8 x i64>* [[MAT_ADDR]], align 8 +// CHECK-NEXT: ret void +// +void divide_ull_matrix_scalar_ull(ullx4x2_t b, unsigned long long s) { + b = b / s; +} + +// CHECK-LABEL: @divide_float_matrix_constant( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca [6 x float], align 4 +// CHECK-NEXT: [[MAT_ADDR:%.*]] = bitcast [6 x float]* [[A_ADDR]] to <6 x float>* +// CHECK-NEXT: store <6 x float> [[A:%.*]], <6 x float>* [[MAT_ADDR]], align 4 +// CHECK-NEXT: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR]], align 4 +// CHECK-NEXT: [[RES:%.*]] = fdiv <6 x float> [[MAT]], +// CHECK-NEXT: store <6 x float> [[RES]], <6 x float>* [[MAT_ADDR]], align 4 +// CHECK-NEXT: ret void +// +void divide_float_matrix_constant(fx2x3_t a) { + a = a / 2.5; +} + // Tests for the matrix type operators. typedef double dx5x5_t __attribute__((matrix_type(5, 5))); diff --git a/clang/test/CodeGen/matrix-type.c b/clang/test/CodeGen/matrix-type.c index 414401af861b..bb0dc3dd1b86 100644 --- a/clang/test/CodeGen/matrix-type.c +++ b/clang/test/CodeGen/matrix-type.c @@ -4,6 +4,10 @@ #error Expected extension 'matrix_types' to be enabled #endif +#if !__has_extension(matrix_types_scalar_division) +#error Expected extension 'matrix_types_scalar_division' to be enabled +#endif + typedef double dx5x5_t __attribute__((matrix_type(5, 5))); // CHECK: %struct.Matrix = type { i8, [12 x float], float } diff --git a/clang/test/CodeGen/mcount.c b/clang/test/CodeGen/mcount.c index 649f0b56949d..8f994ab4e754 100644 --- a/clang/test/CodeGen/mcount.c +++ b/clang/test/CodeGen/mcount.c @@ -12,6 +12,13 @@ // RUN: %clang_cc1 -pg -triple mipsel-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s // RUN: %clang_cc1 -pg -triple mips64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s // RUN: %clang_cc1 -pg -triple mips64el-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -pg -triple riscv32-elf -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -pg -triple riscv64-elf -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -pg -triple riscv32-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -pg -triple riscv64-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -pg -triple riscv64-freebsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -pg -triple riscv64-freebsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -pg -triple riscv64-openbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s // RUN: %clang_cc1 -pg -triple powerpc-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s // RUN: %clang_cc1 -pg -triple powerpc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s // RUN: %clang_cc1 -pg -triple powerpc64le-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s diff --git a/clang/test/CodeGen/private-extern.c b/clang/test/CodeGen/private-extern.c index 26b3fcede5ab..dae623762ca3 100644 --- a/clang/test/CodeGen/private-extern.c +++ b/clang/test/CodeGen/private-extern.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fvisibility default -emit-llvm -o - %s | FileCheck %s // CHECK-DAG: @g0 = external hidden constant i32 // CHECK-DAG: @g1 = hidden constant i32 1 diff --git a/clang/test/CodeGen/sanitize-coverage-old-pm.c b/clang/test/CodeGen/sanitize-coverage-old-pm.c index a6ded8a0fb98..610dd651587f 100644 --- a/clang/test/CodeGen/sanitize-coverage-old-pm.c +++ b/clang/test/CodeGen/sanitize-coverage-old-pm.c @@ -7,6 +7,8 @@ // // Host armv7 is currently unsupported: https://bugs.llvm.org/show_bug.cgi?id=46117 // XFAIL: armv7, thumbv7 +// The same issue also occurs on a riscv32 host. +// XFAIL: riscv32 int x[10]; diff --git a/clang/test/CodeGen/strictfp_builtins.c b/clang/test/CodeGen/strictfp_builtins.c index 2d55b07ccc11..fbf3c274bd6d 100644 --- a/clang/test/CodeGen/strictfp_builtins.c +++ b/clang/test/CodeGen/strictfp_builtins.c @@ -55,23 +55,114 @@ void test_fpclassify(double d) { return; } -// CHECK-LABEL: @test_isinf( +// CHECK-LABEL: @test_fp16_isinf( // CHECK-NEXT: entry: -// CHECK-NEXT: [[D_ADDR:%.*]] = alloca double, align 8 -// CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[TMP0]]) [[ATTR5]] -// CHECK-NEXT: [[CMPINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") [[ATTR4]] -// CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[CMPINF]] to i32 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0), i32 [[TMP2]]) [[ATTR4]] +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca half, align 2 +// CHECK-NEXT: store half [[H:%.*]], half* [[LD_ADDR]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load half, half* [[LD_ADDR]], align 2 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast half [[TMP0]] to i16 +// CHECK-NEXT: [[SHL1:%.*]] = shl i16 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[SHL1]], -2048 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.[[#STRID:2]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] // CHECK-NEXT: ret void // -void test_isinf(double d) { +void test_fp16_isinf(__fp16 h) { + P(isinf, (h)); + + return; +} + +// CHECK-LABEL: @test_float_isinf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: store float [[F:%.*]], float* [[LD_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[LD_ADDR]], align 4 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast float [[TMP0]] to i32 +// CHECK-NEXT: [[SHL1:%.*]] = shl i32 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SHL1]], -16777216 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_float_isinf(float f) { + P(isinf, (f)); + + return; +} + +// CHECK-LABEL: @test_double_isinf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca double, align 8 +// CHECK-NEXT: store double [[D:%.*]], double* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast double [[TMP0]] to i64 +// CHECK-NEXT: [[SHL1:%.*]] = shl i64 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[SHL1]], -9007199254740992 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_double_isinf(double d) { P(isinf, (d)); return; } +// CHECK-LABEL: @test_fp16_isfinite( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca half, align 2 +// CHECK-NEXT: store half [[H:%.*]], half* [[LD_ADDR]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load half, half* [[LD_ADDR]], align 2 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast half [[TMP0]] to i16 +// CHECK-NEXT: [[SHL1:%.*]] = shl i16 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[SHL1]], -2048 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_fp16_isfinite(__fp16 h) { + P(isfinite, (h)); + + return; +} + +// CHECK-LABEL: @test_float_isfinite( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: store float [[F:%.*]], float* [[LD_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[LD_ADDR]], align 4 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast float [[TMP0]] to i32 +// CHECK-NEXT: [[SHL1:%.*]] = shl i32 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[SHL1]], -16777216 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_float_isfinite(float f) { + P(isfinite, (f)); + + return; +} + +// CHECK-LABEL: @test_double_isfinite( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca double, align 8 +// CHECK-NEXT: store double [[D:%.*]], double* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[LD_ADDR]], align 8 +// CHECK-NEXT: [[BITCAST:%.*]] = bitcast double [[TMP0]] to i64 +// CHECK-NEXT: [[SHL1:%.*]] = shl i64 [[BITCAST]], 1 +// CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL1]], -9007199254740992 +// CHECK-NEXT: [[RES:%.*]] = zext i1 [[CMP]] to i32 +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: ret void +// +void test_double_isfinite(double d) { + P(isfinite, (d)); + + return; +} + // CHECK-LABEL: @test_isinf_sign( // CHECK-NEXT: entry: // CHECK-NEXT: [[D_ADDR:%.*]] = alloca double, align 8 @@ -83,7 +174,7 @@ void test_isinf(double d) { // CHECK-NEXT: [[TMP3:%.*]] = icmp slt i64 [[TMP2]], 0 // CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 -1, i32 1 // CHECK-NEXT: [[TMP5:%.*]] = select i1 [[ISINF]], i32 [[TMP4]], i32 0 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.3, i64 0, i64 0), i32 [[TMP5]]) [[ATTR4]] +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[TMP5]]) [[ATTR4]] // CHECK-NEXT: ret void // void test_isinf_sign(double d) { @@ -102,7 +193,7 @@ void test_isinf_sign(double d) { // CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[#%u,0x7C00]], [[ABS]] // CHECK-NEXT: [[ISNAN:%.*]] = lshr i16 [[TMP1]], 15 // CHECK-NEXT: [[RES:%.*]] = zext i16 [[ISNAN]] to i32 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.4, i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] // CHECK-NEXT: ret void // void test_fp16_isnan(__fp16 h) { @@ -120,7 +211,7 @@ void test_fp16_isnan(__fp16 h) { // CHECK-NEXT: [[ABS:%.*]] = and i32 [[BITCAST]], [[#%u,0x7FFFFFFF]] // CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[#%u,0x7F800000]], [[ABS]] // CHECK-NEXT: [[ISNAN:%.*]] = lshr i32 [[TMP1]], 31 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.5, i64 0, i64 0), i32 [[ISNAN]]) [[ATTR4]] +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[ISNAN]]) [[ATTR4]] // CHECK-NEXT: ret void // void test_float_isnan(float f) { @@ -139,7 +230,7 @@ void test_float_isnan(float f) { // CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[#%u,0x7FF0000000000000]], [[ABS]] // CHECK-NEXT: [[ISNAN:%.*]] = lshr i64 [[TMP1]], 63 // CHECK-NEXT: [[RES:%.*]] = trunc i64 [[ISNAN]] to i32 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.6, i64 0, i64 0), i32 [[RES]]) [[ATTR4]] +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[RES]]) [[ATTR4]] // CHECK-NEXT: ret void // void test_double_isnan(double d) { @@ -160,7 +251,7 @@ void test_double_isnan(double d) { // CHECK-NEXT: [[AND:%.*]] = and i1 [[ISEQ]], [[ISINF]] // CHECK-NEXT: [[AND1:%.*]] = and i1 [[AND]], [[ISNORMAL]] // CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[AND1]] to i32 -// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.7, i64 0, i64 0), i32 [[TMP2]]) [[ATTR4]] +// CHECK-NEXT: call void @p(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.[[#STRID:STRID+1]], i64 0, i64 0), i32 [[TMP2]]) [[ATTR4]] // CHECK-NEXT: ret void // void test_isnormal(double d) { diff --git a/clang/test/CodeGen/thinlto-distributed-newpm.ll b/clang/test/CodeGen/thinlto-distributed-newpm.ll index 867203417754..1e9d5d4d2629 100644 --- a/clang/test/CodeGen/thinlto-distributed-newpm.ll +++ b/clang/test/CodeGen/thinlto-distributed-newpm.ll @@ -12,7 +12,7 @@ ; RUN: %clang -target x86_64-grtev4-linux-gnu \ ; RUN: -O2 -fexperimental-new-pass-manager -Xclang -fdebug-pass-manager \ ; RUN: -c -fthinlto-index=%t.o.thinlto.bc \ -; RUN: -o %t.native.o -x ir %t.o 2>&1 | FileCheck -check-prefixes=CHECK-O,CHECK-O2 %s --dump-input=fail +; RUN: -o %t.native.o -x ir %t.o 2>&1 | FileCheck -check-prefix=CHECK-O %s --dump-input=fail ; RUN: %clang -target x86_64-grtev4-linux-gnu \ ; RUN: -O3 -fexperimental-new-pass-manager -Xclang -fdebug-pass-manager \ @@ -70,24 +70,19 @@ ; CHECK-O: Starting CGSCC pass manager run. ; CHECK-O: Running pass: InlinerPass on (main) ; CHECK-O: Running pass: PostOrderFunctionAttrsPass on (main) -; CHECK-O: Clearing all analysis results for: main +; CHECK-O: Invalidating analysis: DominatorTreeAnalysis on main +; CHECK-O: Invalidating analysis: BasicAA on main +; CHECK-O: Invalidating analysis: AAManager on main ; CHECK-O3: Running pass: ArgumentPromotionPass on (main) -; CHECK-O3: Running analysis: TargetIRAnalysis on main ; CHECK-O: Starting {{.*}}Function pass manager run. ; CHECK-O: Running pass: SROA on main ; These next two can appear in any order since they are accessed as parameters ; on the same call to SROA::runImpl ; CHECK-O-DAG: Running analysis: DominatorTreeAnalysis on main -; CHECK-O-DAG: Running analysis: AssumptionAnalysis on main ; CHECK-O: Running pass: EarlyCSEPass on main -; CHECK-O: Running analysis: TargetLibraryAnalysis on main -; CHECK-O2: Running analysis: TargetIRAnalysis on main ; CHECK-O: Running analysis: MemorySSAAnalysis on main ; CHECK-O: Running analysis: AAManager on main ; CHECK-O: Running analysis: BasicAA on main -; CHECK-O: Running analysis: ScopedNoAliasAA on main -; CHECK-O: Running analysis: TypeBasedAA on main -; CHECK-O: Running analysis: OuterAnalysisManagerProxy ; CHECK-O: Running pass: SpeculativeExecutionPass on main ; CHECK-O: Running pass: JumpThreadingPass on main ; CHECK-O: Running analysis: LazyValueAnalysis on main @@ -96,7 +91,6 @@ ; CHECK-O: Running pass: SimplifyCFGPass on main ; CHECK-O3: Running pass: AggressiveInstCombinePass on main ; CHECK-O: Running pass: InstCombinePass on main -; CHECK-O: Running analysis: OptimizationRemarkEmitterAnalysis on main ; CHECK-O: Running pass: LibCallsShrinkWrapPass on main ; CHECK-O: Running pass: TailCallElimPass on main ; CHECK-O: Running pass: SimplifyCFGPass on main diff --git a/clang/test/CodeGen/thinlto_backend.ll b/clang/test/CodeGen/thinlto_backend.ll index 715ff1ec229e..c8b840e40006 100644 --- a/clang/test/CodeGen/thinlto_backend.ll +++ b/clang/test/CodeGen/thinlto_backend.ll @@ -47,7 +47,7 @@ ; Ensure we get expected error for input files without summaries ; RUN: opt -o %t2.o %s ; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR2 -; CHECK-ERROR2: Error loading imported file '{{.*}}': Could not find module summary +; CHECK-ERROR2: Error loading imported file {{.*}}: Could not find module summary target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/clang/test/CodeGen/unique-internal-linkage-names-dwarf.c b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.c index 916d293f2e5a..e5d507e154ae 100644 --- a/clang/test/CodeGen/unique-internal-linkage-names-dwarf.c +++ b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.c @@ -8,21 +8,48 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=5 -funique-internal-linkage-names -emit-llvm -o - %s | FileCheck %s --check-prefix=UNIQUE static int glob; +// foo should be given a uniquefied name under -funique-internal-linkage-names. static int foo(void) { return glob; } +// bar should not be given a uniquefied name under -funique-internal-linkage-names, +// since it doesn't come with valid prototype. +static int bar(a) int a; +{ + return glob + a; +} + +// go should be given a uniquefied name under -funique-internal-linkage-names, even +// if its definition doesn't come with a valid prototype, but the declaration here +// has a prototype. +static int go(int); + void baz() { foo(); + bar(1); + go(2); } +static int go(a) int a; +{ + return glob + a; +} + + // PLAIN: @glob = internal global i32 // PLAIN: define internal i32 @foo() +// PLAIN: define internal i32 @bar(i32 %a) // PLAIN: distinct !DIGlobalVariable(name: "glob"{{.*}}) // PLAIN: distinct !DISubprogram(name: "foo"{{.*}}) +// PLAIN: distinct !DISubprogram(name: "bar"{{.*}}) +// PLAIN: distinct !DISubprogram(name: "go"{{.*}}) // PLAIN-NOT: linkageName: // -// UNIQUE: @_ZL4glob.[[MODHASH:__uniq.[0-9]+]] = internal global i32 -// UNIQUE: define internal i32 @_ZL3foov.[[MODHASH]]() -// UNIQUE: distinct !DIGlobalVariable(name: "glob", linkageName: "_ZL4glob.[[MODHASH]]"{{.*}}) +// UNIQUE: @glob = internal global i32 +// UNIQUE: define internal i32 @_ZL3foov.[[MODHASH:__uniq.[0-9]+]]() +// UNIQUE: define internal i32 @bar(i32 %a) +// UNIQUE: define internal i32 @_ZL2goi.[[MODHASH]](i32 %a) +// UNIQUE: distinct !DIGlobalVariable(name: "glob"{{.*}}) // UNIQUE: distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov.[[MODHASH]]"{{.*}}) +// UNIQUE: distinct !DISubprogram(name: "go", linkageName: "_ZL2goi.[[MODHASH]]"{{.*}}) diff --git a/clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp index 41b13754396e..37ebfe5eee17 100644 --- a/clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp +++ b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp @@ -46,15 +46,15 @@ void baz() { // PLAIN-DAG: distinct !DIGlobalVariable(name: "glob_zip", linkageName: "_ZL8glob_zip"{{.*}}) // PLAIN-DAG: distinct !DISubprogram(name: "zip", linkageName: "_ZL3zipv"{{.*}}) -// UNIQUE-DAG: @_ZL8glob_foo.[[MODHASH:__uniq\.[0-9]+]] = internal global i32 -// UNIQUE-DAG: define internal i32 @_ZL3foov.[[MODHASH]]() -// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_foo", linkageName: "_ZL8glob_foo.[[MODHASH]]"{{.*}}) +// UNIQUE-DAG: @_ZL8glob_foo = internal global i32 +// UNIQUE-DAG: define internal i32 @_ZL3foov.[[MODHASH:__uniq\.[0-9]+]]() +// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_foo", linkageName: "_ZL8glob_foo"{{.*}}) // UNIQUE-DAG: distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov.[[MODHASH]]"{{.*}}) -// UNIQUE-DAG: @_ZN12_GLOBAL__N_18glob_barE.[[MODHASH]] = internal global i32 +// UNIQUE-DAG: @_ZN12_GLOBAL__N_18glob_barE = internal global i32 // UNIQUE-DAG: define internal i32 @_ZN12_GLOBAL__N_13barEv.[[MODHASH]]() -// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_bar", linkageName: "_ZN12_GLOBAL__N_18glob_barE.[[MODHASH]]"{{.*}}) +// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_bar", linkageName: "_ZN12_GLOBAL__N_18glob_barE"{{.*}}) // UNIQUE-DAG: distinct !DISubprogram(name: "bar", linkageName: "_ZN12_GLOBAL__N_13barEv.[[MODHASH]]"{{.*}}) -// UNIQUE-DAG: @_ZL8glob_zip.[[MODHASH]] = internal global i32 +// UNIQUE-DAG: @_ZL8glob_zip = internal global i32 // UNIQUE-DAG: define internal i32 @_ZL3zipv.[[MODHASH]]() -// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_zip", linkageName: "_ZL8glob_zip.[[MODHASH]]"{{.*}}) +// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_zip", linkageName: "_ZL8glob_zip"{{.*}}) // UNIQUE-DAG: distinct !DISubprogram(name: "zip", linkageName: "_ZL3zipv.[[MODHASH]]"{{.*}}) diff --git a/clang/test/CodeGen/unique-internal-linkage-names.cpp b/clang/test/CodeGen/unique-internal-linkage-names.cpp index d3949a186803..c567bcde45a8 100644 --- a/clang/test/CodeGen/unique-internal-linkage-names.cpp +++ b/clang/test/CodeGen/unique-internal-linkage-names.cpp @@ -51,12 +51,12 @@ int mver_call() { // PLAIN: define internal i32 @_ZL4mverv() // PLAIN: define internal i32 @_ZL4mverv.sse4.2() // PLAIN-NOT: "sample-profile-suffix-elision-policy" -// UNIQUE: @_ZL4glob.__uniq.{{[0-9]+}} = internal global -// UNIQUE: @_ZZ8retAnonMvE5fGlob.__uniq.{{[0-9]+}} = internal global -// UNIQUE: @_ZN12_GLOBAL__N_16anon_mE.__uniq.{{[0-9]+}} = internal global -// UNIQUE: define internal i32 @_ZL3foov.__uniq.{{[0-9]+}}() #[[#ATTR:]] { -// UNIQUE: define internal i32 @_ZN12_GLOBAL__N_14getMEv.__uniq.{{[0-9]+}} -// UNIQUE: define weak_odr i32 ()* @_ZL4mverv.__uniq.{{[0-9]+}}.resolver() -// UNIQUE: define internal i32 @_ZL4mverv.__uniq.{{[0-9]+}}() -// UNIQUE: define internal i32 @_ZL4mverv.__uniq.{{[0-9]+}}.sse4.2 +// UNIQUE: @_ZL4glob = internal global +// UNIQUE: @_ZZ8retAnonMvE5fGlob = internal global +// UNIQUE: @_ZN12_GLOBAL__N_16anon_mE = internal global +// UNIQUE: define internal i32 @_ZL3foov.[[MODHASH:__uniq.[0-9]+]]() #[[#ATTR:]] { +// UNIQUE: define internal i32 @_ZN12_GLOBAL__N_14getMEv.[[MODHASH]] +// UNIQUE: define weak_odr i32 ()* @_ZL4mverv.[[MODHASH]].resolver() +// UNIQUE: define internal i32 @_ZL4mverv.[[MODHASH]]() +// UNIQUE: define internal i32 @_ZL4mverv.[[MODHASH]].sse4.2 // UNIQUE: attributes #[[#ATTR]] = { {{.*}}"sample-profile-suffix-elision-policy"{{.*}} } diff --git a/clang/test/CodeGen/wmemchr.c b/clang/test/CodeGen/wmemchr.c new file mode 100644 index 000000000000..3ff3fba34043 --- /dev/null +++ b/clang/test/CodeGen/wmemchr.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s + +typedef __SIZE_TYPE__ size_t; +typedef __WCHAR_TYPE__ wchar_t; + +const wchar_t *wmemchr_test(const wchar_t *s, const wchar_t c, size_t n) { + // CHECK-LABEL: define dso_local i16* @wmemchr_test + // CHECK: [[S:%.*]] = load + // CHECK: [[C:%.*]] = load + // CHECK: [[N:%.*]] = load + // CHECK: [[N0:%.*]] = icmp eq i64 [[N]], 0 + // CHECK: br i1 [[N0]], label %[[EXIT:.*]], label %[[EQ:.*]] + + // CHECK: [[EQ]]: + // CHECK: [[SP:%.*]] = phi i16* [ [[S]], %[[ENTRY:.*]] ], [ [[SN:.*]], %[[NEXT:.*]] ] + // CHECK: [[NP:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[NN:.*]], %[[NEXT]] ] + // CHECK: [[SL:%.*]] = load i16, i16* [[SP]], align 2 + // CHECK: [[RES:%.*]] = getelementptr inbounds i16, i16* [[SP]], i32 0 + // CHECK: [[CMPEQ:%.*]] = icmp eq i16 [[SL]], [[C]] + // CHECK: br i1 [[CMPEQ]], label %[[EXIT]], label %[[LT:.*]] + + // CHECK: [[NEXT]]: + // CHECK: [[SN]] = getelementptr inbounds i16, i16* [[SP]], i32 1 + // CHECK: [[NN]] = sub i64 [[NP]], 1 + // CHECK: [[NN0:%.*]] = icmp eq i64 [[NN]], 0 + // CHECK: br i1 [[NN0]], label %[[EXIT]], label %[[EQ]] + // + // CHECK: [[EXIT]]: + // CHECK: [[RV:%.*]] = phi i16* [ null, %[[ENTRY]] ], [ null, %[[NEXT]] ], [ [[RES]], %[[EQ]] ] + // CHECK: ret i16* [[RV]] + return __builtin_wmemchr(s, c, n); +} diff --git a/clang/test/CodeGenCUDA/builtin-mangled-name.cu b/clang/test/CodeGenCUDA/builtin-mangled-name.cu new file mode 100644 index 000000000000..e9dca5680155 --- /dev/null +++ b/clang/test/CodeGenCUDA/builtin-mangled-name.cu @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-gnu-linux -aux-triple amdgcn-amd-amdhsa \ +// RUN: -emit-llvm -o - -x hip %s | FileCheck -check-prefixes=CHECK,LNX %s +// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -aux-triple amdgcn-amd-amdhsa \ +// RUN: -emit-llvm -o - -x hip %s | FileCheck -check-prefixes=CHECK,MSVC %s + +#include "Inputs/cuda.h" + +namespace X { + __global__ void kern1(int *x); + __device__ int var1; +} + +// CHECK: @[[STR1:.*]] = {{.*}} c"_ZN1X5kern1EPi\00" +// CHECK: @[[STR2:.*]] = {{.*}} c"_ZN1X4var1E\00" + +// LNX-LABEL: define {{.*}}@_Z4fun1v() +// MSVC-LABEL: define {{.*}} @"?fun1@@YAPEBDXZ"() +// CHECK: ret i8* getelementptr inbounds ({{.*}} @[[STR1]], i64 0, i64 0) +const char *fun1() { + return __builtin_get_device_side_mangled_name(X::kern1); +} + +// LNX-LABEL: define {{.*}}@_Z4fun2v() +// MSVC-LABEL: define {{.*}}@"?fun2@@YAPEBDXZ"() +// CHECK: ret i8* getelementptr inbounds ({{.*}} @[[STR2]], i64 0, i64 0) +__host__ __device__ const char *fun2() { + return __builtin_get_device_side_mangled_name(X::var1); +} diff --git a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp index ec2ee37f97c0..27e8a4999c32 100644 --- a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp +++ b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp @@ -1,60 +1,263 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu -verify // RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s +// CHECK-LABEL: @_Z2wli( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[E:%.*]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT: br label [[WHILE_COND:%.*]] +// CHECK: while.cond: +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 true) +// CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]] +// CHECK: while.body: +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// CHECK-NEXT: store i32 [[INC]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[WHILE_COND]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK: while.end: +// CHECK-NEXT: ret void +// void wl(int e){ - // CHECK-LABEL: define{{.*}}wl - // CHECK: br {{.*}} !prof !6 while(e) [[likely]] ++e; } +// CHECK-LABEL: @_Z2wui( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[E:%.*]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[WHILE_COND:%.*]] +// CHECK: while.cond: +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) +// CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]] +// CHECK: while.body: +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// CHECK-NEXT: store i32 [[INC]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[WHILE_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK: while.end: +// CHECK-NEXT: ret void +// void wu(int e){ - // CHECK-LABEL: define{{.*}}wu - // CHECK: br {{.*}} !prof !10 while(e) [[unlikely]] ++e; } +// CHECK-LABEL: @_Z15w_branch_elidedj( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[E:%.*]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[WHILE_BODY:%.*]] +// CHECK: while.body: +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add i32 [[TMP0]], 1 +// CHECK-NEXT: store i32 [[INC]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[WHILE_BODY]], !llvm.loop [[LOOP10:![0-9]+]] +// void w_branch_elided(unsigned e){ - // CHECK-LABEL: define{{.*}}w_branch_elided - // CHECK-NOT: br {{.*}} !prof // expected-warning@+2 {{attribute 'likely' has no effect when annotating an infinite loop}} // expected-note@+1 {{annotating the infinite loop here}} while(1) [[likely]] ++e; } +// CHECK-LABEL: @_Z2flj( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[E:%.*]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR4:[0-9]+]] +// CHECK-NEXT: store i32 0, i32* [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[FOR_COND:%.*]] +// CHECK: for.cond: +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[TMP2]] +// CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 true) +// CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] +// CHECK: for.cond.cleanup: +// CHECK-NEXT: [[TMP3:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR4]] +// CHECK-NEXT: br label [[FOR_END:%.*]] +// CHECK: for.body: +// CHECK-NEXT: br label [[FOR_INC:%.*]] +// CHECK: for.inc: +// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add i32 [[TMP4]], 1 +// CHECK-NEXT: store i32 [[INC]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]] +// CHECK: for.end: +// CHECK-NEXT: ret void +// void fl(unsigned e) { - // CHECK-LABEL: define{{.*}}fl - // CHECK: br {{.*}} !prof !6 for(int i = 0; i != e; ++e) [[likely]]; } +// CHECK-LABEL: @_Z2fui( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[E:%.*]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR4]] +// CHECK-NEXT: store i32 0, i32* [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[FOR_COND:%.*]] +// CHECK: for.cond: +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[TMP2]] +// CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 false) +// CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] +// CHECK: for.cond.cleanup: +// CHECK-NEXT: [[TMP3:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR4]] +// CHECK-NEXT: br label [[FOR_END:%.*]] +// CHECK: for.body: +// CHECK-NEXT: br label [[FOR_INC:%.*]] +// CHECK: for.inc: +// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK-NEXT: store i32 [[INC]], i32* [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK: for.end: +// CHECK-NEXT: ret void +// void fu(int e) { - // CHECK-LABEL: define{{.*}}fu - // CHECK: br {{.*}} !prof !10 for(int i = 0; i != e; ++e) [[unlikely]]; } +// CHECK-LABEL: @_Z15f_branch_elidedv( +// CHECK-NEXT: entry: +// CHECK-NEXT: br label [[FOR_COND:%.*]] +// CHECK: for.cond: +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP13:![0-9]+]] +// void f_branch_elided() { - // CHECK-LABEL: define{{.*}}f_branch_elided - // CHECK-NOT: br {{.*}} !prof for(;;) [[likely]]; } +// CHECK-LABEL: @_Z3frlOA4_i( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[E_ADDR:%.*]] = alloca [4 x i32]*, align 8 +// CHECK-NEXT: [[__RANGE1:%.*]] = alloca [4 x i32]*, align 8 +// CHECK-NEXT: [[__BEGIN1:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[__END1:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store [4 x i32]* [[E:%.*]], [4 x i32]** [[E_ADDR]], align 8, !tbaa [[TBAA14:![0-9]+]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast [4 x i32]** [[__RANGE1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP0]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP1:%.*]] = load [4 x i32]*, [4 x i32]** [[E_ADDR]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: store [4 x i32]* [[TMP1]], [4 x i32]** [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i32** [[__BEGIN1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP2]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP3:%.*]] = load [4 x i32]*, [4 x i32]** [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[TMP3]], i64 0, i64 0 +// CHECK-NEXT: store i32* [[ARRAYDECAY]], i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP4:%.*]] = bitcast i32** [[__END1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP4]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP5:%.*]] = load [4 x i32]*, [4 x i32]** [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[TMP5]], i64 0, i64 0 +// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAYDECAY1]], i64 4 +// CHECK-NEXT: store i32* [[ADD_PTR]], i32** [[__END1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: br label [[FOR_COND:%.*]] +// CHECK: for.cond: +// CHECK-NEXT: [[TMP6:%.*]] = load i32*, i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP7:%.*]] = load i32*, i32** [[__END1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[TMP6]], [[TMP7]] +// CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 true) +// CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] +// CHECK: for.cond.cleanup: +// CHECK-NEXT: [[TMP8:%.*]] = bitcast i32** [[__END1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP8]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP9:%.*]] = bitcast i32** [[__BEGIN1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP9]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP10:%.*]] = bitcast [4 x i32]** [[__RANGE1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP10]]) #[[ATTR4]] +// CHECK-NEXT: br label [[FOR_END:%.*]] +// CHECK: for.body: +// CHECK-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP12:%.*]] = load i32*, i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: store i32 [[TMP13]], i32* [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP14:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP14]]) #[[ATTR4]] +// CHECK-NEXT: br label [[FOR_INC:%.*]] +// CHECK: for.inc: +// CHECK-NEXT: [[TMP15:%.*]] = load i32*, i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP15]], i32 1 +// CHECK-NEXT: store i32* [[INCDEC_PTR]], i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK: for.end: +// CHECK-NEXT: ret void +// void frl(int (&&e) [4]) { - // CHECK-LABEL: define{{.*}}frl - // CHECK: br {{.*}} !prof !6 for(int i : e) [[likely]]; } +// CHECK-LABEL: @_Z3fruOA4_i( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[E_ADDR:%.*]] = alloca [4 x i32]*, align 8 +// CHECK-NEXT: [[__RANGE1:%.*]] = alloca [4 x i32]*, align 8 +// CHECK-NEXT: [[__BEGIN1:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[__END1:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store [4 x i32]* [[E:%.*]], [4 x i32]** [[E_ADDR]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast [4 x i32]** [[__RANGE1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP0]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP1:%.*]] = load [4 x i32]*, [4 x i32]** [[E_ADDR]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: store [4 x i32]* [[TMP1]], [4 x i32]** [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i32** [[__BEGIN1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP2]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP3:%.*]] = load [4 x i32]*, [4 x i32]** [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[TMP3]], i64 0, i64 0 +// CHECK-NEXT: store i32* [[ARRAYDECAY]], i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP4:%.*]] = bitcast i32** [[__END1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP4]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP5:%.*]] = load [4 x i32]*, [4 x i32]** [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[TMP5]], i64 0, i64 0 +// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAYDECAY1]], i64 4 +// CHECK-NEXT: store i32* [[ADD_PTR]], i32** [[__END1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: br label [[FOR_COND:%.*]] +// CHECK: for.cond: +// CHECK-NEXT: [[TMP6:%.*]] = load i32*, i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP7:%.*]] = load i32*, i32** [[__END1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[TMP6]], [[TMP7]] +// CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 false) +// CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] +// CHECK: for.cond.cleanup: +// CHECK-NEXT: [[TMP8:%.*]] = bitcast i32** [[__END1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP8]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP9:%.*]] = bitcast i32** [[__BEGIN1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP9]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP10:%.*]] = bitcast [4 x i32]** [[__RANGE1]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP10]]) #[[ATTR4]] +// CHECK-NEXT: br label [[FOR_END:%.*]] +// CHECK: for.body: +// CHECK-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR4]] +// CHECK-NEXT: [[TMP12:%.*]] = load i32*, i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: store i32 [[TMP13]], i32* [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP14:%.*]] = bitcast i32* [[I]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP14]]) #[[ATTR4]] +// CHECK-NEXT: br label [[FOR_INC:%.*]] +// CHECK: for.inc: +// CHECK-NEXT: [[TMP15:%.*]] = load i32*, i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP15]], i32 1 +// CHECK-NEXT: store i32* [[INCDEC_PTR]], i32** [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK: for.end: +// CHECK-NEXT: ret void +// void fru(int (&&e) [4]) { - // CHECK-LABEL: define{{.*}}fru - // CHECK: br {{.*}} !prof !10 for(int i : e) [[unlikely]]; } - -// CHECK: !6 = !{!"branch_weights", i32 2000, i32 1} -// CHECK: !10 = !{!"branch_weights", i32 1, i32 2000} diff --git a/clang/test/CodeGenCXX/attr-likelihood-switch-branch-weights.cpp b/clang/test/CodeGenCXX/attr-likelihood-switch-branch-weights.cpp index 5fb7a67a7d9e..05729eb5a789 100644 --- a/clang/test/CodeGenCXX/attr-likelihood-switch-branch-weights.cpp +++ b/clang/test/CodeGenCXX/attr-likelihood-switch-branch-weights.cpp @@ -1,59 +1,111 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s extern volatile int i; +// CHECK-LABEL: @_Z8OneCaseLv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG]] +// CHECK-NEXT: ], !prof !6 +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void OneCaseL() { - // CHECK-LABEL: define{{.*}}OneCaseL - // CHECK: switch - // CHECK: {{.*}} !prof !6 switch (i) { [[likely]] case 1: break; } } +// CHECK-LABEL: @_Z8OneCaseUv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_BB:%.*]] +// CHECK-NEXT: ], !prof !7 +// CHECK: sw.bb: +// CHECK-NEXT: [[TMP1:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// CHECK-NEXT: store volatile i32 [[INC]], i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void OneCaseU() { - // CHECK-LABEL: define{{.*}}OneCaseU - // CHECK: switch - // CHECK: {{.*}} !prof !7 switch (i) { [[unlikely]] case 1: ++i; break; } } +// CHECK-LABEL: @_Z10TwoCasesLNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG]] +// CHECK-NEXT: i32 2, label [[SW_EPILOG]] +// CHECK-NEXT: ], !prof !8 +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void TwoCasesLN() { - // CHECK-LABEL: define{{.*}}TwoCasesLN - // CHECK: switch - // CHECK: {{.*}} !prof !8 switch (i) { [[likely]] case 1: break; case 2: break; } } +// CHECK-LABEL: @_Z10TwoCasesUNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG]] +// CHECK-NEXT: i32 2, label [[SW_EPILOG]] +// CHECK-NEXT: ], !prof !9 +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void TwoCasesUN() { - // CHECK-LABEL: define{{.*}}TwoCasesUN - // CHECK: switch - // CHECK: {{.*}} !prof !9 switch (i) { [[unlikely]] case 1: break; case 2: break; } } +// CHECK-LABEL: @_Z10TwoCasesLUv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG]] +// CHECK-NEXT: i32 2, label [[SW_EPILOG]] +// CHECK-NEXT: ], !prof !10 +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void TwoCasesLU() { - // CHECK-LABEL: define{{.*}}TwoCasesLU - // CHECK: switch - // CHECK: {{.*}} !prof !10 switch (i) { [[likely]] case 1: break; [[unlikely]] case 2: break; } } +// CHECK-LABEL: @_Z20CasesFallthroughNNLNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_BB:%.*]] +// CHECK-NEXT: i32 2, label [[SW_BB]] +// CHECK-NEXT: i32 3, label [[SW_BB1:%.*]] +// CHECK-NEXT: i32 4, label [[SW_BB1]] +// CHECK-NEXT: ], !prof !11 +// CHECK: sw.bb: +// CHECK-NEXT: br label [[SW_BB1]] +// CHECK: sw.bb1: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void CasesFallthroughNNLN() { - // CHECK-LABEL: define{{.*}}CasesFallthroughNNLN - // CHECK: switch - // CHECK: {{.*}} !prof !11 switch (i) { case 1: case 2: @@ -62,10 +114,23 @@ void CasesFallthroughNNLN() { } } +// CHECK-LABEL: @_Z20CasesFallthroughNNUNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_BB:%.*]] +// CHECK-NEXT: i32 2, label [[SW_BB]] +// CHECK-NEXT: i32 3, label [[SW_BB1:%.*]] +// CHECK-NEXT: i32 4, label [[SW_BB1]] +// CHECK-NEXT: ], !prof !12 +// CHECK: sw.bb: +// CHECK-NEXT: br label [[SW_BB1]] +// CHECK: sw.bb1: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void CasesFallthroughNNUN() { - // CHECK-LABEL: define{{.*}}CasesFallthroughNNUN - // CHECK: switch - // CHECK: {{.*}} !prof !12 switch (i) { case 1: case 2: @@ -74,10 +139,32 @@ void CasesFallthroughNNUN() { } } +// CHECK-LABEL: @_Z28CasesFallthroughRangeSmallLNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_BB:%.*]] +// CHECK-NEXT: i32 2, label [[SW_BB]] +// CHECK-NEXT: i32 3, label [[SW_BB]] +// CHECK-NEXT: i32 4, label [[SW_BB]] +// CHECK-NEXT: i32 5, label [[SW_BB]] +// CHECK-NEXT: i32 102, label [[SW_BB1:%.*]] +// CHECK-NEXT: i32 103, label [[SW_BB2:%.*]] +// CHECK-NEXT: i32 104, label [[SW_BB2]] +// CHECK-NEXT: ], !prof !13 +// CHECK: sw.bb: +// CHECK-NEXT: [[TMP1:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// CHECK-NEXT: store volatile i32 [[INC]], i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[SW_BB1]] +// CHECK: sw.bb1: +// CHECK-NEXT: br label [[SW_BB2]] +// CHECK: sw.bb2: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void CasesFallthroughRangeSmallLN() { - // CHECK-LABEL: define{{.*}}CasesFallthroughRangeSmallLN - // CHECK: switch - // CHECK: {{.*}} !prof !13 switch (i) { case 1 ... 5: ++i; case 102: @@ -86,10 +173,32 @@ void CasesFallthroughRangeSmallLN() { } } +// CHECK-LABEL: @_Z28CasesFallthroughRangeSmallUNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_EPILOG:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_BB:%.*]] +// CHECK-NEXT: i32 2, label [[SW_BB]] +// CHECK-NEXT: i32 3, label [[SW_BB]] +// CHECK-NEXT: i32 4, label [[SW_BB]] +// CHECK-NEXT: i32 5, label [[SW_BB]] +// CHECK-NEXT: i32 102, label [[SW_BB1:%.*]] +// CHECK-NEXT: i32 103, label [[SW_BB2:%.*]] +// CHECK-NEXT: i32 104, label [[SW_BB2]] +// CHECK-NEXT: ], !prof !14 +// CHECK: sw.bb: +// CHECK-NEXT: [[TMP1:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// CHECK-NEXT: store volatile i32 [[INC]], i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: br label [[SW_BB1]] +// CHECK: sw.bb1: +// CHECK-NEXT: br label [[SW_BB2]] +// CHECK: sw.bb2: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void CasesFallthroughRangeSmallUN() { - // CHECK-LABEL: define{{.*}}CasesFallthroughRangeSmallUN - // CHECK: switch - // CHECK: {{.*}} !prof !14 switch (i) { case 1 ... 5: ++i; case 102: @@ -98,12 +207,26 @@ void CasesFallthroughRangeSmallUN() { } } +// CHECK-LABEL: @_Z29CasesFallthroughRangeLargeLLNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_CASERANGE:%.*]] [ +// CHECK-NEXT: i32 1003, label [[SW_BB1:%.*]] +// CHECK-NEXT: i32 104, label [[SW_BB1]] +// CHECK-NEXT: ], !prof !8 +// CHECK: sw.bb: +// CHECK-NEXT: br label [[SW_BB1]] +// CHECK: sw.bb1: +// CHECK-NEXT: br label [[SW_EPILOG:%.*]] +// CHECK: sw.caserange: +// CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], 0 +// CHECK-NEXT: [[INBOUNDS:%.*]] = icmp ule i32 [[TMP1]], 64 +// CHECK-NEXT: [[INBOUNDS_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[INBOUNDS]], i1 true) +// CHECK-NEXT: br i1 [[INBOUNDS_EXPVAL]], label [[SW_BB:%.*]], label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void CasesFallthroughRangeLargeLLN() { - // CHECK-LABEL: define{{.*}}CasesFallthroughRangeLargeLLN - // CHECK: switch - // CHECK: {{.*}} !prof !8 - // CHECK: caserange - // CHECK: br{{.*}} !prof !15 switch (i) { [[likely]] case 0 ... 64: [[likely]] case 1003: @@ -111,12 +234,26 @@ void CasesFallthroughRangeLargeLLN() { } } +// CHECK-LABEL: @_Z29CasesFallthroughRangeLargeUUNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_CASERANGE:%.*]] [ +// CHECK-NEXT: i32 1003, label [[SW_BB1:%.*]] +// CHECK-NEXT: i32 104, label [[SW_BB1]] +// CHECK-NEXT: ], !prof !9 +// CHECK: sw.bb: +// CHECK-NEXT: br label [[SW_BB1]] +// CHECK: sw.bb1: +// CHECK-NEXT: br label [[SW_EPILOG:%.*]] +// CHECK: sw.caserange: +// CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], 0 +// CHECK-NEXT: [[INBOUNDS:%.*]] = icmp ule i32 [[TMP1]], 64 +// CHECK-NEXT: [[INBOUNDS_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[INBOUNDS]], i1 false) +// CHECK-NEXT: br i1 [[INBOUNDS_EXPVAL]], label [[SW_BB:%.*]], label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void CasesFallthroughRangeLargeUUN() { - // CHECK-LABEL: define{{.*}}CasesFallthroughRangeLargeUUN - // CHECK: switch - // CHECK: {{.*}} !prof !9 - // CHECK: caserange - // CHECK: br{{.*}} !prof !16 switch (i) { [[unlikely]] case 0 ... 64: [[unlikely]] case 1003: @@ -124,30 +261,55 @@ void CasesFallthroughRangeLargeUUN() { } } +// CHECK-LABEL: @_Z15OneCaseDefaultLv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_DEFAULT:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG:%.*]] +// CHECK-NEXT: ], !prof !15 +// CHECK: sw.default: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void OneCaseDefaultL() { - // CHECK-LABEL: define{{.*}}OneCaseDefaultL - // CHECK: switch - // CHECK: {{.*}} !prof !17 switch (i) { case 1: break; [[likely]] default: break; } } +// CHECK-LABEL: @_Z15OneCaseDefaultUv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_DEFAULT:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG:%.*]] +// CHECK-NEXT: ], !prof !16 +// CHECK: sw.default: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void OneCaseDefaultU() { - // CHECK-LABEL: define{{.*}}OneCaseDefaultU - // CHECK: switch - // CHECK: {{.*}} !prof !18 switch (i) { case 1: break; [[unlikely]] default: break; } } +// CHECK-LABEL: @_Z18TwoCasesDefaultLNLv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_DEFAULT:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG:%.*]] +// CHECK-NEXT: i32 2, label [[SW_EPILOG]] +// CHECK-NEXT: ], !prof !17 +// CHECK: sw.default: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void TwoCasesDefaultLNL() { - // CHECK-LABEL: define{{.*}}TwoCasesDefaultLNL - // CHECK: switch - // CHECK: {{.*}} !prof !19 switch (i) { [[likely]] case 1: break; case 2: break; @@ -155,10 +317,19 @@ void TwoCasesDefaultLNL() { } } +// CHECK-LABEL: @_Z18TwoCasesDefaultLNNv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_DEFAULT:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG:%.*]] +// CHECK-NEXT: i32 2, label [[SW_EPILOG]] +// CHECK-NEXT: ], !prof !8 +// CHECK: sw.default: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void TwoCasesDefaultLNN() { - // CHECK-LABEL: define{{.*}}TwoCasesDefaultLNN - // CHECK: switch - // CHECK: {{.*}} !prof !8 switch (i) { [[likely]] case 1: break; case 2: break; @@ -166,29 +337,22 @@ void TwoCasesDefaultLNN() { } } +// CHECK-LABEL: @_Z18TwoCasesDefaultLNUv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, i32* @i, align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: switch i32 [[TMP0]], label [[SW_DEFAULT:%.*]] [ +// CHECK-NEXT: i32 1, label [[SW_EPILOG:%.*]] +// CHECK-NEXT: i32 2, label [[SW_EPILOG]] +// CHECK-NEXT: ], !prof !18 +// CHECK: sw.default: +// CHECK-NEXT: br label [[SW_EPILOG]] +// CHECK: sw.epilog: +// CHECK-NEXT: ret void +// void TwoCasesDefaultLNU() { - // CHECK-LABEL: define{{.*}}TwoCasesDefaultLNU - // CHECK: switch - // CHECK: {{.*}} !prof !20 switch (i) { [[likely]] case 1: break; case 2: break; [[unlikely]] default: break; } } - -// CHECK: !6 = !{!"branch_weights", i32 357913942, i32 715827883} -// CHECK: !7 = !{!"branch_weights", i32 536870912, i32 1} -// CHECK: !8 = !{!"branch_weights", i32 238609295, i32 715827883, i32 238609295} -// CHECK: !9 = !{!"branch_weights", i32 357913942, i32 1, i32 357913942} -// CHECK: !10 = !{!"branch_weights", i32 357913942, i32 715827883, i32 1} -// CHECK: !11 = !{!"branch_weights", i32 143165577, i32 143165577, i32 143165577, i32 715827883, i32 143165577} -// CHECK: !12 = !{!"branch_weights", i32 214748365, i32 214748365, i32 214748365, i32 1, i32 214748365} -// CHECK: !13 = !{!"branch_weights", i32 79536432, i32 79536432, i32 79536432, i32 79536432, i32 79536432, i32 79536432, i32 79536432, i32 715827883, i32 79536432} -// CHECK: !14 = !{!"branch_weights", i32 119304648, i32 119304648, i32 119304648, i32 119304648, i32 119304648, i32 119304648, i32 119304648, i32 1, i32 119304648} -// CHECK: !15 = !{!"branch_weights", i32 2000, i32 1} -// CHECK: !16 = !{!"branch_weights", i32 1, i32 2000} -// CHECK: !17 = !{!"branch_weights", i32 715827883, i32 357913942} -// CHECK: !18 = !{!"branch_weights", i32 1, i32 536870912} -// CHECK: !19 = !{!"branch_weights", i32 536870912, i32 536870912, i32 268435456} -// CHECK: !20 = !{!"branch_weights", i32 1, i32 715827883, i32 357913942} diff --git a/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp b/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp index a611587b56f7..be9fc941c480 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp @@ -16,20 +16,20 @@ void usage() { bar(f); } -// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* inalloca %0) +// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %0) // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] // WINDOWS: ret i32 %[[LOAD]] -// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* inalloca %0) +// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %0) // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] // WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1 // WINDOWS: ret i32 %[[ADD]] -// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* inalloca %0) +// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %0) // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] @@ -39,7 +39,7 @@ void usage() { // WINDOWS: define dso_local void @"?usage@@YAXXZ"() // WINDOWS: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo // WINDOWS: %[[ARGMEM:[0-9a-zA-Z]+]] = alloca inalloca <{ %struct.Foo }> -// WINDOWS: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* inalloca %[[ARGMEM]]) +// WINDOWS: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %[[ARGMEM]]) // WINDOWS: define weak_odr dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* %0) // WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* %0) diff --git a/clang/test/CodeGenCXX/bitfield-layout.cpp b/clang/test/CodeGenCXX/bitfield-layout.cpp index 79dbf9c691c4..d570b8f33e34 100644 --- a/clang/test/CodeGenCXX/bitfield-layout.cpp +++ b/clang/test/CodeGenCXX/bitfield-layout.cpp @@ -93,7 +93,7 @@ int test_trunc_int() { } const U = {15}; // 0b00001111 return U.i; } -// CHECK: define dso_local i32 @test_trunc_int() +// CHECK: define{{.*}} i32 @test_trunc_int() // CHECK: ret i32 -1 int test_trunc_three_bits() { @@ -102,7 +102,7 @@ int test_trunc_three_bits() { } const U = {15}; // 0b00001111 return U.i; } -// CHECK: define dso_local i32 @test_trunc_three_bits() +// CHECK: define{{.*}} i32 @test_trunc_three_bits() // CHECK: ret i32 -1 int test_trunc_1() { @@ -111,7 +111,7 @@ int test_trunc_1() { } const U = {15}; // 0b00001111 return U.i; } -// CHECK: define dso_local i32 @test_trunc_1() +// CHECK: define{{.*}} i32 @test_trunc_1() // CHECK: ret i32 -1 int test_trunc_zero() { @@ -120,7 +120,7 @@ int test_trunc_zero() { } const U = {80}; // 0b01010000 return U.i; } -// CHECK: define dso_local i32 @test_trunc_zero() +// CHECK: define{{.*}} i32 @test_trunc_zero() // CHECK: ret i32 0 int test_constexpr() { @@ -129,7 +129,7 @@ int test_constexpr() { } const U = {1 + 2 + 4 + 8}; // 0b00001111 return U.i; } -// CHECK: define dso_local i32 @test_constexpr() +// CHECK: define{{.*}} i32 @test_constexpr() // CHECK: ret i32 -1 int test_notrunc() { @@ -138,7 +138,7 @@ int test_notrunc() { } const U = {1 + 2 + 4 + 8}; // 0b00001111 return U.i; } -// CHECK: define dso_local i32 @test_notrunc() +// CHECK: define{{.*}} i32 @test_notrunc() // CHECK: ret i32 15 long long test_trunc_long_long() { @@ -147,6 +147,6 @@ long long test_trunc_long_long() { } const U = {0b0100111101001101}; return U.i; } -// CHECK: define dso_local i64 @test_trunc_long_long() +// CHECK: define{{.*}} i64 @test_trunc_long_long() // CHECK: ret i64 3917 } diff --git a/clang/test/CodeGenCXX/const-init.cpp b/clang/test/CodeGenCXX/const-init.cpp index 5b305bc5e4d6..f5c9dae7ba4b 100644 --- a/clang/test/CodeGenCXX/const-init.cpp +++ b/clang/test/CodeGenCXX/const-init.cpp @@ -2,17 +2,17 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -std=c++98 -o - %s | FileCheck %s // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -std=c++11 -o - %s | FileCheck %s -// CHECK: @a = dso_local global i32 10 +// CHECK: @a = global i32 10 int a = 10; -// CHECK: @ar = dso_local constant i32* @a +// CHECK: @ar = constant i32* @a int &ar = a; void f(); -// CHECK: @fr = dso_local constant void ()* @_Z1fv +// CHECK: @fr = constant void ()* @_Z1fv void (&fr)() = f; struct S { int& a; }; -// CHECK: @s = dso_local global %struct.S { i32* @a } +// CHECK: @s = global %struct.S { i32* @a } S s = { a }; // PR5581 @@ -23,7 +23,7 @@ class C { unsigned f; }; -// CHECK: @_ZN6PR55812g0E = dso_local global %"class.PR5581::C" { i32 1 } +// CHECK: @_ZN6PR55812g0E = global %"class.PR5581::C" { i32 1 } C g0 = { C::e1 }; } @@ -39,10 +39,10 @@ namespace test2 { static int g(); } a; - // CHECK: @_ZN5test22t0E = dso_local global double {{1\.0+e\+0+}}, align 8 - // CHECK: @_ZN5test22t1E = dso_local global [2 x double] [double {{1\.0+e\+0+}}, double {{5\.0+e-0*}}1], align 16 - // CHECK: @_ZN5test22t2E = dso_local global double* @_ZN5test21A1d - // CHECK: @_ZN5test22t3E = dso_local global {{.*}} @_ZN5test21A1g + // CHECK: @_ZN5test22t0E = global double {{1\.0+e\+0+}}, align 8 + // CHECK: @_ZN5test22t1E = global [2 x double] [double {{1\.0+e\+0+}}, double {{5\.0+e-0*}}1], align 16 + // CHECK: @_ZN5test22t2E = global double* @_ZN5test21A1d + // CHECK: @_ZN5test22t3E = global {{.*}} @_ZN5test21A1g double t0 = A::d; double t1[] = { A::d, A::f }; const double *t2 = &a.d; @@ -50,7 +50,7 @@ namespace test2 { } // We don't expect to fold this in the frontend, but make sure it doesn't crash. -// CHECK: @PR9558 = dso_local global float 0.000000e+0 +// CHECK: @PR9558 = global float 0.000000e+0 float PR9558 = reinterpret_cast("asd"); // An initialized const automatic variable cannot be promoted to a constant @@ -66,7 +66,7 @@ int writeToMutable() { // Make sure we don't try to fold this in the frontend; the backend can't // handle it. -// CHECK: @PR11705 = dso_local global i128 0 +// CHECK: @PR11705 = global i128 0 __int128_t PR11705 = (__int128_t)&PR11705; // Make sure we don't try to fold this either. @@ -77,11 +77,11 @@ void UnfoldableAddrLabelDiff() { static __int128_t x = (long)&&a-(long)&&b; a:b: // CHECK: @_ZZ21FoldableAddrLabelDiffvE1x = internal global i64 sub (i64 ptrtoint (i8* blockaddress(@_Z21FoldableAddrLabelDiffv void FoldableAddrLabelDiff() { static long x = (long)&&a-(long)&&b; a:b:return;} -// CHECK: @i = dso_local constant i32* bitcast (float* @PR9558 to i32*) +// CHECK: @i = constant i32* bitcast (float* @PR9558 to i32*) int &i = reinterpret_cast(PR9558); int arr[2]; -// CHECK: @pastEnd = dso_local constant i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) +// CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) int &pastEnd = arr[2]; struct X { diff --git a/clang/test/CodeGenCXX/default_calling_conv.cpp b/clang/test/CodeGenCXX/default_calling_conv.cpp index e3d7ac429a60..83d1200e0ab1 100644 --- a/clang/test/CodeGenCXX/default_calling_conv.cpp +++ b/clang/test/CodeGenCXX/default_calling_conv.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL +// RUN: %clang_cc1 -triple i686-pc-win32 -fdefault-calling-conv=vectorcall -emit-llvm -o - %s -DWINDOWS | FileCheck %s --check-prefix=WIN32 +// RUN: %clang_cc1 -triple x86_64-windows-msvc -fdefault-calling-conv=vectorcall -emit-llvm -o - %s -DWINDOWS | FileCheck %s --check-prefix=WIN64 +// RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm -o - %s -DEXPLICITCC | FileCheck %s --check-prefix=EXPLICITCC // CDECL: define{{.*}} void @_Z5test1v // FASTCALL: define{{.*}} x86_fastcallcc void @_Z5test1v @@ -50,3 +53,45 @@ void test() { int main() { return 1; } + +#ifdef WINDOWS +// WIN32: define dso_local i32 @wmain +// WIN64: define dso_local i32 @wmain +int wmain() { + return 1; +} +// WIN32: define dso_local x86_stdcallcc i32 @WinMain +// WIN64: define dso_local i32 @WinMain +int WinMain() { + return 1; +} +// WIN32: define dso_local x86_stdcallcc i32 @wWinMain +// WIN64: define dso_local i32 @wWinMain +int wWinMain() { + return 1; +} +// WIN32: define dso_local x86_stdcallcc i32 @DllMain +// WIN64: define dso_local i32 @DllMain +int DllMain() { + return 1; +} +#endif // Windows + +#ifdef EXPLICITCC +// EXPLICITCC: define dso_local x86_fastcallcc i32 @wmain +int __fastcall wmain() { + return 1; +} +// EXPLICITCC: define dso_local x86_fastcallcc i32 @WinMain +int __fastcall WinMain() { + return 1; +} +// EXPLICITCC: define dso_local x86_fastcallcc i32 @wWinMain +int __fastcall wWinMain() { + return 1; +} +// EXPLICITCC: define dso_local x86_fastcallcc i32 @DllMain +int __fastcall DllMain() { + return 1; +} +#endif // ExplicitCC diff --git a/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp index f6cca8eda9d9..6b5c27097cbd 100644 --- a/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp +++ b/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp @@ -123,3 +123,25 @@ void test_lambda() { // CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]] // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]] // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]], i32 %[[l2]]) + +struct U { + void this_in_lambda(); +}; + +void U::this_in_lambda() { + auto lambda = [=]() { + __try { + might_crash(); + } __except (basic_filter(0, this)) { + } + }; + lambda(); +} + +// CHECK-LABEL: define internal i32 @"?filt$0@0@?R@?0??this_in_lambda@U@@QEAAXXZ@"(i8* %exception_pointers, i8* %frame_pointer) +// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon.0*)* @"??R@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ" to i8*), i8* %[[fp:[^ ]*]], i32 0) +// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0** +// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** %[[this_ptr]], align 8 +// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, %class.anon.0* %[[this]], i32 0, i32 0 +// CHECK: %[[actual_this:[^ ]*]] = load %struct.U*, %struct.U** %[[actual_this_ptr]], align 8 +// CHECK: call i32 (i32, ...) @basic_filter(i32 0, %struct.U* %[[actual_this]]) diff --git a/clang/test/CodeGenCXX/for-cond-var.cpp b/clang/test/CodeGenCXX/for-cond-var.cpp new file mode 100644 index 000000000000..60e54d4141f7 --- /dev/null +++ b/clang/test/CodeGenCXX/for-cond-var.cpp @@ -0,0 +1,138 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s -triple x86_64-linux | FileCheck %s + +struct A { + A(); + A(const A &); + ~A(); + operator bool(); + void *data; +}; + +A make(); +bool cond(); +void f(int); + +// PR49585: Ensure that 'continue' performs the proper cleanups in the presence +// of a for loop condition variable. +// +// CHECK: define {{.*}} void @_Z7PR49585v( +void PR49585() { + for ( + // CHECK: call void @_Z1fi(i32 1) + // CHECK: br label %[[for_cond:.*]] + f(1); + + // CHECK: [[for_cond]]: + // CHECK: call {{.*}} @_Z4makev( + // CHECK: call {{.*}} @_ZN1AcvbEv( + // CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_cond_cleanup:.*]] + A a = make(); + + // CHECK: [[for_cond_cleanup]]: + // CHECK: store + // CHECK: br label %[[cleanup:.*]] + + f(2)) { + // CHECK: [[for_body]]: + // CHECK: call {{.*}} @_Z4condv( + // CHECK: br i1 {{.*}}, label %[[if_then:.*]], label %[[if_end:.*]] + if (cond()) { + // CHECK: [[if_then]]: + // CHECK: call {{.*}} @_Z1fi(i32 3) + // CHECK: br label %[[for_inc:.*]] + f(3); + continue; + } + + // CHECK: [[if_end]]: + // CHECK: call {{.*}} @_Z1fi(i32 4) + // CHECK: br label %[[for_inc]] + f(4); + } + + // CHECK: [[for_inc]]: + // CHECK: call void @_Z1fi(i32 2) + // CHECK: store + // CHECK: br label %[[cleanup]] + + // CHECK: [[cleanup]]: + // CHECK: call void @_ZN1AD1Ev( + // CHECK: load + // CHECK: switch {{.*}} label + // CHECK-NEXT: label %[[cleanup_cont:.*]] + // CHECK-NEXT: label %[[for_end:.*]] + + // CHECK: [[cleanup_cont]]: + // CHECK: br label %[[for_cond]] + + // CHECK [[for_end]]: + // CHECK: ret void +} + +// CHECK: define {{.*}} void @_Z13PR49585_breakv( +void PR49585_break() { + for ( + // CHECK: call void @_Z1fi(i32 1) + // CHECK: br label %[[for_cond:.*]] + f(1); + + // CHECK: [[for_cond]]: + // CHECK: call {{.*}} @_Z4makev( + // CHECK: call {{.*}} @_ZN1AcvbEv( + // CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_cond_cleanup:.*]] + A a = make(); + + // CHECK: [[for_cond_cleanup]]: + // CHECK: store + // CHECK: br label %[[cleanup:.*]] + + f(2)) { + // CHECK: [[for_body]]: + // CHECK: call {{.*}} @_Z4condv( + // CHECK: br i1 {{.*}}, label %[[if_then:.*]], label %[[if_end:.*]] + if (cond()) { + // CHECK: [[if_then]]: + // CHECK: call {{.*}} @_Z1fi(i32 3) + // CHECK: store + // CHECK: br label %[[cleanup:.*]] + f(3); + break; + } + + // CHECK: [[if_end]]: + // CHECK: call {{.*}} @_Z1fi(i32 4) + // CHECK: br label %[[for_inc]] + f(4); + } + + // CHECK: [[for_inc]]: + // CHECK: call void @_Z1fi(i32 2) + // CHECK: store + // CHECK: br label %[[cleanup]] + + // CHECK: [[cleanup]]: + // CHECK: call void @_ZN1AD1Ev( + // CHECK: load + // CHECK: switch {{.*}} label + // CHECK-NEXT: label %[[cleanup_cont:.*]] + // CHECK-NEXT: label %[[for_end:.*]] + + // CHECK: [[cleanup_cont]]: + // CHECK: br label %[[for_cond]] + + // CHECK [[for_end]]: + // CHECK: ret void +} + +// CHECK: define {{.*}} void @_Z16incless_for_loopv( +void incless_for_loop() { + // CHECK: br label %[[for_cond:.*]] + // CHECK: [[for_cond]]: + // CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_end:.*]] + // CHECK: [[for_body]]: + // CHECK: br label %[[for_cond]] + // CHECK: [[for_end]]: + // CHECK: ret void + // CHECK: } + for (; int b = 0;) continue; +} diff --git a/clang/test/CodeGenCXX/inalloca-overaligned.cpp b/clang/test/CodeGenCXX/inalloca-overaligned.cpp index 48a6183db8eb..0a51875bb592 100644 --- a/clang/test/CodeGenCXX/inalloca-overaligned.cpp +++ b/clang/test/CodeGenCXX/inalloca-overaligned.cpp @@ -28,7 +28,7 @@ int receive_inalloca_overaligned(NonTrivial nt, OverAligned o) { } // CHECK-LABEL: define dso_local i32 @"?receive_inalloca_overaligned@@Y{{.*}}" -// CHECK-SAME: (<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %0) +// CHECK-SAME: (<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca(<{ %struct.NonTrivial, %struct.OverAligned* }>) %0) int pass_inalloca_overaligned() { gvi32 = receive_inalloca_overaligned(NonTrivial(), OverAligned()); @@ -50,7 +50,7 @@ int pass_inalloca_overaligned() { // Store the address of an OverAligned temporary into the struct. // CHECK: getelementptr inbounds <{ %struct.NonTrivial, %struct.OverAligned* }>, <{ %struct.NonTrivial, %struct.OverAligned* }>* %{{.*}}, i32 0, i32 1 // CHECK: store %struct.OverAligned* [[TMP]], %struct.OverAligned** %{{.*}}, align 4 -// CHECK: call i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %argmem) +// CHECK: call i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca(<{ %struct.NonTrivial, %struct.OverAligned* }>) %argmem) int receive_both(Both o) { return o.x + o.y; @@ -74,7 +74,7 @@ int receive_inalloca_both(NonTrivial nt, Both o) { } // CHECK-LABEL: define dso_local i32 @"?receive_inalloca_both@@Y{{.*}}" -// CHECK-SAME: (<{ %struct.NonTrivial, %struct.Both* }>* inalloca %0) +// CHECK-SAME: (<{ %struct.NonTrivial, %struct.Both* }>* inalloca(<{ %struct.NonTrivial, %struct.Both* }>) %0) int pass_inalloca_both() { gvi32 = receive_inalloca_both(NonTrivial(), Both()); @@ -84,7 +84,7 @@ int pass_inalloca_both() { // CHECK-LABEL: define dso_local i32 @"?pass_inalloca_both@@Y{{.*}}" // CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 8 // CHECK: call x86_thiscallcc %struct.Both* @"??0Both@@QAE@XZ"(%struct.Both* {{[^,]*}} [[TMP]]) -// CHECK: call i32 @"?receive_inalloca_both@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.Both* }>* inalloca %argmem) +// CHECK: call i32 @"?receive_inalloca_both@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.Both* }>* inalloca(<{ %struct.NonTrivial, %struct.Both* }>) %argmem) // Here we have a type that is: // - overaligned diff --git a/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp b/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp index e7ae2cb4e703..090953ae3b1d 100644 --- a/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp +++ b/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp @@ -46,6 +46,6 @@ out:; // CHECK: call zeroext i1 @"?cond@@YA_NXZ"() // CHECK: br i1 // CHECK: br label %out -// CHECK: call void @"?inalloca@@YAXUFoo@@0@Z"(<{ %struct.Foo, %struct.Foo }>* inalloca %{{.*}}) +// CHECK: call void @"?inalloca@@YAXUFoo@@0@Z"(<{ %struct.Foo, %struct.Foo }>* inalloca(<{ %struct.Foo, %struct.Foo }>) %{{.*}}) // CHECK: call void @llvm.stackrestore(i8* %inalloca.save) // CHECK: out: diff --git a/clang/test/CodeGenCXX/inalloca-vector.cpp b/clang/test/CodeGenCXX/inalloca-vector.cpp index bf71fac37b6a..e052d2e6728d 100644 --- a/clang/test/CodeGenCXX/inalloca-vector.cpp +++ b/clang/test/CodeGenCXX/inalloca-vector.cpp @@ -21,7 +21,7 @@ void receive_vec_128(NonTrivial nt, __m128 x, __m128 y, __m128 z, __m128 w, __m1 // CHECK-SAME: (<4 x float> inreg %x, // CHECK-SAME: <4 x float> inreg %y, // CHECK-SAME: <4 x float> inreg %z, -// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca %0) +// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca(<{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>) %0) void pass_vec_128() { __m128 z = {0}; @@ -45,7 +45,7 @@ void pass_vec_128() { // CHECK-SAME: (<4 x float> inreg %{{[^,]*}}, // CHECK-SAME: <4 x float> inreg %{{[^,]*}}, // CHECK-SAME: <4 x float> inreg %{{[^,]*}}, -// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca %{{[^,]*}}) +// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca(<{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>) %{{[^,]*}}) // w will be passed indirectly by register, and q will be passed indirectly, but // the pointer will be in memory. @@ -58,7 +58,7 @@ void __fastcall fastcall_receive_vec(__m128 x, __m128 y, __m128 z, __m128 w, int // CHECK-SAME: <4 x float> inreg %z, // CHECK-SAME: <4 x float>* inreg %0, // CHECK-SAME: i32 inreg %edx, -// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca %1) +// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca(<{ <4 x float>*, %struct.NonTrivial }>) %1) void __vectorcall vectorcall_receive_vec(double xmm0, double xmm1, double xmm2, @@ -75,4 +75,4 @@ void __vectorcall vectorcall_receive_vec(double xmm0, double xmm1, double xmm2, // CHECK-SAME: <4 x float> inreg %z, // CHECK-SAME: <4 x float>* inreg %0, // CHECK-SAME: i32 inreg %edx, -// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca %1) +// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca(<{ <4 x float>*, %struct.NonTrivial }>) %1) diff --git a/clang/test/CodeGenCXX/inheriting-constructor.cpp b/clang/test/CodeGenCXX/inheriting-constructor.cpp index 6de8e92186dd..c338edcc76ae 100644 --- a/clang/test/CodeGenCXX/inheriting-constructor.cpp +++ b/clang/test/CodeGenCXX/inheriting-constructor.cpp @@ -134,7 +134,7 @@ namespace inalloca_nonvirt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( @@ -170,7 +170,7 @@ namespace inalloca_nonvirt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( @@ -216,7 +216,7 @@ namespace inalloca_virt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: br // @@ -266,7 +266,7 @@ namespace inalloca_virt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: br // diff --git a/clang/test/CodeGenCXX/linkage.cpp b/clang/test/CodeGenCXX/linkage.cpp index d6c45cefd378..69b426269ccd 100644 --- a/clang/test/CodeGenCXX/linkage.cpp +++ b/clang/test/CodeGenCXX/linkage.cpp @@ -226,5 +226,5 @@ namespace test18 { template class> struct A {}; struct B { template struct C; }; void f(A) {} - // CHECK-DAG: define dso_local void @_ZN6test181fENS_1AINS_1B1CEEE( + // CHECK-DAG: define void @_ZN6test181fENS_1AINS_1B1CEEE( } diff --git a/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp b/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp index 4da04a43ff61..215a39ec7d48 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp @@ -14,7 +14,7 @@ void foo(A a, A b, A c) { // Order of destruction should be left to right. // // X86-LABEL: define dso_local void @"?foo@@YAXUA@@00@Z" -// X86: ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca %0) +// X86: ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca([[argmem_ty]]) %0) // X86: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 0 // X86: %[[b:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 1 // X86: %[[c:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 2 @@ -47,7 +47,7 @@ void call_foo() { // X86: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@H@Z"(%struct.A* {{[^,]*}} %[[arg2]], i32 2) // X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // X86: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@H@Z"(%struct.A* {{[^,]*}} %[[arg1]], i32 1) -// X86: call void @"?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca %[[argmem]]) +// X86: call void @"?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %[[argmem]]) // X86: call void @llvm.stackrestore // X86: ret void // diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp index 7f8730080a09..adf3921f7115 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp @@ -19,7 +19,7 @@ A B::foo(A x) { } // CHECK-LABEL: define dso_local x86_thiscallcc %struct.A* @"?foo@B@@QAE?AUA@@U2@@Z" -// CHECK: (%struct.B* %this, <{ %struct.A*, %struct.A }>* inalloca %0) +// CHECK: (%struct.B* %this, <{ %struct.A*, %struct.A }>* inalloca(<{ %struct.A*, %struct.A }>) %0) // CHECK: getelementptr inbounds <{ %struct.A*, %struct.A }>, <{ %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 0 // CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* @@ -29,7 +29,7 @@ A B::bar(A x) { } // CHECK-LABEL: define dso_local %struct.A* @"?bar@B@@QAA?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %0) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %0) // CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 // CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* @@ -39,7 +39,7 @@ A B::baz(A x) { } // CHECK-LABEL: define dso_local x86_stdcallcc %struct.A* @"?baz@B@@QAG?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %0) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %0) // CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 // CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* @@ -49,7 +49,7 @@ A B::qux(A x) { } // CHECK-LABEL: define dso_local x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z" -// CHECK: (%struct.B* inreg %this, %struct.A* inreg noalias sret(%struct.A) align 4 %agg.result, <{ %struct.A }>* inalloca %0) +// CHECK: (%struct.B* inreg %this, %struct.A* inreg noalias sret(%struct.A) align 4 %agg.result, <{ %struct.A }>* inalloca(<{ %struct.A }>) %0) // CHECK: ret void int main() { @@ -61,10 +61,10 @@ int main() { } // CHECK: call x86_thiscallcc %struct.A* @"?foo@B@@QAE?AUA@@U2@@Z" -// CHECK: (%struct.B* %{{[^,]*}}, <{ %struct.A*, %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (%struct.B* %{{[^,]*}}, <{ %struct.A*, %struct.A }>* inalloca(<{ %struct.A*, %struct.A }>) %{{[^,]*}}) // CHECK: call %struct.A* @"?bar@B@@QAA?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %{{[^,]*}}) // CHECK: call x86_stdcallcc %struct.A* @"?baz@B@@QAG?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %{{[^,]*}}) // CHECK: call x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z" -// CHECK: (%struct.B* inreg %{{[^,]*}}, %struct.A* inreg sret(%struct.A) align 4 %{{.*}}, <{ %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (%struct.B* inreg %{{[^,]*}}, %struct.A* inreg sret(%struct.A) align 4 %{{.*}}, <{ %struct.A }>* inalloca(<{ %struct.A }>) %{{[^,]*}}) diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp index 917a7677c41e..65e789ce5c63 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp @@ -15,10 +15,10 @@ struct C : A, B { C(); virtual void foo(Agg x); }; C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?foo@C@byval_thunk@@W3AEXUAgg@2@@Z" -// CHECK32: (%"struct.byval_thunk::C"* %this, <{ %"struct.byval_thunk::Agg" }>* inalloca %0) +// CHECK32: (%"struct.byval_thunk::C"* %this, <{ %"struct.byval_thunk::Agg" }>* inalloca(<{ %"struct.byval_thunk::Agg" }>) %0) // CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: musttail call x86_thiscallcc void @"?foo@C@byval_thunk@@UAEXUAgg@2@@Z" -// CHECK32: (%"struct.byval_thunk::C"* %{{.*}}, <{ %"struct.byval_thunk::Agg" }>* inalloca %0) +// CHECK32: (%"struct.byval_thunk::C"* %{{.*}}, <{ %"struct.byval_thunk::Agg" }>* inalloca(<{ %"struct.byval_thunk::Agg" }>) %0) // CHECK32-NEXT: ret void // CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@byval_thunk@@W7EAAXUAgg@2@@Z" @@ -44,13 +44,13 @@ struct C : A, B { C(); virtual void __stdcall foo(Agg x); }; C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr dso_local x86_stdcallcc void @"?foo@C@stdcall_thunk@@W3AGXUAgg@2@@Z" -// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca(<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>) %0) // CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>, <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* %0, i32 0, i32 0 // CHECK32: load %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::C"** %[[this_slot]] // CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: store %"struct.stdcall_thunk::C"* %{{.*}}, %"struct.stdcall_thunk::C"** %[[this_slot]] // CHECK32: musttail call x86_stdcallcc void @"?foo@C@stdcall_thunk@@UAGXUAgg@2@@Z" -// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca(<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>) %0) // CHECK32-NEXT: ret void // CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@stdcall_thunk@@W7EAAXUAgg@2@@Z" @@ -76,13 +76,13 @@ struct C : A, B { C(); virtual Agg __cdecl foo(Agg x); }; C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr dso_local %"struct.sret_thunk::Agg"* @"?foo@C@sret_thunk@@W3AA?AUAgg@2@U32@@Z" -// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca(<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>) %0) // CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>, <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* %0, i32 0, i32 0 // CHECK32: load %"struct.sret_thunk::C"*, %"struct.sret_thunk::C"** %[[this_slot]] // CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: store %"struct.sret_thunk::C"* %{{.*}}, %"struct.sret_thunk::C"** %[[this_slot]] // CHECK32: %[[rv:[^ ]*]] = musttail call %"struct.sret_thunk::Agg"* @"?foo@C@sret_thunk@@UAA?AUAgg@2@U32@@Z" -// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca(<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>) %0) // CHECK32-NEXT: ret %"struct.sret_thunk::Agg"* %[[rv]] // CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@sret_thunk@@W7EAA?AUAgg@2@U32@@Z" diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp index 26f6814cc1d4..18333f36c239 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp @@ -19,14 +19,14 @@ int foo(A a, ...) { return sum; } -// CHECK-LABEL: define dso_local i32 @"?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca %0, ...) +// CHECK-LABEL: define dso_local i32 @"?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca(<{ %struct.A }>) %0, ...) int main() { return foo(A(3), 1, 2, 3); } // CHECK-LABEL: define dso_local i32 @main() // CHECK: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.A, i32, i32, i32 }> -// CHECK: call i32 {{.*bitcast.*}}@"?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca %[[argmem]]) +// CHECK: call i32 {{.*bitcast.*}}@"?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca(<{ %struct.A, i32, i32, i32 }>) %[[argmem]]) void varargs_zero(...); void varargs_one(int, ...); @@ -41,10 +41,10 @@ void call_var_args() { } // CHECK-LABEL: define dso_local void @"?call_var_args@@YAXXZ"() -// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca %{{.*}}) -// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca %{{.*}}) -// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca %{{.*}}) -// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca(<{ %struct.A }>) %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca(<{ i32, %struct.A }>) %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca(<{ i32, i32, %struct.A }>) %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca(<{ i32, i32, i32, %struct.A }>) %{{.*}}) // CHECK-LABEL: declare dso_local void @"?varargs_zero@@YAXZZ"(...) // CHECK-LABEL: declare dso_local void @"?varargs_one@@YAXHZZ"(i32, ...) diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp index 7e173668f26f..0b6b4385a352 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -54,7 +54,7 @@ int HasDeactivatedCleanups() { // WIN32: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ" // WIN32: store i1 false, i1* %[[isactive]] // -// WIN32: invoke i32 @"?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca %[[argmem]]) +// WIN32: invoke i32 @"?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %[[argmem]]) // Destroy the two const ref temporaries. // WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) // WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) diff --git a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp index e0e4ba9e41b5..b36ea9ccd9f0 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp @@ -76,7 +76,7 @@ struct SmallWithPrivate { // WIN32: declare dso_local void @"{{.*take_bools_and_chars.*}}" // WIN32: (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor, -// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca) +// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca(<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor, i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>) void take_bools_and_chars(char a, char b, SmallWithDtor c, char d, bool e, int f, bool g); void call_bools_and_chars() { take_bools_and_chars('A', 'B', SmallWithDtor(), 'D', true, 13, false); @@ -176,7 +176,7 @@ void packed_arg(Packed s) {} // Test that dtors are invoked in the callee. void small_arg_with_dtor(SmallWithDtor s) {} -// WIN32: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca %0) {{.*}} { +// WIN32: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca(<{ %struct.SmallWithDtor }>) %0) {{.*}} { // WIN32: call x86_thiscallcc void @"??1SmallWithDtor@@QAE@XZ" // WIN32: } // WIN64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %s.coerce) {{.*}} { @@ -253,13 +253,13 @@ void eh_cleanup_arg_with_dtor() { void small_arg_with_vftable(SmallWithVftable s) {} // LINUX-LABEL: define{{.*}} void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s) -// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca %0) +// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca(<{ %struct.SmallWithVftable }>) %0) // WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s) // WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s) void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {} // LINUX-LABEL: define{{.*}} void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s) -// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca %0) +// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca(<{ %struct.MediumWithCopyCtor }>) %0) // WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s) // WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s) // WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s) @@ -363,7 +363,7 @@ struct X { }; void g(X) { } -// WIN32: define dso_local void @"?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca %0) {{.*}} { +// WIN32: define dso_local void @"?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca(<{ %struct.X, [3 x i8] }>) %0) {{.*}} { // WIN32: call x86_thiscallcc void @"??1X@@QAE@XZ"(%struct.X* {{.*}}) // WIN32: } void f() { @@ -398,7 +398,7 @@ void bar() { // WIN32: call void @llvm.memcpy // WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // WIN32: call x86_thiscallcc %"struct.test2::NonTrivial"* @"??0NonTrivial@test2@@QAE@XZ" -// WIN32: call i32 @"?foo@test2@@YAHUNonTrivial@1@UPOD@1@@Z"([[argmem_ty]]* inalloca %argmem) +// WIN32: call i32 @"?foo@test2@@YAHUNonTrivial@1@UPOD@1@@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %argmem) // WIN32: ret void // WIN32: } @@ -414,7 +414,7 @@ struct NonTrivial { int a; }; void foo(NonTrivial a, bool b) { } -// WIN32-LABEL: define dso_local void @"?foo@test3@@YAXUNonTrivial@1@_N@Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca %0) +// WIN32-LABEL: define dso_local void @"?foo@test3@@YAXUNonTrivial@1@_N@Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>) %0) } @@ -440,7 +440,7 @@ void fn2(FnPtr1 a, SmallWithDtor b) { fn1(a, b); }; // WIN32: %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // WIN32: %[[addr:[^ ]*]] = bitcast {}** %[[gep2]] to void [[dst_ty]]* // WIN32: store void [[dst_ty]] %[[a2]], void [[dst_ty]]* %[[addr]], align 4 -// WIN32: call void @"?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca %[[argmem]]) +// WIN32: call void @"?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %[[argmem]]) namespace pr30293 { // Virtual methods living in a secondary vtable take i8* as their 'this' @@ -462,8 +462,8 @@ void C::g() { return h(SmallWithDtor()); } // WIN32-LABEL: define dso_local x86_thiscallcc void @"?g@C@pr30293@@QAEXXZ"(%"struct.pr30293::C"* {{[^,]*}} %this) // WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE@XZ" -// WIN32: call void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca %{{[^,)]*}}) -// WIN32: declare dso_local void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca) +// WIN32: call void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>) %{{[^,)]*}}) +// WIN32: declare dso_local void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>)) // WIN64-LABEL: define dso_local void @"?g@C@pr30293@@QEAAXXZ"(%"struct.pr30293::C"* {{[^,]*}} %this) // WIN64: declare dso_local void @"?h@C@pr30293@@UEAAXUSmallWithDtor@@@Z"(i8*, i32) diff --git a/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp b/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp index 6082228d36b6..e71d6238c53a 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp @@ -94,7 +94,7 @@ void f(C *c) { // CHECK-LABEL: define dso_local void @"?f@cdecl_inalloca@@YAXPAUC@1@@Z"(%"struct.cdecl_inalloca::C"* %c) // CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* {{[^,]*}} %{{.*}}) -// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}}) +// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>) %{{.*}}) // CHECK-LABEL: define linkonce_odr void @"??_9C@cdecl_inalloca@@$BA@AA"(%"struct.cdecl_inalloca::C"* %this, ...) {{.*}} comdat // CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...) %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...) diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp index 93a7d4602223..5cced42834e1 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp @@ -189,7 +189,7 @@ void C::g(NonTrivial o) { whatsthis = this; } -// BITCODE-LABEL: define dso_local void @"?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca %0) +// BITCODE-LABEL: define dso_local void @"?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca(<{ i8*, %"struct.pr30293::NonTrivial" }>) %0) // BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ i8*, %"struct.pr30293::NonTrivial" }>, <{ i8*, %"struct.pr30293::NonTrivial" }>* {{.*}}, i32 0, i32 0 // BITCODE: %[[thisaddr1:[^ ]*]] = bitcast i8** %[[thisaddr]] to %"struct.pr30293::C"** // BITCODE: %[[this1:[^ ]*]] = load %"struct.pr30293::C"*, %"struct.pr30293::C"** %[[thisaddr1]], align 4 diff --git a/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp index 256f7123ee51..b8ebe2dd9f39 100644 --- a/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp +++ b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp @@ -20,8 +20,8 @@ class C : A, B { }; C c; -// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca %0) +// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca(<{ %struct.NonTrivial }>) %0) // CHECK-NOT: invoke -// CHECK: musttail call x86_thiscallcc void @"?f@C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca %0) +// CHECK: musttail call x86_thiscallcc void @"?f@C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca(<{ %struct.NonTrivial }>) %0) // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenCXX/standalone-debug-attribute.cpp b/clang/test/CodeGenCXX/standalone-debug-attribute.cpp new file mode 100644 index 000000000000..a814e6f425ed --- /dev/null +++ b/clang/test/CodeGenCXX/standalone-debug-attribute.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -DSETATTR=0 -triple x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=constructor %s -o - | FileCheck %s --check-prefix=DEBUG +// RUN: %clang_cc1 -DSETATTR=1 -triple x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=constructor %s -o - | FileCheck %s --check-prefix=WITHATTR +// Use -debug-info-kind=constructor because it includes all the optimizations. + +#if SETATTR +#define STANDALONEDEBUGATTR __attribute__((standalone_debug)) +#else +#define STANDALONEDEBUGATTR +#endif + +struct STANDALONEDEBUGATTR StructWithConstructor { + StructWithConstructor() {} +}; +void f(StructWithConstructor s) {} +// DEBUG: !DICompositeType({{.*}}name: "StructWithConstructor" +// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl +// WITHATTR: !DICompositeType({{.*}}name: "StructWithConstructor" +// WITHATTR-NOT: DIFlagFwdDecl + +union STANDALONEDEBUGATTR UnionWithConstructor { + UnionWithConstructor() {} +}; +void f(UnionWithConstructor u) {} +// DEBUG: !DICompositeType({{.*}}name: "UnionWithConstructor" +// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl +// WITHATTR: !DICompositeType({{.*}}name: "UnionWithConstructor" +// WITHATTR-NOT: DIFlagFwdDecl + +template struct ExternTemplate { + ExternTemplate() {} + T x; +}; +extern template struct STANDALONEDEBUGATTR ExternTemplate; +void f(ExternTemplate s) {} +// DEBUG: !DICompositeType({{.*}}name: "ExternTemplate" +// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl +// WITHATTR: !DICompositeType({{.*}}name: "ExternTemplate" +// WITHATTR-NOT: DIFlagFwdDecl + +struct STANDALONEDEBUGATTR CompleteTypeRequired {}; +void f(CompleteTypeRequired &s) {} +// DEBUG: !DICompositeType({{.*}}name: "CompleteTypeRequired" +// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl +// WITHATTR: !DICompositeType({{.*}}name: "CompleteTypeRequired" +// WITHATTR-NOT: DIFlagFwdDecl + +struct STANDALONEDEBUGATTR Redecl; +struct Redecl {}; +void f(Redecl &s) {} +// DEBUG: !DICompositeType({{.*}}name: "Redecl" +// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl +// WITHATTR: !DICompositeType({{.*}}name: "Redecl" +// WITHATTR-NOT: DIFlagFwdDecl + diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp index 3ce350d03f48..b769411c9518 100644 --- a/clang/test/CodeGenCXX/temporaries.cpp +++ b/clang/test/CodeGenCXX/temporaries.cpp @@ -60,7 +60,7 @@ namespace RefTempSubobject { }; // CHECK: @_ZGRN16RefTempSubobject2srE_ = internal global { i32*, [3 x i32] } { {{.*}} getelementptr {{.*}} @_ZGRN16RefTempSubobject2srE_ {{.*}}, [3 x i32] [i32 1, i32 2, i32 3] } - // CHECK: @_ZN16RefTempSubobject2srE = {{.*}} constant {{.*}} @_ZGRN16RefTempSubobject2srE_ + // CHECK: @_ZN16RefTempSubobject2srE = constant {{.*}} @_ZGRN16RefTempSubobject2srE_ constexpr const SelfReferential &sr = SelfReferential(); } diff --git a/clang/test/CodeGenCXX/trivial_abi.cpp b/clang/test/CodeGenCXX/trivial_abi.cpp index ac41f5cac086..a4222c100311 100644 --- a/clang/test/CodeGenCXX/trivial_abi.cpp +++ b/clang/test/CodeGenCXX/trivial_abi.cpp @@ -262,3 +262,21 @@ void calleeExceptionLarge(Large, Large); void testExceptionLarge() { calleeExceptionLarge(Large(), Large()); } + +// PR42961 + +// CHECK: define{{.*}} @"_ZN3$_08__invokeEv"() +// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_SMALL]], align 8 +// CHECK: %[[COERCE:.*]] = alloca %[[STRUCT_SMALL]], align 8 +// CHECK: %[[CALL:.*]] = call{{.*}} @"_ZNK3$_0clEv" +// CHECK: %[[COERCEDIVE:.*]] = getelementptr{{.*}} %[[COERCE]] +// CHECK: %[[COERCEVALIP:.*]] = inttoptr{{.*}} %[[CALL]] +// CHECK: %[[RETVALP:.*]] = bitcast %[[STRUCT_SMALL]]* %[[RETVAL]] +// CHECK: %[[COERCEP:.*]] = bitcast %[[STRUCT_SMALL]]* %[[COERCE]] +// CHECK: call {{.*}}memcpy{{.*}} %[[RETVALP]]{{.*}} %[[COERCEP]] +// CHECK: %[[COERCEDIVE1:.*]] = getelementptr{{.*}} %[[RETVAL]] +// CHECK: %[[TMP:.*]] = load{{.*}} %[[COERCEDIVE1]] +// CHECK: %[[COERCEVALPI:.*]] = ptrtoint{{.*}} %[[TMP]] +// CHECK: ret{{.*}} %[[COERCEVALPI]] + +Small (*fp)() = []() -> Small { return Small(); }; diff --git a/clang/test/CodeGenCXX/type_visibility.cpp b/clang/test/CodeGenCXX/type_visibility.cpp index 0096525cd772..a7b7198a23fa 100644 --- a/clang/test/CodeGenCXX/type_visibility.cpp +++ b/clang/test/CodeGenCXX/type_visibility.cpp @@ -110,14 +110,14 @@ namespace type0 { }; void A::foo() {} - // FUNS-LABEL: define{{.*}} void @_ZN5type01A3fooEv( - // VARS: @_ZTVN5type01AE = dso_local unnamed_addr constant - // VARS: @_ZTSN5type01AE = dso_local constant - // VARS: @_ZTIN5type01AE = dso_local constant + // FUNS-LABEL: define void @_ZN5type01A3fooEv( + // VARS: @_ZTVN5type01AE = unnamed_addr constant + // VARS: @_ZTSN5type01AE = constant + // VARS: @_ZTIN5type01AE = constant // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type01A3fooEv( - // VARS-HIDDEN: @_ZTVN5type01AE = dso_local unnamed_addr constant - // VARS-HIDDEN: @_ZTSN5type01AE = dso_local constant - // VARS-HIDDEN: @_ZTIN5type01AE = dso_local constant + // VARS-HIDDEN: @_ZTVN5type01AE = unnamed_addr constant + // VARS-HIDDEN: @_ZTSN5type01AE = constant + // VARS-HIDDEN: @_ZTIN5type01AE = constant } namespace type1 { @@ -127,13 +127,13 @@ namespace type1 { void A::foo() {} // FUNS-LABEL: define hidden void @_ZN5type11A3fooEv( - // VARS: @_ZTVN5type11AE = dso_local unnamed_addr constant - // VARS: @_ZTSN5type11AE = dso_local constant - // VARS: @_ZTIN5type11AE = dso_local constant + // VARS: @_ZTVN5type11AE = unnamed_addr constant + // VARS: @_ZTSN5type11AE = constant + // VARS: @_ZTIN5type11AE = constant // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type11A3fooEv( - // VARS-HIDDEN: @_ZTVN5type11AE = dso_local unnamed_addr constant - // VARS-HIDDEN: @_ZTSN5type11AE = dso_local constant - // VARS-HIDDEN: @_ZTIN5type11AE = dso_local constant + // VARS-HIDDEN: @_ZTVN5type11AE = unnamed_addr constant + // VARS-HIDDEN: @_ZTSN5type11AE = constant + // VARS-HIDDEN: @_ZTIN5type11AE = constant } namespace type2 { @@ -142,7 +142,7 @@ namespace type2 { }; void A::foo() {} - // FUNS-LABEL: define dso_local void @_ZN5type21A3fooEv( + // FUNS-LABEL: define void @_ZN5type21A3fooEv( // VARS: @_ZTVN5type21AE = hidden unnamed_addr constant // VARS: @_ZTSN5type21AE = hidden constant // VARS: @_ZTIN5type21AE = hidden constant @@ -158,11 +158,11 @@ namespace type3 { }; void A::foo() {} - // FUNS-LABEL: define dso_local void @_ZN5type31A3fooEv( + // FUNS-LABEL: define void @_ZN5type31A3fooEv( // VARS: @_ZTVN5type31AE = hidden unnamed_addr constant // VARS: @_ZTSN5type31AE = hidden constant // VARS: @_ZTIN5type31AE = hidden constant - // FUNS-HIDDEN-LABEL: define dso_local void @_ZN5type31A3fooEv( + // FUNS-HIDDEN-LABEL: define void @_ZN5type31A3fooEv( // VARS-HIDDEN: @_ZTVN5type31AE = hidden unnamed_addr constant // VARS-HIDDEN: @_ZTSN5type31AE = hidden constant // VARS-HIDDEN: @_ZTIN5type31AE = hidden constant diff --git a/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp b/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp index 8f413021b3d0..dd1c88a65334 100644 --- a/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp +++ b/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp @@ -13,7 +13,7 @@ void test(X x) { // CHECK-LABEL: define dso_local void @"?test@@YAXUX@@@Z" // X86: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.X }> - // X86: call void (<{ %struct.X }>*, ...) bitcast (void (...)* @"?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca %[[argmem]]) + // X86: call void (<{ %struct.X }>*, ...) bitcast (void (...)* @"?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca(<{ %struct.X }>) %[[argmem]]) // X64: alloca %struct.X diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp index 48ec1b8b712f..aff6554282ca 100644 --- a/clang/test/CodeGenCXX/visibility.cpp +++ b/clang/test/CodeGenCXX/visibility.cpp @@ -18,7 +18,7 @@ namespace test30 { }; H DEFAULT a; X<&a> b; - // CHECK: _ZN6test301bE = dso_local global + // CHECK: _ZN6test301bE = global // CHECK-HIDDEN: _ZN6test301bE = hidden global } @@ -33,7 +33,7 @@ namespace test25 { class DEFAULT A { }; X::definition a; - // CHECK: @_ZN6test251aE = dso_local global + // CHECK: @_ZN6test251aE = global // CHECK-HIDDEN: @_ZN6test251aE = hidden global } @@ -41,7 +41,7 @@ namespace test28 { class DEFAULT foo { }; foo myvec; - // CHECK: @_ZN6test285myvecE = dso_local global + // CHECK: @_ZN6test285myvecE = global // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global } @@ -53,8 +53,8 @@ namespace test29 { DEFAULT extern RECT data_rect; RECT data_rect = { -1}; #pragma GCC visibility pop - // CHECK: @_ZN6test299data_rectE = dso_local global - // CHECK-HIDDEN: @_ZN6test299data_rectE = dso_local global + // CHECK: @_ZN6test299data_rectE = global + // CHECK-HIDDEN: @_ZN6test299data_rectE = global } namespace test40 { @@ -103,17 +103,17 @@ namespace test48 { // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 // CHECK: @_ZN5Test71aE = hidden global -// CHECK: @_ZN5Test71bE = dso_local global -// CHECK: @test9_var = dso_local global -// CHECK-HIDDEN: @test9_var = dso_local global +// CHECK: @_ZN5Test71bE = global +// CHECK: @test9_var = global +// CHECK-HIDDEN: @test9_var = global // CHECK: @_ZN6Test121A6hiddenE = external hidden global // CHECK: @_ZN6Test121A7visibleE = external global // CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global // CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global // CHECK: @_ZN6Test131B1aE = hidden global -// CHECK: @_ZN6Test131C1aE = dso_local global +// CHECK: @_ZN6Test131C1aE = global // CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global -// CHECK-HIDDEN: @_ZN6Test131C1aE = dso_local global +// CHECK-HIDDEN: @_ZN6Test131C1aE = global // CHECK: @_ZN6Test143varE = external global // CHECK-HIDDEN: @_ZN6Test143varE = external global // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] @@ -134,8 +134,8 @@ namespace test27 { void C::D::g() { } - // CHECK: _ZTVN6test271CIiE1DE = dso_local unnamed_addr constant - // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = dso_local unnamed_addr constant + // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant + // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant } // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant @@ -195,7 +195,7 @@ namespace Test4 HIDDEN { }; // A has default visibility. - // CHECK-LABEL: define dso_local void @_ZN5Test41A1fEv + // CHECK-LABEL: define void @_ZN5Test41A1fEv void A::f() { } } @@ -209,7 +209,7 @@ namespace Test5 { namespace NS { // g is in NS, but this NS decl is not hidden. - // CHECK-LABEL: define dso_local void @_ZN5Test52NS1gEv + // CHECK-LABEL: define void @_ZN5Test52NS1gEv void g() { } } } @@ -268,8 +268,8 @@ namespace Test9 { void DEFAULT test9_fun(struct A *a) { } struct A DEFAULT test9_var; // above } - // CHECK-LABEL: define dso_local void @test9_fun( - // CHECK-HIDDEN-LABEL: define dso_local void @test9_fun( + // CHECK-LABEL: define void @test9_fun( + // CHECK-HIDDEN-LABEL: define void @test9_fun( void test() { A a = test9_var; @@ -285,8 +285,8 @@ namespace Test10 { void foo(A*); }; - // CHECK-LABEL: define dso_local void @_ZN6Test101B3fooEPNS_1AE( - // CHECK-HIDDEN-LABEL: define dso_local void @_ZN6Test101B3fooEPNS_1AE( + // CHECK-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( + // CHECK-HIDDEN-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( void B::foo(A*) {} } @@ -507,7 +507,7 @@ namespace Test20 { static void test3(); }; - // CHECK-LABEL: define dso_local void @_ZN6Test201AILj1EE5test2Ev() + // CHECK-LABEL: define void @_ZN6Test201AILj1EE5test2Ev() void A<1>::test2() {} // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev() @@ -684,8 +684,8 @@ namespace test26 { template<> void C::f() { } - // CHECK-LABEL: define dso_local void @_ZN6test261CIiE1fEv - // CHECK-HIDDEN-LABEL: define dso_local void @_ZN6test261CIiE1fEv + // CHECK-LABEL: define void @_ZN6test261CIiE1fEv + // CHECK-HIDDEN-LABEL: define void @_ZN6test261CIiE1fEv } namespace test31 { @@ -709,8 +709,8 @@ namespace test32 { }; void A::B::baz() { } - // CHECK-LABEL: define dso_local void @_ZN6test321A1B3bazEv - // CHECK-HIDDEN-LABEL: define dso_local void @_ZN6test321A1B3bazEv + // CHECK-LABEL: define void @_ZN6test321A1B3bazEv + // CHECK-HIDDEN-LABEL: define void @_ZN6test321A1B3bazEv } namespace test33 { @@ -829,8 +829,8 @@ namespace test42 { }; void bar::zed() { } - // CHECK-LABEL: define dso_local void @_ZN6test423barINS_3fooEE3zedEv - // CHECK-HIDDEN-LABEL: define dso_local void @_ZN6test423barINS_3fooEE3zedEv + // CHECK-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv + // CHECK-HIDDEN-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv } namespace test43 { @@ -842,8 +842,8 @@ namespace test43 { template <> DEFAULT void bar() { } - // CHECK-LABEL: define dso_local void @_ZN6test433barINS_3fooEEEvv - // CHECK-HIDDEN-LABEL: define dso_local void @_ZN6test433barINS_3fooEEEvv + // CHECK-LABEL: define void @_ZN6test433barINS_3fooEEEvv + // CHECK-HIDDEN-LABEL: define void @_ZN6test433barINS_3fooEEEvv } namespace test44 { @@ -1208,10 +1208,10 @@ namespace test65 { static void foo() {} }; - // CHECK-LABEL: define dso_local void @_ZN6test651BINS_1AEE4funcEv() + // CHECK-LABEL: define void @_ZN6test651BINS_1AEE4funcEv() template <> DEFAULT void B::func() {} - // CHECK-LABEL: define dso_local void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv() + // CHECK-LABEL: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv() template <> template <> DEFAULT void B::funcT2() {} // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6funcT1IiEEvv() @@ -1314,6 +1314,6 @@ namespace test69 { } namespace foo __attribute__((visibility("hidden"))) { } - // CHECK-LABEL: define dso_local void @_ZN6test693foo1fEv + // CHECK-LABEL: define void @_ZN6test693foo1fEv // CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv } diff --git a/clang/test/CodeGenCoroutines/coro-alloc.cpp b/clang/test/CodeGenCoroutines/coro-alloc.cpp index bf8edf012a33..c60ca5a83d48 100644 --- a/clang/test/CodeGenCoroutines/coro-alloc.cpp +++ b/clang/test/CodeGenCoroutines/coro-alloc.cpp @@ -245,6 +245,8 @@ extern "C" int f4(promise_on_alloc_failure_tag) { // CHECK: %[[Tmp1:.*]] = load i32, i32* %[[Gro]] // CHECK-NEXT: store i32 %[[Tmp1]], i32* %[[RetVal]] + // CHECK-NEXT: %[[Gro_CAST:.+]] = bitcast i32* %[[Gro]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* %[[Gro_CAST]]) #2 // CHECK-NEXT: br label %[[RetBB]] // CHECK: [[RetBB]]: diff --git a/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp b/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp index f8173d8f8df0..1b0c3a1c5c57 100644 --- a/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp +++ b/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp @@ -57,12 +57,18 @@ throwing_task f() { // CHECK-NEXT: to label %[[RESUMEENDCATCHCONT:.+]] unwind label // CHECK: [[RESUMEENDCATCHCONT]]: // CHECK-NEXT: br label %[[RESUMETRYCONT]] + // CHECK: [[RESUMETRYCONT]]: + // CHECK-NEXT: br label %[[CLEANUP:.+]] + // CHECK: [[CLEANUP]]: + // CHECK: switch i32 %{{.+}}, label %{{.+}} [ + // CHECK-NEXT: i32 0, label %[[CLEANUPCONT:.+]] + // CHECK-NEXT: ] // The variable RESUMETHREW is loaded and if true, then 'await_resume' // threw an exception and the coroutine body is skipped, and the final // suspend is executed immediately. Otherwise, the coroutine body is // executed, and then the final suspend. - // CHECK: [[RESUMETRYCONT]]: + // CHECK: [[CLEANUPCONT]]: // CHECK-NEXT: %[[RESUMETHREWLOAD:.+]] = load i1, i1* %[[RESUMETHREW]] // CHECK-NEXT: br i1 %[[RESUMETHREWLOAD]], label %[[RESUMEDCONT:.+]], label %[[RESUMEDBODY:.+]] @@ -76,7 +82,7 @@ throwing_task f() { // CHECK-NEXT: br label %[[COROFINAL]] // CHECK: [[COROFINAL]]: - // CHECK-NEXT: call void @_ZN13throwing_task12promise_type13final_suspendEv + // CHECK: call void @_ZN13throwing_task12promise_type13final_suspendEv co_return; } diff --git a/clang/test/CodeGenCoroutines/coro-await.cpp b/clang/test/CodeGenCoroutines/coro-await.cpp index 4344cf3db4d8..3fa45d5f9ab6 100644 --- a/clang/test/CodeGenCoroutines/coro-await.cpp +++ b/clang/test/CodeGenCoroutines/coro-await.cpp @@ -231,7 +231,9 @@ extern "C" void TestScalar() { int Val = co_await ScalarAwaiter{}; // CHECK: %[[Result2:.+]] = call i32 @_ZN13ScalarAwaiter12await_resumeEv(%struct.ScalarAwaiter* - // CHECK: store i32 %[[Result2]], i32* %Val + // CHECK: store i32 %[[Result2]], i32* %[[TMP_EXPRCLEANUP:.+]], + // CHECK: %[[TMP:.+]] = load i32, i32* %[[TMP_EXPRCLEANUP]], + // CHECK: store i32 %[[TMP]], i32* %Val, co_await ScalarAwaiter{}; // CHECK: call i32 @_ZN13ScalarAwaiter12await_resumeEv(%struct.ScalarAwaiter* @@ -312,19 +314,25 @@ void AwaitReturnsLValue(double) { // CHECK: %[[YVAR:.+]] = alloca %struct.RefTag*, // CHECK-NEXT: %[[TMP1:.+]] = alloca %struct.AwaitResumeReturnsLValue, + // CHECK: %[[TMP_EXPRCLEANUP1:.+]] = alloca %struct.RefTag*, // CHECK: %[[ZVAR:.+]] = alloca %struct.RefTag*, // CHECK-NEXT: %[[TMP2:.+]] = alloca %struct.AwaitResumeReturnsLValue, + // CHECK: %[[TMP_EXPRCLEANUP2:.+]] = alloca %struct.RefTag*, // CHECK: %[[RES1:.+]] = call nonnull align 1 dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* {{[^,]*}} %[[AVAR]]) // CHECK-NEXT: store %struct.RefTag* %[[RES1]], %struct.RefTag** %[[XVAR]], RefTag& x = co_await a; // CHECK: %[[RES2:.+]] = call nonnull align 1 dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* {{[^,]*}} %[[TMP1]]) - // CHECK-NEXT: store %struct.RefTag* %[[RES2]], %struct.RefTag** %[[YVAR]], + // CHECK-NEXT: store %struct.RefTag* %[[RES2]], %struct.RefTag** %[[TMP_EXPRCLEANUP1]], + // CHECK: %[[LOAD_TMP1:.+]] = load %struct.RefTag*, %struct.RefTag** %[[TMP_EXPRCLEANUP1]], + // CHECK: store %struct.RefTag* %[[LOAD_TMP1]], %struct.RefTag** %[[YVAR]], RefTag& y = co_await AwaitResumeReturnsLValue{}; // CHECK: %[[RES3:.+]] = call nonnull align 1 dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* {{[^,]*}} %[[TMP2]]) - // CHECK-NEXT: store %struct.RefTag* %[[RES3]], %struct.RefTag** %[[ZVAR]], + // CHECK-NEXT: store %struct.RefTag* %[[RES3]], %struct.RefTag** %[[TMP_EXPRCLEANUP2]], + // CHECK: %[[LOAD_TMP2:.+]] = load %struct.RefTag*, %struct.RefTag** %[[TMP_EXPRCLEANUP2]], + // CHECK: store %struct.RefTag* %[[LOAD_TMP2]], %struct.RefTag** %[[ZVAR]], RefTag& z = co_yield 42; } diff --git a/clang/test/CodeGenCoroutines/coro-dest-slot.cpp b/clang/test/CodeGenCoroutines/coro-dest-slot.cpp index 0c8ef6b04582..762fa1aede3c 100644 --- a/clang/test/CodeGenCoroutines/coro-dest-slot.cpp +++ b/clang/test/CodeGenCoroutines/coro-dest-slot.cpp @@ -17,10 +17,24 @@ struct coro { extern "C" coro f(int) { co_return; } // Verify that cleanup.dest.slot is eliminated in a coroutine. // CHECK-LABEL: f( +// CHECK: %[[INIT_SUSPEND:.+]] = call i8 @llvm.coro.suspend( +// CHECK-NEXT: switch i8 %[[INIT_SUSPEND]], label +// CHECK-NEXT: i8 0, label %[[INIT_READY:.+]] +// CHECK-NEXT: i8 1, label %[[INIT_CLEANUP:.+]] +// CHECK-NEXT: ] +// CHECK: %[[CLEANUP_DEST0:.+]] = phi i32 [ 0, %[[INIT_READY]] ], [ 2, %[[INIT_CLEANUP]] ] + +// CHECK: %[[FINAL_SUSPEND:.+]] = call i8 @llvm.coro.suspend( +// CHECK-NEXT: switch i8 %29, label %coro.ret [ +// CHECK-NEXT: i8 0, label %[[FINAL_READY:.+]] +// CHECK-NEXT: i8 1, label %[[FINAL_CLEANUP:.+]] +// CHECK-NEXT: ] + // CHECK: call void @_ZNSt12experimental13coroutines_v113suspend_never12await_resumeEv( -// CHECK: %[[CLEANUP_DEST:.+]] = phi i32 [ 0, %{{.+}} ], [ 2, %{{.+}} ], [ 2, %{{.+}} ] +// CHECK: %[[CLEANUP_DEST1:.+]] = phi i32 [ 0, %[[FINAL_READY]] ], [ 2, %[[FINAL_CLEANUP]] ] +// CHECK: %[[CLEANUP_DEST2:.+]] = phi i32 [ %[[CLEANUP_DEST0]], %{{.+}} ], [ %[[CLEANUP_DEST1]], %{{.+}} ], [ 0, %{{.+}} ] // CHECK: call i8* @llvm.coro.free( -// CHECK: switch i32 %cleanup.dest.slot.0, label %{{.+}} [ +// CHECK: switch i32 %[[CLEANUP_DEST2]], label %{{.+}} [ // CHECK-NEXT: i32 0 // CHECK-NEXT: i32 2 // CHECK-NEXT: ] diff --git a/clang/test/CodeGenCoroutines/coro-params.cpp b/clang/test/CodeGenCoroutines/coro-params.cpp index d69d3103e39a..12332cd793c4 100644 --- a/clang/test/CodeGenCoroutines/coro-params.cpp +++ b/clang/test/CodeGenCoroutines/coro-params.cpp @@ -70,7 +70,11 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam) { // CHECK: call i8* @llvm.coro.begin( // CHECK: call void @_ZN8MoveOnlyC1EOS_(%struct.MoveOnly* {{[^,]*}} %[[MoCopy]], %struct.MoveOnly* nonnull align 4 dereferenceable(4) %[[MoParam]]) + // CHECK-NEXT: bitcast %struct.MoveAndCopy* %[[McCopy]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-NEXT: call void @_ZN11MoveAndCopyC1EOS_(%struct.MoveAndCopy* {{[^,]*}} %[[McCopy]], %struct.MoveAndCopy* nonnull align 4 dereferenceable(4) %[[McParam]]) # + // CHECK-NEXT: bitcast %"struct.std::experimental::coroutine_traits::promise_type"* %__promise to i8* + // CHECK-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-NEXT: invoke void @_ZNSt12experimental16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeC1Ev( // CHECK: call void @_ZN14suspend_always12await_resumeEv( @@ -89,9 +93,17 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam) { // CHECK: call void @_ZN14suspend_always12await_resumeEv( // Destroy promise, then parameter copies: - // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeD1Ev(%"struct.std::experimental::coroutine_traits::promise_type"* {{[^,]*}} %__promise) #2 + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeD1Ev(%"struct.std::experimental::coroutine_traits::promise_type"* {{[^,]*}} %__promise) + // CHECK-NEXT: bitcast %"struct.std::experimental::coroutine_traits::promise_type"* %__promise to i8* + // CHECK-NEXT: call void @llvm.lifetime.end.p0i8( // CHECK-NEXT: call void @_ZN11MoveAndCopyD1Ev(%struct.MoveAndCopy* {{[^,]*}} %[[McCopy]]) + // CHECK-NEXT: bitcast %struct.MoveAndCopy* %[[McCopy]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.end.p0i8( // CHECK-NEXT: call void @_ZN8MoveOnlyD1Ev(%struct.MoveOnly* {{[^,]*}} %[[MoCopy]] + // CHECK-NEXT: bitcast %struct.MoveOnly* %[[MoCopy]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.end.p0i8( + // CHECK-NEXT: bitcast i32* %{{.+}} to i8* + // CHECK-NEXT: call void @llvm.lifetime.end.p0i8( // CHECK-NEXT: call i8* @llvm.coro.free( } @@ -103,9 +115,17 @@ void dependent_params(T x, U, U y) { // CHECK-NEXT: %[[y_copy:.+]] = alloca %struct.B // CHECK: call i8* @llvm.coro.begin + // CHECK-NEXT: bitcast %struct.A* %[[x_copy]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-NEXT: call void @_ZN1AC1EOS_(%struct.A* {{[^,]*}} %[[x_copy]], %struct.A* nonnull align 4 dereferenceable(512) %x) + // CHECK-NEXT: bitcast %struct.B* %[[unnamed_copy]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-NEXT: call void @_ZN1BC1EOS_(%struct.B* {{[^,]*}} %[[unnamed_copy]], %struct.B* nonnull align 4 dereferenceable(512) %0) + // CHECK-NEXT: %10 = bitcast %struct.B* %[[y_copy]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-NEXT: call void @_ZN1BC1EOS_(%struct.B* {{[^,]*}} %[[y_copy]], %struct.B* nonnull align 4 dereferenceable(512) %y) + // CHECK-NEXT: bitcast %"struct.std::experimental::coroutine_traits::promise_type"* %__promise to i8* + // CHECK-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-NEXT: invoke void @_ZNSt12experimental16coroutine_traitsIJv1A1BS2_EE12promise_typeC1Ev( co_return; diff --git a/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp index 0725abc91c02..a5592b066f7a 100644 --- a/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp +++ b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -O1 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -O0 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s #include "Inputs/coroutine.h" @@ -50,8 +50,13 @@ detached_task foo() { // check that the lifetime of the coroutine handle used to obtain the address is contained within single basic block, and hence does not live across suspension points. // CHECK-LABEL: final.suspend: -// CHECK: %[[PTR1:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle.0"* %[[ADDR_TMP:.+]] to i8* -// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* %[[PTR1]]) -// CHECK: call i8* @{{.*address.*}}(%"struct.std::experimental::coroutines_v1::coroutine_handle.0"* {{[^,]*}} %[[ADDR_TMP]]) -// CHECK-NEXT: %[[PTR2:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle.0"* %[[ADDR_TMP]] to i8* -// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* %[[PTR2]]) +// CHECK: %{{.+}} = call token @llvm.coro.save(i8* null) +// CHECK: %[[HDL_CAST1:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle.0"* %[[HDL:.+]] to i8* +// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* %[[HDL_CAST1]]) +// CHECK: %[[CALL:.+]] = call i8* @_ZN13detached_task12promise_type13final_awaiter13await_suspendENSt12experimental13coroutines_v116coroutine_handleIS0_EE( +// CHECK: %[[HDL_CAST2:.+]] = getelementptr inbounds %"struct.std::experimental::coroutines_v1::coroutine_handle.0", %"struct.std::experimental::coroutines_v1::coroutine_handle.0"* %[[HDL]], i32 0, i32 0 +// CHECK: store i8* %[[CALL]], i8** %[[HDL_CAST2]], align 8 +// CHECK: %[[HDL_TRANSFER:.+]] = call i8* @_ZNKSt12experimental13coroutines_v116coroutine_handleIvE7addressEv(%"struct.std::experimental::coroutines_v1::coroutine_handle.0"* nonnull dereferenceable(8) %[[HDL]]) +// CHECK: %[[HDL_CAST3:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle.0"* %[[HDL]] to i8* +// CHECK: call void @llvm.lifetime.end.p0i8(i64 8, i8* %[[HDL_CAST3]]) +// CHECK: call void @llvm.coro.resume(i8* %[[HDL_TRANSFER]]) diff --git a/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp b/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp index 30cec4e5000b..f038c5b3a913 100644 --- a/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp +++ b/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp @@ -50,6 +50,8 @@ coro_t f() { // CHECK: [[TRYCONT]]: // CHECK-NEXT: br label %[[COROFIN:.+]] // CHECK: [[COROFIN]]: +// CHECK-NEXT: bitcast %"struct.std::experimental::coroutines_v1::suspend_never"* %{{.+}} to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-NEXT: call void @"?final_suspend@promise_type@coro_t@@QEAA?AUsuspend_never@coroutines_v1@experimental@std@@XZ"( // CHECK-LPAD: @_Z1fv( @@ -69,4 +71,6 @@ coro_t f() { // CHECK-LPAD: [[TRYCONT]]: // CHECK-LPAD: br label %[[COROFIN:.+]] // CHECK-LPAD: [[COROFIN]]: +// CHECK-LPAD-NEXT: bitcast %"struct.std::experimental::coroutines_v1::suspend_never"* %{{.+}} to i8* +// CHECK-LPAD-NEXT: call void @llvm.lifetime.start.p0i8( // CHECK-LPAD-NEXT: call void @_ZN6coro_t12promise_type13final_suspendEv( diff --git a/clang/test/CodeGenObjC/attr-nomerge.m b/clang/test/CodeGenObjC/attr-nomerge.m new file mode 100644 index 000000000000..7d053d0b1d69 --- /dev/null +++ b/clang/test/CodeGenObjC/attr-nomerge.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm -fobjc-exceptions -triple x86_64-unknown-linux -o - %s | FileCheck %s + +// Test that the nomerge attribute is applied to function calls +// in @try, @catch and @finally +void opaque(void); +void opaque2(void); +void opaque3(void); + +int main(int argc, const char * argv[]) { + __attribute__((nomerge)) @try { + opaque(); + } @catch(...) { + opaque2(); + } @finally { + opaque3(); + } + + return 0; +} + +// CHECK: call void @opaque() #[[ATTR0:[0-9]+]] +// CHECK-DAG: call void @opaque2() #[[ATTR0]] +// CHECK-DAG: call void @opaque3() #[[ATTR0]] +// CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}} diff --git a/clang/test/CodeGenObjC/debug-info-property-class-instance-same-name.m b/clang/test/CodeGenObjC/debug-info-property-class-instance-same-name.m new file mode 100644 index 000000000000..68423fc07f8a --- /dev/null +++ b/clang/test/CodeGenObjC/debug-info-property-class-instance-same-name.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +// Both properties should be emitted as having a class and an instance property +// with the same name is allowed. +@interface I1 +// CHECK: !DIObjCProperty(name: "p1" +// CHECK-SAME: line: [[@LINE+1]] +@property int p1; +// CHECK: !DIObjCProperty(name: "p1" +// CHECK-SAME: line: [[@LINE+1]] +@property(class) int p1; +@end + +@implementation I1 +@synthesize p1; +@end + +void foo(I1 *iptr) {} diff --git a/clang/test/CodeGenObjCXX/arc-indirect.mm b/clang/test/CodeGenObjCXX/arc-indirect.mm index de7566fcf987..40543c054ea5 100644 --- a/clang/test/CodeGenObjCXX/arc-indirect.mm +++ b/clang/test/CodeGenObjCXX/arc-indirect.mm @@ -15,8 +15,8 @@ - (void)object:(id)obj struct:(S)s { } @end -// CHECK-GNUSTEP: define internal void @_i_C__object_struct_(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca %0) -// CHECK-DARWIN: define internal void @"\01-[C object:struct:]"(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca %0) +// CHECK-GNUSTEP: define internal void @_i_C__object_struct_(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>) %0) +// CHECK-DARWIN: define internal void @"\01-[C object:struct:]"(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>) %0) // CHECK: %obj = getelementptr inbounds <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>, <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* %0, i32 0, i32 2 // CHECK: %[[INSTANCE:[0-9]+]] = load i8*, i8** %obj, align 4 // CHECK: call void @llvm.objc.storeStrong(i8** %obj, i8* %[[INSTANCE]]) diff --git a/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm b/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm index 6be7995f5f01..26c13acf8959 100644 --- a/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm +++ b/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm @@ -10,7 +10,7 @@ // Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d. // // CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAUobjc_object@@01@Z" -// CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca %0) +// CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca(<{ %struct.A, i8*, %struct.A, i8* }>) %0) void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) { // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* {{[^,]*}} %{{.*}}) // CHECK: call void @llvm.objc.storeStrong(i8** %{{.*}}, i8* null) diff --git a/clang/test/CodeGenOpenCL/amdgpu-features.cl b/clang/test/CodeGenOpenCL/amdgpu-features.cl index 930c53705d84..5c9059866e88 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-features.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-features.cl @@ -50,17 +50,17 @@ // GFX900: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" // GFX902: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" // GFX904: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX908: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+mai-insts,+s-memrealtime,+s-memtime-inst" +// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot7-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" +// GFX908: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+mai-insts,+s-memrealtime,+s-memtime-inst" // GFX909: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX90A: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+gfx90a-insts,+mai-insts,+s-memrealtime,+s-memtime-inst" +// GFX90A: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+gfx90a-insts,+mai-insts,+s-memrealtime,+s-memtime-inst" // GFX90C: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" // GFX1010: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX1011: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX1012: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX1030: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX1031: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX1032: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" -// GFX1033: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" +// GFX1011: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" +// GFX1012: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" +// GFX1030: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" +// GFX1031: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" +// GFX1032: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" +// GFX1033: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,+flat-address-space,+gfx10-3-insts,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime,+s-memtime-inst" kernel void test() {} diff --git a/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl b/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl index d1ab6aceac5c..a4d28c7e6cf8 100644 --- a/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl +++ b/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -finclude-default-header -cl-std=CL1.2 -emit-llvm -o - -O0 | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -finclude-default-header -fdeclare-opencl-builtins -cl-std=CL1.2 -emit-llvm -o - -O0 | FileCheck %s #pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : enable void test_int8(uchar4 ua, uchar4 ub, char4 sa, char4 sb) { diff --git a/clang/test/CodeGenOpenCL/atomic-ops.cl b/clang/test/CodeGenOpenCL/atomic-ops.cl index bd5a01c5434a..e5da50883c65 100644 --- a/clang/test/CodeGenOpenCL/atomic-ops.cl +++ b/clang/test/CodeGenOpenCL/atomic-ops.cl @@ -227,6 +227,7 @@ void generalFailureOrder(atomic_int *ptr, int *ptr2, int success, int fail) { // CHECK: [[RELEASE]] // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [ + // CHECK-NEXT: i32 2, label %[[RELEASE_ACQUIRE:[0-9a-zA-Z._]+]] // CHECK-NEXT: ] // CHECK: [[ACQREL]] @@ -254,6 +255,14 @@ void generalFailureOrder(atomic_int *ptr, int *ptr2, int success, int fail) { // CHECK: cmpxchg {{.*}} acquire acquire, align 4 // CHECK: br + // CHECK: [[RELEASE_MONOTONIC]] + // CHECK: cmpxchg {{.*}} release monotonic, align 4 + // CHECK: br + + // CHECK: [[RELEASE_ACQUIRE]] + // CHECK: cmpxchg {{.*}} release acquire, align 4 + // CHECK: br + // CHECK: [[ACQREL_MONOTONIC]] // CHECK: cmpxchg {{.*}} acq_rel monotonic, align 4 // CHECK: br diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl index cb83c0b48c65..e7a71b515885 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl @@ -13,8 +13,8 @@ kernel void builtins_amdgcn_dl_insts_err( half2 v2hA, half2 v2hB, float fC, short2 v2ssA, short2 v2ssB, int siA, int siB, int siC, ushort2 v2usA, ushort2 v2usB, uint uiA, uint uiB, uint uiC) { - fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot2-insts}} - fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot2-insts}} + fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot7-insts}} + fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot7-insts}} siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, false); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot2-insts}} siOut[1] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, true); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot2-insts}} @@ -25,12 +25,12 @@ kernel void builtins_amdgcn_dl_insts_err( siOut[2] = __builtin_amdgcn_sdot4(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot1-insts}} siOut[3] = __builtin_amdgcn_sdot4(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot1-insts}} - uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot2-insts}} - uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot2-insts}} + uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot7-insts}} + uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot7-insts}} siOut[4] = __builtin_amdgcn_sdot8(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot1-insts}} siOut[5] = __builtin_amdgcn_sdot8(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot1-insts}} - uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot2-insts}} - uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot2-insts}} + uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot7-insts}} + uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot7-insts}} } diff --git a/clang/test/CodeGenOpenCL/builtins.cl b/clang/test/CodeGenOpenCL/builtins.cl index 2ab6f12a9f4b..1d566698d045 100644 --- a/clang/test/CodeGenOpenCL/builtins.cl +++ b/clang/test/CodeGenOpenCL/builtins.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -finclude-default-header -cl-std=clc++ -fblocks -O0 -emit-llvm -o - -triple "spir-unknown-unknown" | FileCheck %s +// RUN: %clang_cc1 %s -finclude-default-header -fdeclare-opencl-builtins -cl-std=clc++ -fblocks -O0 -emit-llvm -o - -triple "spir-unknown-unknown" | FileCheck %s void testBranchingOnEnqueueKernel(queue_t default_queue, unsigned flags, ndrange_t ndrange) { // Ensure `enqueue_kernel` can be branched upon. diff --git a/clang/test/CodeGenOpenCL/fdeclare-opencl-builtins.cl b/clang/test/CodeGenOpenCL/fdeclare-opencl-builtins.cl index a59357e331e7..665297b469f8 100644 --- a/clang/test/CodeGenOpenCL/fdeclare-opencl-builtins.cl +++ b/clang/test/CodeGenOpenCL/fdeclare-opencl-builtins.cl @@ -1,8 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm -o - -O0 -triple spir-unknown-unknown -cl-std=CL1.2 -finclude-default-header %s | FileCheck %s // RUN: %clang_cc1 -emit-llvm -o - -O0 -triple spir-unknown-unknown -cl-std=CL1.2 -fdeclare-opencl-builtins -finclude-default-header %s | FileCheck %s // Test that mix is correctly defined. // CHECK-LABEL: @test_float -// CHECK: call <4 x float> @_Z3mixDv4_fS_f +// CHECK: call spir_func <4 x float> @_Z3mixDv4_fS_f // CHECK: ret void test_float(float4 x, float a) { float4 ret = mix(x, x, a); @@ -10,7 +11,7 @@ void test_float(float4 x, float a) { // Test that Attr.Const from OpenCLBuiltins.td is lowered to a readnone attribute. // CHECK-LABEL: @test_const_attr -// CHECK: call i32 @_Z3maxii({{.*}}) [[ATTR_CONST:#[0-9]]] +// CHECK: call spir_func i32 @_Z3maxii({{.*}}) [[ATTR_CONST:#[0-9]]] // CHECK: ret int test_const_attr(int a) { return max(a, 2); @@ -18,7 +19,7 @@ int test_const_attr(int a) { // Test that Attr.Pure from OpenCLBuiltins.td is lowered to a readonly attribute. // CHECK-LABEL: @test_pure_attr -// CHECK: call <4 x float> @_Z11read_imagef{{.*}} [[ATTR_PURE:#[0-9]]] +// CHECK: call spir_func <4 x float> @_Z11read_imagef{{.*}} [[ATTR_PURE:#[0-9]]] // CHECK: ret kernel void test_pure_attr(read_only image1d_t img) { float4 resf = read_imagef(img, 42); @@ -26,7 +27,7 @@ kernel void test_pure_attr(read_only image1d_t img) { // Test that builtins with only one prototype are mangled. // CHECK-LABEL: @test_mangling -// CHECK: call i32 @_Z12get_local_idj +// CHECK: call spir_func i32 @_Z12get_local_idj kernel void test_mangling() { size_t lid = get_local_id(0); } diff --git a/clang/test/CodeGenOpenCL/sampler.cl b/clang/test/CodeGenOpenCL/sampler.cl index e6bda49f51c8..5ad8d0dbbf37 100644 --- a/clang/test/CodeGenOpenCL/sampler.cl +++ b/clang/test/CodeGenOpenCL/sampler.cl @@ -39,7 +39,7 @@ kernel void foo(sampler_t smp_par) { // Case 2b sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_NEAREST; // CHECK: [[smp_ptr:%[A-Za-z0-9_\.]+]] = alloca %opencl.sampler_t addrspace(2)* - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 19) + // CHECK: [[SAMP:%[0-9]+]] = call spir_func %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 19) // CHECK: store %opencl.sampler_t addrspace(2)* [[SAMP]], %opencl.sampler_t addrspace(2)** [[smp_ptr]] // Case 1b @@ -56,12 +56,12 @@ kernel void foo(sampler_t smp_par) { // Case 1a/2a fnc4smp(glb_smp); - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) + // CHECK: [[SAMP:%[0-9]+]] = call spir_func %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) // CHECK: call spir_func void [[FUNCNAME]](%opencl.sampler_t addrspace(2)* [[SAMP]]) // Case 1a/2c fnc4smp(glb_smp_const); - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) + // CHECK: [[SAMP:%[0-9]+]] = call spir_func %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) // CHECK: call spir_func void [[FUNCNAME]](%opencl.sampler_t addrspace(2)* [[SAMP]]) // Case 1c @@ -70,12 +70,12 @@ kernel void foo(sampler_t smp_par) { // CHECK: call spir_func void [[FUNCNAME]](%opencl.sampler_t addrspace(2)* [[SAMP]]) fnc4smp(5); - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 5) + // CHECK: [[SAMP:%[0-9]+]] = call spir_func %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 5) // CHECK: call spir_func void [[FUNCNAME]](%opencl.sampler_t addrspace(2)* [[SAMP]]) const sampler_t const_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; fnc4smp(const_smp); - // CHECK: [[CONST_SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) + // CHECK: [[CONST_SAMP:%[0-9]+]] = call spir_func %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) // CHECK: store %opencl.sampler_t addrspace(2)* [[CONST_SAMP]], %opencl.sampler_t addrspace(2)** [[CONST_SMP_PTR:%[a-zA-Z0-9]+]] fnc4smp(const_smp); // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[CONST_SMP_PTR]] @@ -83,7 +83,7 @@ kernel void foo(sampler_t smp_par) { constant sampler_t constant_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; fnc4smp(constant_smp); - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) + // CHECK: [[SAMP:%[0-9]+]] = call spir_func %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) // CHECK: call spir_func void [[FUNCNAME]](%opencl.sampler_t addrspace(2)* [[SAMP]]) // TODO: enable sampler initialization with non-constant integer. diff --git a/clang/test/CodeGenOpenCL/size_t.cl b/clang/test/CodeGenOpenCL/size_t.cl index 63a062268da3..b9bb72ac45a0 100644 --- a/clang/test/CodeGenOpenCL/size_t.cl +++ b/clang/test/CodeGenOpenCL/size_t.cl @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple spir-unknown-unknown -o - | FileCheck --check-prefix=SZ32 %s -// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple spir64-unknown-unknown -o - | FileCheck --check-prefix=SZ64 --check-prefix=SZ64ONLY %s -// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple amdgcn -o - | FileCheck --check-prefix=SZ64 --check-prefix=AMDGCN %s -// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple amdgcn---opencl -o - | FileCheck --check-prefix=SZ64 --check-prefix=AMDGCN %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -fdeclare-opencl-builtins -emit-llvm -O0 -triple spir-unknown-unknown -o - | FileCheck --check-prefix=SZ32 %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -fdeclare-opencl-builtins -emit-llvm -O0 -triple spir64-unknown-unknown -o - | FileCheck --check-prefix=SZ64 --check-prefix=SZ64ONLY %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -fdeclare-opencl-builtins -emit-llvm -O0 -triple amdgcn -o - | FileCheck --check-prefix=SZ64 --check-prefix=AMDGCN %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -fdeclare-opencl-builtins -emit-llvm -O0 -triple amdgcn---opencl -o - | FileCheck --check-prefix=SZ64 --check-prefix=AMDGCN %s //SZ32: define{{.*}} i32 @test_ptrtoint_private(i8* %x) //SZ32: ptrtoint i8* %{{.*}} to i32 diff --git a/clang/test/CodeGenOpenCLCXX/address-space-deduction.cl b/clang/test/CodeGenOpenCLCXX/address-space-deduction.clcpp similarity index 86% rename from clang/test/CodeGenOpenCLCXX/address-space-deduction.cl rename to clang/test/CodeGenOpenCLCXX/address-space-deduction.clcpp index c0f30d291c95..e7c883bb8bcb 100644 --- a/clang/test/CodeGenOpenCLCXX/address-space-deduction.cl +++ b/clang/test/CodeGenOpenCLCXX/address-space-deduction.clcpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -O0 -emit-llvm -o - | FileCheck %s -check-prefixes=COMMON,PTR -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -O0 -emit-llvm -o - -DREF | FileCheck %s -check-prefixes=COMMON,REF +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s -check-prefixes=COMMON,PTR +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - -DREF | FileCheck %s -check-prefixes=COMMON,REF #ifdef REF #define PTR & diff --git a/clang/test/CodeGenOpenCLCXX/address-space-deduction2.cl b/clang/test/CodeGenOpenCLCXX/address-space-deduction2.clcpp similarity index 77% rename from clang/test/CodeGenOpenCLCXX/address-space-deduction2.cl rename to clang/test/CodeGenOpenCLCXX/address-space-deduction2.clcpp index 36e89499c954..b454f5a2de98 100644 --- a/clang/test/CodeGenOpenCLCXX/address-space-deduction2.cl +++ b/clang/test/CodeGenOpenCLCXX/address-space-deduction2.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -O0 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s class P { public: diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-conversion.cl b/clang/test/CodeGenOpenCLCXX/addrspace-conversion.clcpp similarity index 63% rename from clang/test/CodeGenOpenCLCXX/addrspace-conversion.cl rename to clang/test/CodeGenOpenCLCXX/addrspace-conversion.clcpp index a80662f72334..0608117dd660 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-conversion.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-conversion.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -O0 -o - | FileCheck %s void bar(__generic volatile unsigned int* ptr) { diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl b/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.clcpp similarity index 95% rename from clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl rename to clang/test/CodeGenOpenCLCXX/addrspace-derived-base.clcpp index 954536a94448..6b087e75c486 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s struct B { int mb; diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-new-delete.cl b/clang/test/CodeGenOpenCLCXX/addrspace-new-delete.clcpp similarity index 80% rename from clang/test/CodeGenOpenCLCXX/addrspace-new-delete.cl rename to clang/test/CodeGenOpenCLCXX/addrspace-new-delete.clcpp index f3a397419def..a78c0373ed18 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-new-delete.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-new-delete.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s typedef __SIZE_TYPE__ size_t; diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-of-this.cl b/clang/test/CodeGenOpenCLCXX/addrspace-of-this.clcpp similarity index 95% rename from clang/test/CodeGenOpenCLCXX/addrspace-of-this.cl rename to clang/test/CodeGenOpenCLCXX/addrspace-of-this.clcpp index 764df17d1f51..50c146bae6eb 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-of-this.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-of-this.clcpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -emit-llvm -pedantic -verify -O0 -o - -DDECL | FileCheck %s --check-prefixes="COMMON,EXPL" -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -emit-llvm -pedantic -verify -O0 -o - -DDECL -DUSE_DEFLT | FileCheck %s --check-prefixes="COMMON,IMPL" -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s --check-prefixes="COMMON,IMPL" +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -pedantic -verify -O0 -o - -DDECL | FileCheck %s --check-prefixes="COMMON,EXPL" +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -pedantic -verify -O0 -o - -DDECL -DUSE_DEFLT | FileCheck %s --check-prefixes="COMMON,IMPL" +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s --check-prefixes="COMMON,IMPL" // expected-no-diagnostics // Test that the 'this' pointer is in the __generic address space. diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-operators.cl b/clang/test/CodeGenOpenCLCXX/addrspace-operators.clcpp similarity index 97% rename from clang/test/CodeGenOpenCLCXX/addrspace-operators.cl rename to clang/test/CodeGenOpenCLCXX/addrspace-operators.clcpp index cad98c6072fa..bd3832635d9b 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-operators.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-operators.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +//RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s enum E { a, diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-references.cl b/clang/test/CodeGenOpenCLCXX/addrspace-references.clcpp similarity index 93% rename from clang/test/CodeGenOpenCLCXX/addrspace-references.cl rename to clang/test/CodeGenOpenCLCXX/addrspace-references.clcpp index 6d4bece1a624..d8e83450a9e5 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-references.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-references.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -triple spir -emit-llvm -o - -O0 | FileCheck %s +//RUN: %clang_cc1 %s -triple spir -emit-llvm -o - -O0 | FileCheck %s typedef short short2 __attribute__((ext_vector_type(2))); diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-with-class.cl b/clang/test/CodeGenOpenCLCXX/addrspace-with-class.clcpp similarity index 93% rename from clang/test/CodeGenOpenCLCXX/addrspace-with-class.cl rename to clang/test/CodeGenOpenCLCXX/addrspace-with-class.clcpp index 7cff76a04dff..c4051f93442e 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-with-class.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-with-class.clcpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CLC++ -emit-llvm -O0 -o - | FileCheck %s --check-prefix=CHECK-DEFINITIONS +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -O0 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -O0 -o - | FileCheck %s --check-prefix=CHECK-DEFINITIONS // This test ensures the proper address spaces and address space cast are used // for constructors, member functions and destructors. diff --git a/clang/test/CodeGenOpenCLCXX/addrspace_cast.cl b/clang/test/CodeGenOpenCLCXX/addrspace_cast.clcpp similarity index 71% rename from clang/test/CodeGenOpenCLCXX/addrspace_cast.cl rename to clang/test/CodeGenOpenCLCXX/addrspace_cast.clcpp index 1ea0fdfb2040..78656cb32aa7 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace_cast.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace_cast.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +//RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s //CHECK-LABEL: define{{.*}} spir_func void @_Z3barPU3AS1i void bar(global int *gl) { diff --git a/clang/test/CodeGenOpenCLCXX/atexit.cl b/clang/test/CodeGenOpenCLCXX/atexit.clcpp similarity index 81% rename from clang/test/CodeGenOpenCLCXX/atexit.cl rename to clang/test/CodeGenOpenCLCXX/atexit.clcpp index 2b28aeaacf45..e987790348fc 100644 --- a/clang/test/CodeGenOpenCLCXX/atexit.cl +++ b/clang/test/CodeGenOpenCLCXX/atexit.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +//RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s struct S { ~S(){}; diff --git a/clang/test/CodeGenOpenCLCXX/constexpr.cl b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp similarity index 94% rename from clang/test/CodeGenOpenCLCXX/constexpr.cl rename to clang/test/CodeGenOpenCLCXX/constexpr.clcpp index 4f2ed7d06f06..7a04d1671274 100644 --- a/clang/test/CodeGenOpenCLCXX/constexpr.cl +++ b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -O0 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s typedef int int2 __attribute__((ext_vector_type(2))); typedef int int4 __attribute__((ext_vector_type(4))); diff --git a/clang/test/CodeGenOpenCLCXX/global_init.cl b/clang/test/CodeGenOpenCLCXX/global_init.clcpp similarity index 79% rename from clang/test/CodeGenOpenCLCXX/global_init.cl rename to clang/test/CodeGenOpenCLCXX/global_init.clcpp index 9f602beda5ba..4e02d4accb62 100644 --- a/clang/test/CodeGenOpenCLCXX/global_init.cl +++ b/clang/test/CodeGenOpenCLCXX/global_init.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s struct S { S() {} diff --git a/clang/test/CodeGenOpenCLCXX/local_addrspace_init.cl b/clang/test/CodeGenOpenCLCXX/local_addrspace_init.clcpp similarity index 89% rename from clang/test/CodeGenOpenCLCXX/local_addrspace_init.cl rename to clang/test/CodeGenOpenCLCXX/local_addrspace_init.clcpp index e892e674ad14..bb9acf09d120 100644 --- a/clang/test/CodeGenOpenCLCXX/local_addrspace_init.cl +++ b/clang/test/CodeGenOpenCLCXX/local_addrspace_init.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s // Test that we don't initialize local address space objects. //CHECK: @_ZZ4testE1i = internal addrspace(3) global i32 undef diff --git a/clang/test/CodeGenOpenCLCXX/method-overload-address-space.cl b/clang/test/CodeGenOpenCLCXX/method-overload-address-space.clcpp similarity index 91% rename from clang/test/CodeGenOpenCLCXX/method-overload-address-space.cl rename to clang/test/CodeGenOpenCLCXX/method-overload-address-space.clcpp index b170ead38179..3cca5c2dc8c5 100644 --- a/clang/test/CodeGenOpenCLCXX/method-overload-address-space.cl +++ b/clang/test/CodeGenOpenCLCXX/method-overload-address-space.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -emit-llvm -O0 -o - | FileCheck %s +//RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -O0 -o - | FileCheck %s struct C { void foo() __local; diff --git a/clang/test/CodeGenOpenCLCXX/template-address-spaces.cl b/clang/test/CodeGenOpenCLCXX/template-address-spaces.clcpp similarity index 91% rename from clang/test/CodeGenOpenCLCXX/template-address-spaces.cl rename to clang/test/CodeGenOpenCLCXX/template-address-spaces.clcpp index 2142d387d558..d3814204ed99 100644 --- a/clang/test/CodeGenOpenCLCXX/template-address-spaces.cl +++ b/clang/test/CodeGenOpenCLCXX/template-address-spaces.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -cl-std=clc++ %s -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck %s template struct S{ diff --git a/clang/test/CodeGenSYCL/convergent.cpp b/clang/test/CodeGenSYCL/convergent.cpp index 784fb8976c27..58be1b153c93 100644 --- a/clang/test/CodeGenSYCL/convergent.cpp +++ b/clang/test/CodeGenSYCL/convergent.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsycl -fsycl-is-device -emit-llvm -disable-llvm-passes \ +// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -disable-llvm-passes \ // RUN: -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | \ // RUN: FileCheck %s diff --git a/clang/test/CodeGenSYCL/filescope_asm.c b/clang/test/CodeGenSYCL/filescope_asm.c index 5f4f6709a0e1..3c1c12fd589a 100644 --- a/clang/test/CodeGenSYCL/filescope_asm.c +++ b/clang/test/CodeGenSYCL/filescope_asm.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s // // Check that file-scope asm is ignored during device-side SYCL compilation. // diff --git a/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtbeginT.o b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtbeginT.o similarity index 100% rename from clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtbeginT.o rename to clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtbeginT.o diff --git a/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtfastmath.o b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtfastmath.o similarity index 100% rename from clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtfastmath.o rename to clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtfastmath.o diff --git a/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtbegin.o diff --git a/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbeginT.o b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtbeginT.o similarity index 100% rename from clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbeginT.o rename to clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtbeginT.o diff --git a/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtfastmath.o similarity index 100% rename from clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o rename to clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtfastmath.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/.keep b/clang/test/Driver/Inputs/basic_fuchsia_tree/include/c++/v1/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/.keep rename to clang/test/Driver/Inputs/basic_fuchsia_tree/include/c++/v1/.keep diff --git a/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/hwasan+noexcept/libc++.so similarity index 100% rename from clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/hwasan+noexcept/libc++.so diff --git a/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/hwasan/libc++.so similarity index 100% rename from clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/hwasan/libc++.so diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/i386-linux-gnu/libtest.so b/clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/relative-vtables+hwasan+noexcept/libc++.so similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/i386-linux-gnu/libtest.so rename to clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/relative-vtables+hwasan+noexcept/libc++.so diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/mips-linux-gnu/.keep b/clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/relative-vtables+hwasan/libc++.so similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/mips-linux-gnu/.keep rename to clang/test/Driver/Inputs/basic_fuchsia_tree/lib/x86_64-fuchsia/c++/relative-vtables+hwasan/libc++.so diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/i686-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/i686-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mips-linux-gnu/4.5/64/crtbegin.o b/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mips-linux-gnu/4.5/64/crtbegin.o rename to clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mips-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mips-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/mipsel-linux-gnu/.keep b/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbeginT.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/mipsel-linux-gnu/.keep rename to clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbeginT.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/powerpc-linux-gnu/.keep b/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtfastmath.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/powerpc-linux-gnu/.keep rename to clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtfastmath.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/powerpc64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/lib/aarch64-linux-gnu/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/powerpc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/lib/aarch64-linux-gnu/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/powerpc64le-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/lib32/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/powerpc64le-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/lib32/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/sparc-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/lib64/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/sparc-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/lib64/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/sparc64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/include/c++/10/aarch64-linux-gnu/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/lib/sparc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/include/c++/10/aarch64-linux-gnu/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/include/c++/10/backward/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/include/c++/10/backward/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/lib/crt1.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/lib/crt1.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/backward/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/lib/crti.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/backward/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/lib/crti.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/i686-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/lib/crtn.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/i686-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/aarch64-linux-gnu/lib/crtn.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/mips-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/10/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/mips-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/10/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/mipsel-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/10/backward/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/mipsel-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/10/backward/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/powerpc-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnu/c++/10/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/powerpc-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnu/c++/10/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/powerpc64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnu/c++/10/32/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/powerpc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnu/c++/10/32/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/sparc-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/aarch64-linux-gnu/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/sparc-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/aarch64-linux-gnu/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mips-linux-gnu/4.5/n32/crtbegin.o b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc-cross/aarch64-linux-gnu/10/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mips-linux-gnu/4.5/n32/crtbegin.o rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc-cross/aarch64-linux-gnu/10/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/sparc64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc-cross/aarch64-linux-gnu/10/crtbeginT.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/sparc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc-cross/aarch64-linux-gnu/10/crtbeginT.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/x86_64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc-cross/aarch64-linux-gnu/10/crtend.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/x86_64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc-cross/aarch64-linux-gnu/10/crtend.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mipsel-linux-gnu/4.5/64/crtbegin.o b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10/32/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mipsel-linux-gnu/4.5/64/crtbegin.o rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10/32/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mipsel-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mipsel-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/mips-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10/crtend.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/mips-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10/crtend.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/mipsel-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/crt1.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/mipsel-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/crt1.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/powerpc-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/crti.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/powerpc-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/crti.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/powerpc64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/crtn.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/powerpc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/crtn.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/sparc-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/crt1.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/sparc-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/crt1.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/sparc64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/crti.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/sparc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/crti.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/crtn.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/crtn.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib32/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib32/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib64/.keep similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/i386-linux-gnu/.keep rename to clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib64/.keep diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mipsel-linux-gnu/4.5/n32/crtbegin.o b/clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/64/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/mipsel-linux-gnu/4.5/n32/crtbegin.o rename to clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/64/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/powerpc-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/powerpc-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/powerpc64-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/powerpc64-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/sparc-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/sparc-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/sparc64-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/32/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/sparc64-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/32/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.5/crtbegin.o b/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.5/crtbegin.o rename to clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/crtbegin.o diff --git a/clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/64/crtbegin.o b/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/x32/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/64/crtbegin.o rename to clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/x32/crtbegin.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/mips-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabi/crt1.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/mips-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabi/crt1.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/mipsel-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabi/crti.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/mipsel-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabi/crti.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/powerpc-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabi/crtn.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/powerpc-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabi/crtn.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/powerpc64-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabihf/crt1.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/powerpc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabihf/crt1.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/powerpc64le-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabihf/crti.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/powerpc64le-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabihf/crti.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/sparc-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabihf/crtn.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/sparc-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/arm-linux-gnueabihf/crtn.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/sparc64-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabi/crt1.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/sparc64-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabi/crt1.o diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabi/crti.o similarity index 100% rename from clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnu/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabi/crti.o diff --git a/clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabi/crtn.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabi/crtn.o diff --git a/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabihf/crt1.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabihf/crt1.o diff --git a/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabihf/crti.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabihf/crti.o diff --git a/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabihf/crtn.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/armeb-linux-gnueabihf/crtn.o diff --git a/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/32/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/arm-linux-gnueabi/10/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/32/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/arm-linux-gnueabi/10/crtbegin.o diff --git a/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/arm-linux-gnueabihf/10/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/arm-linux-gnueabihf/10/crtbegin.o diff --git a/clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/x32/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/armeb-linux-gnueabi/10/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/x32/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/armeb-linux-gnueabi/10/crtbegin.o diff --git a/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/crtbegin.o b/clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/armeb-linux-gnueabihf/10/crtbegin.o similarity index 100% rename from clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/crtbegin.o rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/lib/gcc/armeb-linux-gnueabihf/10/crtbegin.o diff --git a/clang/test/Driver/Inputs/multilib_armeb_linux_tree/usr/include/armeb-linux-gnueabi/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/usr/include/arm-linux-gnueabihf/.keep similarity index 100% rename from clang/test/Driver/Inputs/multilib_armeb_linux_tree/usr/include/armeb-linux-gnueabi/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/usr/include/arm-linux-gnueabihf/.keep diff --git a/clang/test/Driver/Inputs/multilib_armebhf_linux_tree/usr/include/armeb-linux-gnueabihf/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/usr/include/armeb-linux-gnueabi/.keep similarity index 100% rename from clang/test/Driver/Inputs/multilib_armebhf_linux_tree/usr/include/armeb-linux-gnueabihf/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/usr/include/armeb-linux-gnueabi/.keep diff --git a/clang/test/Driver/Inputs/multilib_armhf_linux_tree/usr/include/arm-linux-gnueabihf/.keep b/clang/test/Driver/Inputs/multilib_arm_linux_tree/usr/include/armeb-linux-gnueabihf/.keep similarity index 100% rename from clang/test/Driver/Inputs/multilib_armhf_linux_tree/usr/include/arm-linux-gnueabihf/.keep rename to clang/test/Driver/Inputs/multilib_arm_linux_tree/usr/include/armeb-linux-gnueabihf/.keep diff --git a/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/lib/x86_64-linux-gnu/.keep b/clang/test/Driver/Inputs/resource_dir/lib/windows/clang_rt.builtins-x86_64.lib similarity index 100% rename from clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/lib/x86_64-linux-gnu/.keep rename to clang/test/Driver/Inputs/resource_dir/lib/windows/clang_rt.builtins-x86_64.lib diff --git a/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/c++/4.7/backward/.keep b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-pc-windows-msvc/clang_rt.builtins.lib similarity index 100% rename from clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/c++/4.7/backward/.keep rename to clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-pc-windows-msvc/clang_rt.builtins.lib diff --git a/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/crtbegin.o b/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/crtbegin.o deleted file mode 100644 index c6cac69265af..000000000000 --- a/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/crtbegin.o +++ /dev/null @@ -1 +0,0 @@ -empty diff --git a/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o b/clang/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/clang/test/Driver/Xlinker-args.c b/clang/test/Driver/Xlinker-args.c index a44957cd8aef..cb045a1d40ac 100644 --- a/clang/test/Driver/Xlinker-args.c +++ b/clang/test/Driver/Xlinker-args.c @@ -17,7 +17,7 @@ // LINUX: "--no-demangle" "-e" "_start" "one" "two" "three" "four" "-z" "five" "-r" {{.*}} "-T" "a.lds" // Check that we forward '-Xlinker' and '-Wl,' on Windows. -// RUN: %clang -target i686-pc-win32 -### \ +// RUN: %clang -target i686-pc-win32 -fuse-ld=link -### \ // RUN: -Xlinker one -Wl,two %s 2>&1 | \ // RUN: FileCheck -check-prefix=WIN %s // WIN: link.exe diff --git a/clang/test/Driver/amdgpu-openmp-toolchain.c b/clang/test/Driver/amdgpu-openmp-toolchain.c index 0645177f00e2..f2350a51817a 100644 --- a/clang/test/Driver/amdgpu-openmp-toolchain.c +++ b/clang/test/Driver/amdgpu-openmp-toolchain.c @@ -1,3 +1,4 @@ +// REQUIRES: x86-registered-target // REQUIRES: amdgpu-registered-target // RUN: env LIBRARY_PATH=%S/Inputs/hip_dev_lib %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 %s 2>&1 \ // RUN: | FileCheck %s @@ -5,7 +6,7 @@ // verify the tools invocations // CHECK: clang{{.*}}"-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-x" "c"{{.*}} // CHECK: clang{{.*}}"-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-x" "ir"{{.*}} -// CHECK: clang{{.*}}"-cc1"{{.*}}"-triple" "amdgcn-amd-amdhsa"{{.*}}"-target-cpu" "gfx906" "-fcuda-is-device" "-emit-llvm-bc" "-mlink-builtin-bitcode"{{.*}}libomptarget-amdgcn-gfx906.bc"{{.*}} +// CHECK: clang{{.*}}"-cc1"{{.*}}"-triple" "amdgcn-amd-amdhsa"{{.*}}"-target-cpu" "gfx906" "-fcuda-is-device" "-mlink-builtin-bitcode"{{.*}}libomptarget-amdgcn-gfx906.bc"{{.*}} // CHECK: llvm-link{{.*}}"-o" "{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-linked-{{.*}}.bc" // CHECK: llc{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-linked-{{.*}}.bc" "-mtriple=amdgcn-amd-amdhsa" "-mcpu=gfx906" "-filetype=obj" "-o"{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-{{.*}}.o" // CHECK: lld{{.*}}"-flavor" "gnu" "--no-undefined" "-shared" "-o"{{.*}}amdgpu-openmp-toolchain-{{.*}}.out" "{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-{{.*}}.o" @@ -25,18 +26,35 @@ // CHECK-PHASES: 6: preprocessor, {5}, cpp-output, (device-openmp) // CHECK-PHASES: 7: compiler, {6}, ir, (device-openmp) // CHECK-PHASES: 8: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (amdgcn-amd-amdhsa)" {7}, ir -// CHECK-PHASES: 9: backend, {8}, assembler, (device-openmp) -// CHECK-PHASES: 10: assembler, {9}, object, (device-openmp) -// CHECK-PHASES: 11: linker, {10}, image, (device-openmp) -// CHECK-PHASES: 12: offload, "device-openmp (amdgcn-amd-amdhsa)" {11}, image -// CHECK-PHASES: 13: clang-offload-wrapper, {12}, ir, (host-openmp) -// CHECK-PHASES: 14: backend, {13}, assembler, (host-openmp) -// CHECK-PHASES: 15: assembler, {14}, object, (host-openmp) -// CHECK-PHASES: 16: linker, {4, 15}, image, (host-openmp) +// CHECK-PHASES: 9: linker, {8}, image, (device-openmp) +// CHECK-PHASES: 10: offload, "device-openmp (amdgcn-amd-amdhsa)" {9}, image +// CHECK-PHASES: 11: clang-offload-wrapper, {10}, ir, (host-openmp) +// CHECK-PHASES: 12: backend, {11}, assembler, (host-openmp) +// CHECK-PHASES: 13: assembler, {12}, object, (host-openmp) +// CHECK-PHASES: 14: linker, {4, 13}, image, (host-openmp) // handling of --libomptarget-amdgcn-bc-path // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 --libomptarget-amdgcn-bc-path=%S/Inputs/hip_dev_lib/libomptarget-amdgcn-gfx803.bc %s 2>&1 | FileCheck %s --check-prefix=CHECK-LIBOMPTARGET -// CHECK-LIBOMPTARGET: clang{{.*}}"-cc1"{{.*}}"-triple" "amdgcn-amd-amdhsa"{{.*}}"-target-cpu" "gfx803" "-fcuda-is-device" "-emit-llvm-bc" "-mlink-builtin-bitcode"{{.*}}Inputs/hip_dev_lib/libomptarget-amdgcn-gfx803.bc"{{.*}} +// CHECK-LIBOMPTARGET: clang{{.*}}"-cc1"{{.*}}"-triple" "amdgcn-amd-amdhsa"{{.*}}"-target-cpu" "gfx803" "-fcuda-is-device" "-mlink-builtin-bitcode"{{.*}}Inputs/hip_dev_lib/libomptarget-amdgcn-gfx803.bc"{{.*}} // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOGPULIB -// CHECK-NOGPULIB-NOT: clang{{.*}}"-cc1"{{.*}}"-triple" "amdgcn-amd-amdhsa"{{.*}}"-target-cpu" "gfx803" "-fcuda-is-device" "-emit-llvm-bc" "-mlink-builtin-bitcode"{{.*}}libomptarget-amdgcn-gfx803.bc"{{.*}} +// CHECK-NOGPULIB-NOT: clang{{.*}}"-cc1"{{.*}}"-triple" "amdgcn-amd-amdhsa"{{.*}}"-target-cpu" "gfx803" "-fcuda-is-device" "-mlink-builtin-bitcode"{{.*}}libomptarget-amdgcn-gfx803.bc"{{.*}} + +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-bindings -save-temps -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-PRINT-BINDINGS +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[INPUT:.*]]"], +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "clang",{{.*}} output: "[[HOST_BC:.*]]" +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[HOST_BC]]"], output: "[[HOST_S:.*]]" +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "clang::as", inputs: ["[[HOST_S]]"], output: "[[HOST_O:.*]]" +// CHECK-PRINT-BINDINGS: "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]"], output: "[[DEVICE_I:.*]]" +// CHECK-PRINT-BINDINGS: "amdgcn-amd-amdhsa" - "clang", inputs: ["[[DEVICE_I]]", "[[HOST_BC]]"], output: "[[DEVICE_BC:.*]]" +// CHECK-PRINT-BINDINGS: "amdgcn-amd-amdhsa" - "AMDGCN::OpenMPLinker", inputs: ["[[DEVICE_BC]]"], output: "[[DEVICE_OUT:.*]]" +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "offload wrapper", inputs: ["[[DEVICE_OUT]]"], output: "[[OFFLOAD_WRAPPER:.*]]" +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[OFFLOAD_WRAPPER]]"], output: "[[OFFLOAD_S:.*]]" +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "clang::as", inputs: ["[[OFFLOAD_S]]"], output: "[[OFFLOAD_O:.*]]" +// CHECK-PRINT-BINDINGS: "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[HOST_O]]", "[[OFFLOAD_O]]"], output: + +// verify the llc is invoked for textual assembly output +// RUN: env LIBRARY_PATH=%S/Inputs/hip_dev_lib %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 -save-temps %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-SAVE-ASM +// CHECK-SAVE-ASM: llc{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-linked.bc" "-mtriple=amdgcn-amd-amdhsa" "-mcpu=gfx906" "-filetype=asm" "-o"{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906.s" +// CHECK-SAVE-ASM: llc{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-linked.bc" "-mtriple=amdgcn-amd-amdhsa" "-mcpu=gfx906" "-filetype=obj" "-o"{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906.o" diff --git a/clang/test/Driver/android-ndk-standalone.cpp b/clang/test/Driver/android-ndk-standalone.cpp index c4d939934782..d070250913b2 100644 --- a/clang/test/Driver/android-ndk-standalone.cpp +++ b/clang/test/Driver/android-ndk-standalone.cpp @@ -3,14 +3,14 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck %s // CHECK: {{.*}}clang{{.*}}" "-cc1" // CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK: "-internal-isystem" "{{.*}}/include/c++/v1" -// CHECK: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// CHECK: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include/arm-linux-androideabi" // CHECK: "-internal-externc-isystem" "{{.*}}/sysroot/include" // CHECK: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include" @@ -34,7 +34,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi14 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-14 %s // CHECK-14: "-L{{.*}}/sysroot/usr/lib/arm-linux-androideabi/14" @@ -42,7 +42,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 -stdlib=libstdc++ \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-STDCXX %s // CHECK-STDCXX: {{.*}}clang{{.*}}" "-cc1" @@ -76,14 +76,14 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target armv7a-none-linux-androideabi21 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7 %s // CHECK-ARMV7: {{.*}}clang{{.*}}" "-cc1" // CHECK-ARMV7: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-ARMV7: "-internal-isystem" "{{.*}}/include/c++/v1" -// CHECK-ARMV7: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK-ARMV7: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// CHECK-ARMV7: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK-ARMV7: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include/arm-linux-androideabi" // CHECK-ARMV7: "-internal-externc-isystem" "{{.*}}/sysroot/include" // CHECK-ARMV7: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include" @@ -109,19 +109,19 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 \ // RUN: -march=armv7 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7 %s // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 \ // RUN: -march=armv7a \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7 %s // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 \ // RUN: -march=armv7-a \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7 %s // @@ -129,14 +129,14 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 \ // RUN: -mthumb \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-THUMB %s // CHECK-THUMB: {{.*}}clang{{.*}}" "-cc1" // CHECK-THUMB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-THUMB: "-internal-isystem" "{{.*}}/include/c++/v1" -// CHECK-THUMB: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK-THUMB: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// CHECK-THUMB: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK-THUMB: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include/arm-linux-androideabi" // CHECK-THUMB: "-internal-externc-isystem" "{{.*}}/sysroot/include" // CHECK-THUMB: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include" @@ -163,14 +163,14 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 \ // RUN: -march=armv7-a -mthumb \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7THUMB %s // CHECK-ARMV7THUMB: {{.*}}clang{{.*}}" "-cc1" // CHECK-ARMV7THUMB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-ARMV7THUMB: "-internal-isystem" "{{.*}}/include/c++/v1" -// CHECK-ARMV7THUMB: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK-ARMV7THUMB: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// CHECK-ARMV7THUMB: "-internal-isystem" "{{.*}}/sysroot/usr/local/include" // CHECK-ARMV7THUMB: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include/arm-linux-androideabi" // CHECK-ARMV7THUMB: "-internal-externc-isystem" "{{.*}}/sysroot/include" // CHECK-ARMV7THUMB: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include" @@ -195,7 +195,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi21 \ // RUN: -march=armv7-a -mthumb \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: -print-multi-lib \ // RUN: | FileCheck --check-prefix=CHECK-ARM-MULTILIBS %s @@ -209,13 +209,13 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target armv7a-none-linux-androideabi21 \ // RUN: -mthumb \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7THUMB %s // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target aarch64-linux-android21 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-AARCH64 %s // CHECK-AARCH64: {{.*}}clang{{.*}}" "-cc1" @@ -231,7 +231,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm64-linux-android21 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARM64 %s // CHECK-ARM64: {{.*}}clang{{.*}}" "-cc1" @@ -248,7 +248,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target mipsel-linux-android21 \ // RUN: -mips32 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-MIPS %s // CHECK-MIPS: {{.*}}clang{{.*}}" "-cc1" @@ -263,7 +263,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target i686-linux-android21 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-I686 %s // CHECK-I686: {{.*}}clang{{.*}}" "-cc1" @@ -279,7 +279,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-linux-android21 \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-X86_64 %s // CHECK-X86_64: {{.*}}clang{{.*}}" "-cc1" diff --git a/clang/test/Driver/android-standalone.cpp b/clang/test/Driver/android-standalone.cpp index 0f8cf0b1355e..c238fc734716 100644 --- a/clang/test/Driver/android-standalone.cpp +++ b/clang/test/Driver/android-standalone.cpp @@ -3,7 +3,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi -stdlib=libstdc++ \ -// RUN: -B%S/Inputs/basic_android_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_tree \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck %s // CHECK: {{.*}}clang{{.*}}" "-cc1" @@ -18,7 +18,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target aarch64-linux-android -stdlib=libstdc++ \ -// RUN: -B%S/Inputs/basic_android_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_tree \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-AARCH64 %s // CHECK-AARCH64: {{.*}}clang{{.*}}" "-cc1" @@ -33,7 +33,7 @@ // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm64-linux-android -stdlib=libstdc++ \ -// RUN: -B%S/Inputs/basic_android_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_tree \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ARM64 %s // CHECK-ARM64: {{.*}}clang{{.*}}" "-cc1" @@ -49,7 +49,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target mipsel-linux-android \ // RUN: -mips32 -stdlib=libstdc++ \ -// RUN: -B%S/Inputs/basic_android_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_tree \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-MIPS %s // CHECK-MIPS: {{.*}}clang{{.*}}" "-cc1" @@ -65,7 +65,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target mipsel-linux-android \ // RUN: -march=mips32 -mips32r2 -stdlib=libstdc++ \ -// RUN: -B%S/Inputs/basic_android_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_tree \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-MIPSR2 %s // CHECK-MIPSR2: {{.*}}clang{{.*}}" "-cc1" @@ -81,7 +81,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target mipsel-linux-android \ // RUN: -mips32 -march=mips32r2 -stdlib=libstdc++ \ -// RUN: -B%S/Inputs/basic_android_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_tree \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-MIPSR2-A %s // CHECK-MIPSR2-A: {{.*}}clang{{.*}}" "-cc1" diff --git a/clang/test/Driver/arm-multilibs.c b/clang/test/Driver/arm-multilibs.c index bd9c80e8b16a..3ec9ea0b97c5 100644 --- a/clang/test/Driver/arm-multilibs.c +++ b/clang/test/Driver/arm-multilibs.c @@ -1,14 +1,14 @@ -// RUN: %clang -target armv7-linux-gnueabi --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARM %s -// RUN: %clang -target thumbv7-linux-gnueabi --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARM %s +// RUN: %clang --target=armv7-linux-gnueabi --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s +// RUN: %clang --target=thumbv7-linux-gnueabi --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s -// RUN: %clang -target armv7-linux-gnueabihf --sysroot=%S/Inputs/multilib_armhf_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARMHF %s -// RUN: %clang -target thumbv7-linux-gnueabihf --sysroot=%S/Inputs/multilib_armhf_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARMHF %s +// RUN: %clang --target=armv7-linux-gnueabihf --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARMHF %s +// RUN: %clang --target=thumbv7-linux-gnueabihf --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARMHF %s -// RUN: %clang -target armv7eb-linux-gnueabi --sysroot=%S/Inputs/multilib_armeb_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARMEB %s -// RUN: %clang -target thumbv7eb-linux-gnueabi --sysroot=%S/Inputs/multilib_armeb_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARMEB %s +// RUN: %clang --target=armv7eb-linux-gnueabi --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARMEB %s +// RUN: %clang --target=thumbv7eb-linux-gnueabi --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARMEB %s -// RUN: %clang -target armv7eb-linux-gnueabihf --sysroot=%S/Inputs/multilib_armebhf_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARMEBHF %s -// RUN: %clang -target thumbv7eb-linux-gnueabihf --sysroot=%S/Inputs/multilib_armebhf_linux_tree -### -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ARMEBHF %s +// RUN: %clang --target=armv7eb-linux-gnueabihf --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARMEBHF %s +// RUN: %clang --target=thumbv7eb-linux-gnueabihf --sysroot=%S/Inputs/multilib_arm_linux_tree -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARMEBHF %s // CHECK-ARM: "-internal-externc-isystem" "{{.*}}/usr/include/arm-linux-gnueabi" // CHECK-ARMHF: "-internal-externc-isystem" "{{.*}}/usr/include/arm-linux-gnueabihf" diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp index 7bbdbac66754..bca9f7e53f68 100644 --- a/clang/test/Driver/baremetal.cpp +++ b/clang/test/Driver/baremetal.cpp @@ -33,8 +33,9 @@ // RUN: -target armv6m-none-eabi \ // RUN: --sysroot=%S/Inputs/baremetal_arm \ // RUN: | FileCheck --check-prefix=CHECK-V6M-DEFAULTCXX %s +// CHECK-V6M-DEFAULTCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-V6M-DEFAULTCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-V6M-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-V6M-DEFAULTCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-V6M-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}baremetal_arm{{[/\\]+}}lib" // CHECK-V6M-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind" // CHECK-V6M-DEFAULTCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m" @@ -45,10 +46,11 @@ // RUN: --sysroot=%S/Inputs/baremetal_arm \ // RUN: -stdlib=libc++ \ // RUN: | FileCheck --check-prefix=CHECK-V6M-LIBCXX %s +// CHECK-V6M-LIBCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-V6M-LIBCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}{{[^v].*}}" -// CHECK-V6M-LIBCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECK-V6M-LIBCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" // CHECK-V6M-LIBCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-V6M-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-V6M-LIBCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-V6M-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}baremetal_arm{{[/\\]+}}lib" // CHECK-V6M-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind" // CHECK-V6M-LIBCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m" @@ -59,10 +61,11 @@ // RUN: --sysroot=%S/Inputs/baremetal_arm \ // RUN: -stdlib=libstdc++ \ // RUN: | FileCheck --check-prefix=CHECK-V6M-LIBSTDCXX %s +// CHECK-V6M-LIBSTDCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-V6M-LIBSTDCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" -// CHECK-V6M-LIBSTDCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}6.0.0" +// CHECK-V6M-LIBSTDCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}6.0.0" // CHECK-V6M-LIBSTDCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-V6M-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-V6M-LIBSTDCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-V6M-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}baremetal_arm{{[/\\]+}}lib" // CHECK-V6M-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind" // CHECK-V6M-LIBSTDCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m" @@ -73,8 +76,9 @@ // RUN: --sysroot=%S/Inputs/baremetal_arm \ // RUN: -nodefaultlibs \ // RUN: | FileCheck --check-prefix=CHECK-V6M-NDL %s +// CHECK-V6M-NDL: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-V6M-NDL: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-V6M-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-V6M-NDL-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-V6M-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}baremetal_arm{{[/\\]+}}lib" "-o" "{{.*}}.o" // RUN: %clangxx -target arm-none-eabi -v 2>&1 \ @@ -119,8 +123,9 @@ // RUN: -target riscv64-unknown-elf \ // RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ // RUN: | FileCheck --check-prefix=CHECK-RV64-DEFAULTCXX %s +// CHECK-RV64-DEFAULTCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV64-DEFAULTCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-RV64-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-RV64-DEFAULTCXX-SAME: "-L[[RESOURCE_DIR]]{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV64-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" // CHECK-RV64-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind" // CHECK-RV64-DEFAULTCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-riscv64" @@ -131,10 +136,11 @@ // RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ // RUN: -stdlib=libc++ \ // RUN: | FileCheck --check-prefix=CHECK-RV64-LIBCXX %s +// CHECK-RV64-LIBCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV64-LIBCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}{{[^v].*}}" -// CHECK-RV64-LIBCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECK-RV64-LIBCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" // CHECK-RV64-LIBCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-RV64-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-RV64-LIBCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV64-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" // CHECK-RV64-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind" // CHECK-RV64-LIBCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-riscv64" @@ -145,10 +151,11 @@ // RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ // RUN: -stdlib=libstdc++ \ // RUN: | FileCheck --check-prefix=CHECK-RV64-LIBSTDCXX %s +// CHECK-RV64-LIBSTDCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV64-LIBSTDCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" -// CHECK-RV64-LIBSTDCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}8.0.1" +// CHECK-RV64-LIBSTDCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}8.0.1" // CHECK-RV64-LIBSTDCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-RV64-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-RV64-LIBSTDCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV64-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" // CHECK-RV64-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind" // CHECK-RV64-LIBSTDCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-riscv64" @@ -176,8 +183,9 @@ // RUN: -target riscv32-unknown-elf \ // RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ // RUN: | FileCheck --check-prefix=CHECK-RV32-DEFAULTCXX %s +// CHECK-RV32-DEFAULTCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV32-DEFAULTCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-RV32-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-RV32-DEFAULTCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV32-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv32_tree{{[/\\]+}}riscv32-unknown-elf{{[/\\]+}}lib" // CHECK-RV32-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind" // CHECK-RV32-DEFAULTCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-riscv32" @@ -188,10 +196,11 @@ // RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ // RUN: -stdlib=libc++ \ // RUN: | FileCheck --check-prefix=CHECK-RV32-LIBCXX %s +// CHECK-RV32-LIBCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV32-LIBCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}{{[^v].*}}" -// CHECK-RV32-LIBCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECK-RV32-LIBCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" // CHECK-RV32-LIBCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-RV32-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-RV32-LIBCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV32-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv32_tree{{[/\\]+}}riscv32-unknown-elf{{[/\\]+}}lib" // CHECK-RV32-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind" // CHECK-RV32-LIBCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-riscv32" @@ -202,10 +211,11 @@ // RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ // RUN: -stdlib=libstdc++ \ // RUN: | FileCheck --check-prefix=CHECK-RV32-LIBSTDCXX %s +// CHECK-RV32-LIBSTDCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV32-LIBSTDCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" -// CHECK-RV32-LIBSTDCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}8.0.1" +// CHECK-RV32-LIBSTDCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}8.0.1" // CHECK-RV32-LIBSTDCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-RV32-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-RV32-LIBSTDCXX-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV32-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv32_tree{{[/\\]+}}riscv32-unknown-elf{{[/\\]+}}lib" // CHECK-RV32-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind" // CHECK-RV32-LIBSTDCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-riscv32" @@ -229,8 +239,9 @@ // RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ // RUN: -nodefaultlibs \ // RUN: | FileCheck --check-prefix=CHECK-RV64-NDL %s +// CHECK-RV64-NDL: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV64-NDL: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" -// CHECK-RV64-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" +// CHECK-RV64-NDL-SAME: "-L[[RESOURCE_DIR]]{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV64-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" // CHECK-RV64-NDL-SAME: "-o" "{{.*}}.o" diff --git a/clang/test/Driver/cl-inputs.c b/clang/test/Driver/cl-inputs.c index 59455a0aa5e5..8eb44517ee16 100644 --- a/clang/test/Driver/cl-inputs.c +++ b/clang/test/Driver/cl-inputs.c @@ -50,16 +50,16 @@ // RUN: %clang_cl -### /Tc - 2>&1 | FileCheck -check-prefix=STDINTc %s // STDINTc: "-x" "c" -// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -### -- %s cl-test.lib 2>&1 | FileCheck -check-prefix=LIBINPUT %s +// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -fuse-ld=link -### -- %s cl-test.lib 2>&1 | FileCheck -check-prefix=LIBINPUT %s // LIBINPUT: link.exe" // LIBINPUT: "cl-test.lib" -// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -### -- %s cl-test2.lib 2>&1 | FileCheck -check-prefix=LIBINPUT2 %s +// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -fuse-ld=link -### -- %s cl-test2.lib 2>&1 | FileCheck -check-prefix=LIBINPUT2 %s // LIBINPUT2: error: no such file or directory: 'cl-test2.lib' // LIBINPUT2: link.exe" // LIBINPUT2-NOT: "cl-test2.lib" -// RUN: %clang_cl -### -- %s /nonexisting.lib 2>&1 | FileCheck -check-prefix=LIBINPUT3 %s +// RUN: %clang_cl -fuse-ld=link -### -- %s /nonexisting.lib 2>&1 | FileCheck -check-prefix=LIBINPUT3 %s // LIBINPUT3: error: no such file or directory: '/nonexisting.lib' // LIBINPUT3: link.exe" // LIBINPUT3-NOT: "/nonexisting.lib" diff --git a/clang/test/Driver/cl-link-at-file.c b/clang/test/Driver/cl-link-at-file.c index 50ae07fadf5b..4e665f89b74e 100644 --- a/clang/test/Driver/cl-link-at-file.c +++ b/clang/test/Driver/cl-link-at-file.c @@ -7,7 +7,7 @@ // RUN: echo /link bar.lib baz.lib > %t.args // RUN: touch %t.obj -// RUN: %clang_cl -### @%t.args -- %t.obj 2>&1 | FileCheck %s -check-prefix=ARGS +// RUN: %clang_cl -fuse-ld=link -### @%t.args -- %t.obj 2>&1 | FileCheck %s -check-prefix=ARGS // If the "/link" option captures all remaining args beyond its response file, // it will also capture "--" and our input argument. In this case, Clang will // be clueless and will emit "argument unused" warnings. If PR17239 is properly diff --git a/clang/test/Driver/cl-link.c b/clang/test/Driver/cl-link.c index 142725fed8eb..e2f5397e9133 100644 --- a/clang/test/Driver/cl-link.c +++ b/clang/test/Driver/cl-link.c @@ -2,14 +2,14 @@ // be interpreted as a command-line option, e.g. on Mac where %s is commonly // under /Users. -// RUN: %clang_cl /Tc%s -### /link foo bar baz 2>&1 | FileCheck --check-prefix=LINK %s -// RUN: %clang_cl /Tc%s -### /linkfoo bar baz 2>&1 | FileCheck --check-prefix=LINK %s +// RUN: %clang_cl /Tc%s -fuse-ld=link -### /link foo bar baz 2>&1 | FileCheck --check-prefix=LINK %s +// RUN: %clang_cl /Tc%s -fuse-ld=link -### /linkfoo bar baz 2>&1 | FileCheck --check-prefix=LINK %s // LINK: link.exe // LINK: "foo" // LINK: "bar" // LINK: "baz" -// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN %s +// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /Tc%s -fuse-ld=link -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN %s // ASAN: link.exe // ASAN: "-debug" // ASAN: "-incremental:no" @@ -19,7 +19,7 @@ // ASAN: "-wholearchive:{{.*}}clang_rt.asan_cxx-i386.lib" // ASAN: "{{.*}}cl-link{{.*}}.obj" -// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /MD /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-MD %s +// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /MD /Tc%s -fuse-ld=link -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-MD %s // ASAN-MD: link.exe // ASAN-MD: "-debug" // ASAN-MD: "-incremental:no" @@ -29,13 +29,13 @@ // ASAN-MD: "-wholearchive:{{.*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib" // ASAN-MD: "{{.*}}cl-link{{.*}}.obj" -// RUN: %clang_cl /LD -### /Tc%s 2>&1 | FileCheck --check-prefix=DLL %s -// RUN: %clang_cl /LDd -### /Tc%s 2>&1 | FileCheck --check-prefix=DLL %s +// RUN: %clang_cl /LD -fuse-ld=link -### /Tc%s 2>&1 | FileCheck --check-prefix=DLL %s +// RUN: %clang_cl /LDd -fuse-ld=link -### /Tc%s 2>&1 | FileCheck --check-prefix=DLL %s // DLL: link.exe // "-dll" -// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /LD /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s -// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /LDd /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s +// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /LD /Tc%s -fuse-ld=link -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s +// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /LDd /Tc%s -fuse-ld=link -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s // ASAN-DLL: link.exe // ASAN-DLL: "-dll" // ASAN-DLL: "-debug" @@ -43,13 +43,13 @@ // ASAN-DLL: "{{.*}}clang_rt.asan_dll_thunk-i386.lib" // ASAN-DLL: "{{.*}}cl-link{{.*}}.obj" -// RUN: %clang_cl /Zi /Tc%s -### 2>&1 | FileCheck --check-prefix=DEBUG %s +// RUN: %clang_cl /Zi /Tc%s -fuse-ld=link -### 2>&1 | FileCheck --check-prefix=DEBUG %s // DEBUG: link.exe // DEBUG: "-debug" // PR27234 -// RUN: %clang_cl /Tc%s nonexistent.obj -### /link /libpath:somepath 2>&1 | FileCheck --check-prefix=NONEXISTENT %s -// RUN: %clang_cl /Tc%s nonexistent.lib -### /link /libpath:somepath 2>&1 | FileCheck --check-prefix=NONEXISTENT %s +// RUN: %clang_cl /Tc%s nonexistent.obj -fuse-ld=link -### /link /libpath:somepath 2>&1 | FileCheck --check-prefix=NONEXISTENT %s +// RUN: %clang_cl /Tc%s nonexistent.lib -fuse-ld=link -### /link /libpath:somepath 2>&1 | FileCheck --check-prefix=NONEXISTENT %s // NONEXISTENT-NOT: no such file // NONEXISTENT: link.exe // NONEXISTENT: "/libpath:somepath" diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 7d83b3d60b1e..77427f9daa95 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -118,7 +118,8 @@ // RUN: %clang_cl /imsvcmyincludedir -### -- %s 2>&1 | FileCheck -check-prefix=SLASH_imsvc %s // RUN: %clang_cl /imsvc myincludedir -### -- %s 2>&1 | FileCheck -check-prefix=SLASH_imsvc %s // Clang's resource header directory should be first: -// SLASH_imsvc: "-internal-isystem" "{{[^"]*}}lib{{(64)?/|\\\\}}clang{{[^"]*}}include" +// SLASH_imsvc: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// SLASH_imsvc: "-internal-isystem" "[[RESOURCE_DIR]]{{[/\\]+}}include" // SLASH_imsvc: "-internal-isystem" "myincludedir" // RUN: %clang_cl /J -### -- %s 2>&1 | FileCheck -check-prefix=J %s @@ -643,6 +644,7 @@ // RUN: -fno-diagnostics-color \ // RUN: -fdebug-compilation-dir . \ // RUN: -fdebug-compilation-dir=. \ +// RUN: -ffile-compilation-dir=. \ // RUN: -fdiagnostics-parseable-fixits \ // RUN: -fdiagnostics-absolute-paths \ // RUN: -ferror-limit=10 \ diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index b383579f1079..12369361f811 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -3,7 +3,7 @@ // RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fsplit-stack %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s // RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s -// CHECK-OPTIONS1: -split-stacks +// CHECK-OPTIONS1: -fsplit-stack // CHECK-OPTIONS1: -fgnu-keywords // CHECK-OPTIONS1: -fblocks // CHECK-OPTIONS1: -fpascal-strings diff --git a/clang/test/Driver/cross-linux.c b/clang/test/Driver/cross-linux.c index 6c2dab260695..da0952b3f2d4 100644 --- a/clang/test/Driver/cross-linux.c +++ b/clang/test/Driver/cross-linux.c @@ -3,24 +3,24 @@ // RUN: --target=i386-unknown-linux-gnu \ // RUN: | FileCheck --check-prefix=CHECK-I386 %s // CHECK-I386: "-cc1" "-triple" "i386-unknown-linux-gnu" -// CHECK-I386: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/4.6.0/../../../../i386-unknown-linux-gnu/bin{{/|\\\\}}as" "--32" -// CHECK-I386: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/4.6.0/../../../../i386-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_i386" +// CHECK-I386: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/10.2.0/../../../../i386-unknown-linux-gnu/bin{{/|\\\\}}as" "--32" +// CHECK-I386: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/10.2.0/../../../../i386-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_i386" // // RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \ // RUN: --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \ // RUN: --target=x86_64-unknown-linux-gnu \ // RUN: | FileCheck --check-prefix=CHECK-X86-64 %s // CHECK-X86-64: "-cc1" "-triple" "x86_64-unknown-linux-gnu" -// CHECK-X86-64: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}as" "--64" -// CHECK-X86-64: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_x86_64" +// CHECK-X86-64: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}as" "--64" +// CHECK-X86-64: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_x86_64" // // RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \ // RUN: --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \ // RUN: --target=x86_64-unknown-linux-gnux32 \ // RUN: | FileCheck --check-prefix=CHECK-X32 %s // CHECK-X32: "-cc1" "-triple" "x86_64-unknown-linux-gnux32" -// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}as" "--x32" -// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf32_x86_64" +// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}as" "--x32" +// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf32_x86_64" // // RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \ // RUN: --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \ @@ -38,11 +38,11 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-MULTI32-I386 %s // CHECK-MULTI32-I386: "-cc1" "-triple" "i386-unknown-linux" -// CHECK-MULTI32-I386: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/bin{{/|\\\\}}as" "--32" -// CHECK-MULTI32-I386: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/bin{{/|\\\\}}ld" +// CHECK-MULTI32-I386: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/bin{{/|\\\\}}as" "--32" +// CHECK-MULTI32-I386: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/bin{{/|\\\\}}ld" // CHECK-MULTI32-I386: "--sysroot=[[sysroot:.*/Inputs/basic_linux_tree]]" // CHECK-MULTI32-I386: "-m" "elf_i386" -// CHECK-MULTI32-I386: "crti.o" "[[gcc_install:.*/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0]]{{/|\\\\}}crtbegin.o" +// CHECK-MULTI32-I386: "crti.o" "[[gcc_install:.*/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0]]{{/|\\\\}}crtbegin.o" // CHECK-MULTI32-I386: "-L[[gcc_install]]" // CHECK-MULTI32-I386: "-L[[gcc_install]]/../../../../i386-unknown-linux/lib/../lib32" // CHECK-MULTI32-I386: "-L[[gcc_install]]/../../../../i386-unknown-linux/lib" @@ -56,14 +56,13 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-MULTI32-X86-64 %s // CHECK-MULTI32-X86-64: "-cc1" "-triple" "x86_64-unknown-linux" -// CHECK-MULTI32-X86-64: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/bin{{/|\\\\}}as" "--64" -// CHECK-MULTI32-X86-64: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/bin{{/|\\\\}}ld" +// CHECK-MULTI32-X86-64: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/bin{{/|\\\\}}as" "--64" +// CHECK-MULTI32-X86-64: "{{.*}}/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/bin{{/|\\\\}}ld" // CHECK-MULTI32-X86-64: "--sysroot=[[sysroot:.*/Inputs/basic_linux_tree]]" // CHECK-MULTI32-X86-64: "-m" "elf_x86_64" -// CHECK-MULTI32-X86-64: "crti.o" "[[gcc_install:.*/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0]]/64{{/|\\\\}}crtbegin.o" +// CHECK-MULTI32-X86-64: "crti.o" "[[gcc_install:.*/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0]]/64{{/|\\\\}}crtbegin.o" // CHECK-MULTI32-X86-64: "-L[[gcc_install]]/64" // CHECK-MULTI32-X86-64: "-L[[gcc_install]]/../../../../i386-unknown-linux/lib/../lib64" -// CHECK-MULTI32-X86-64: "-L[[gcc_install]]" // CHECK-MULTI32-X86-64: "-L[[gcc_install]]/../../../../i386-unknown-linux/lib" // CHECK-MULTI32-X86-64: "-L[[sysroot]]/lib" // CHECK-MULTI32-X86-64: "-L[[sysroot]]/usr/lib" @@ -75,14 +74,13 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-MULTI64-I386 %s // CHECK-MULTI64-I386: "-cc1" "-triple" "i386-unknown-linux" -// CHECK-MULTI64-I386: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}as" "--32" -// CHECK-MULTI64-I386: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}ld" +// CHECK-MULTI64-I386: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}as" "--32" +// CHECK-MULTI64-I386: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}ld" // CHECK-MULTI64-I386: "--sysroot=[[sysroot:.*/Inputs/basic_linux_tree]]" // CHECK-MULTI64-I386: "-m" "elf_i386" -// CHECK-MULTI64-I386: "crti.o" "[[gcc_install:.*/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0]]/32{{/|\\\\}}crtbegin.o" +// CHECK-MULTI64-I386: "crti.o" "[[gcc_install:.*/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0]]/32{{/|\\\\}}crtbegin.o" // CHECK-MULTI64-I386: "-L[[gcc_install]]/32" // CHECK-MULTI64-I386: "-L[[gcc_install]]/../../../../x86_64-unknown-linux/lib/../lib32" -// CHECK-MULTI64-I386: "-L[[gcc_install]]" // CHECK-MULTI64-I386: "-L[[gcc_install]]/../../../../x86_64-unknown-linux/lib" // CHECK-MULTI64-I386: "-L[[sysroot]]/lib" // CHECK-MULTI64-I386: "-L[[sysroot]]/usr/lib" @@ -94,11 +92,11 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-MULTI64-X86-64 %s // CHECK-MULTI64-X86-64: "-cc1" "-triple" "x86_64-unknown-linux" -// CHECK-MULTI64-X86-64: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}as" "--64" -// CHECK-MULTI64-X86-64: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}ld" +// CHECK-MULTI64-X86-64: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}as" "--64" +// CHECK-MULTI64-X86-64: "{{.*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/bin{{/|\\\\}}ld" // CHECK-MULTI64-X86-64: "--sysroot=[[sysroot:.*/Inputs/basic_linux_tree]]" // CHECK-MULTI64-X86-64: "-m" "elf_x86_64" -// CHECK-MULTI64-X86-64: "crti.o" "[[gcc_install:.*/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0]]{{/|\\\\}}crtbegin.o" +// CHECK-MULTI64-X86-64: "crti.o" "[[gcc_install:.*/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0]]{{/|\\\\}}crtbegin.o" // CHECK-MULTI64-X86-64: "-L[[gcc_install]]" // CHECK-MULTI64-X86-64: "-L[[gcc_install]]/../../../../x86_64-unknown-linux/lib/../lib64" // CHECK-MULTI64-X86-64: "-L[[gcc_install]]/../../../../x86_64-unknown-linux/lib" diff --git a/clang/test/Driver/cxx_for_opencl.clcpp b/clang/test/Driver/cxx_for_opencl.clcpp new file mode 100644 index 000000000000..e3e89c53b888 --- /dev/null +++ b/clang/test/Driver/cxx_for_opencl.clcpp @@ -0,0 +1,18 @@ +// RUN: %clang %s -Xclang -verify -fsyntax-only +// RUN: %clang %s -cl-std=clc++ -Xclang -verify -fsyntax-only +// RUN: %clang %s -cl-std=cl2.0 -Xclang -verify -fsyntax-only +// RUN: %clang %s -### 2>&1 | FileCheck %s + +// CHECK: "-x" "clcpp" + +#ifdef __OPENCL_CPP_VERSION__ +//expected-no-diagnostics +#endif + +kernel void k(){ + auto a = get_local_id(1); +#ifndef __OPENCL_CPP_VERSION__ +//expected-error@-2{{OpenCL C version 2.0 does not support the 'auto' storage class specifier}} +//expected-warning@-3{{type specifier missing, defaults to 'int'}} +#endif +} diff --git a/clang/test/Driver/darwin-ld-lto.c b/clang/test/Driver/darwin-ld-lto.c index 05e6bccd00f0..252ca148c520 100644 --- a/clang/test/Driver/darwin-ld-lto.c +++ b/clang/test/Driver/darwin-ld-lto.c @@ -30,3 +30,11 @@ // THIN_LTO_OBJECT_PATH: {{ld(.exe)?"}} // THIN_LTO_OBJECT_PATH-SAME: "-object_path_lto" // THIN_LTO_OBJECT_PATH-SAME: {{thinlto\-[a-zA-Z0-9_]+}} + + +// Check that we pass through -fglobal-isel flags to libLTO. +// RUN: %clang -target arm64-apple-darwin %s -flto -fglobal-isel -### 2>&1 | \ +// RUN: FileCheck --check-prefix=GISEL %s +// GISEL: {{ld(.exe)?"}} +// GISEL: "-mllvm" "-global-isel" +// GISEL: "-mllvm" "-global-isel-abort=0" diff --git a/clang/test/Driver/darwin-sdk-with-prefix.c b/clang/test/Driver/darwin-sdk-with-prefix.c new file mode 100644 index 000000000000..7619ded56b65 --- /dev/null +++ b/clang/test/Driver/darwin-sdk-with-prefix.c @@ -0,0 +1,10 @@ +// RUN: rm -rf %t.dir +// RUN: mkdir -p %t.dir + +// RUN: rm -rf %t.dir/prefix.iPhoneOS12.0.0.sdk +// RUN: mkdir -p %t.dir/prefix.iPhoneOS12.0.0.sdk +// RUN: %clang -c -isysroot %t.dir/prefix.iPhoneOS12.0.0.sdk -target arm64-apple-darwin %s -### 2>&1 | FileCheck %s +// RUN: env SDKROOT=%t.dir/prefix.iPhoneOS12.0.0.sdk %clang -c -target arm64-apple-darwin %s -### 2>&1 | FileCheck %s +// +// CHECK-NOT: warning: using sysroot for +// CHECK: "-triple" "arm64-apple-ios12.0.0" diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c index 315ce6c58008..d46ca8dd0726 100644 --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -18,6 +18,8 @@ // RUN: | FileCheck -check-prefix=G_STANDALONE -check-prefix=G_LLDB %s // RUN: %clang -### -c -gsce %s -target x86_64-linux-gnu 2>&1 \ // RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_SCE %s +// RUN: %clang -### -c -gdbx %s -target x86_64-linux-gnu 2>&1 \ +// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_DBX %s // Android. // Android should always generate DWARF4. @@ -102,6 +104,12 @@ // RUN: %clang -### -c %s -gsce -target x86_64-unknown-linux 2>&1 \ // RUN: | FileCheck -check-prefix=NOCI %s +// On the AIX, -g defaults to -gdbx and limited debug info. +// RUN: %clang -### -c -g %s -target powerpc-ibm-aix-xcoff 2>&1 \ +// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_DBX %s +// RUN: %clang -### -c -g %s -target powerpc64-ibm-aix-xcoff 2>&1 \ +// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_DBX %s + // RUN: %clang -### -c -gdwarf-2 %s 2>&1 \ // RUN: | FileCheck -check-prefix=G_ONLY_DWARF2 %s // @@ -294,6 +302,7 @@ // G_GDB: "-debugger-tuning=gdb" // G_LLDB: "-debugger-tuning=lldb" // G_SCE: "-debugger-tuning=sce" +// G_DBX: "-debugger-tuning=dbx" // // G_NOTUNING: "-cc1" // G_NOTUNING-NOT: "-debugger-tuning=" diff --git a/clang/test/Driver/env.c b/clang/test/Driver/env.c index 0371bc91c4a3..b96c831fc149 100644 --- a/clang/test/Driver/env.c +++ b/clang/test/Driver/env.c @@ -20,9 +20,8 @@ // // CHECK-LD-32-NOT: warning: // CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-LD-32: "{{.*}}/usr/lib/gcc/i386-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0" -// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib" -// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../.." +// CHECK-LD-32: "{{.*}}/usr/lib/gcc/i386-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0" +// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/lib" // CHECK-LD-32: "-L[[SYSROOT]]/lib" // CHECK-LD-32: "-L[[SYSROOT]]/usr/lib" diff --git a/clang/test/Driver/fdirect-access-external-data.c b/clang/test/Driver/fdirect-access-external-data.c index c3fc93064179..f132b1b088af 100644 --- a/clang/test/Driver/fdirect-access-external-data.c +++ b/clang/test/Driver/fdirect-access-external-data.c @@ -9,10 +9,6 @@ // RUN: %clang -### -c -target aarch64 %s -fpic 2>&1 | FileCheck %s --check-prefix=DEFAULT // RUN: %clang -### -c -target aarch64 %s -fpic -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT -/// -m[no-]pie-copy-relocations are aliases for compatibility. -// RUN: %clang -### -c -target riscv64 %s -mno-pie-copy-relocations 2>&1 | FileCheck %s --check-prefix=INDIRECT -// RUN: %clang -### -c -target riscv64 %s -fpic -mpie-copy-relocations 2>&1 | FileCheck %s --check-prefix=DIRECT - // DEFAULT-NOT: direct-access-external-data" // DIRECT: "-fdirect-access-external-data" // INDIRECT: "-fno-direct-access-external-data" diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c index 5ac262c1a46d..da7370a4d87a 100644 --- a/clang/test/Driver/fpatchable-function-entry.c +++ b/clang/test/Driver/fpatchable-function-entry.c @@ -2,6 +2,8 @@ // RUN: %clang -target x86_64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s // RUN: %clang -target aarch64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s // RUN: %clang -target aarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang -target riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s // CHECK: "-fpatchable-function-entry=1" // RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=1,1 -c -### 2>&1 | FileCheck --check-prefix=11 %s diff --git a/clang/test/Driver/fuchsia.cpp b/clang/test/Driver/fuchsia.cpp index 6b288170a1fc..9177f48fc9e2 100644 --- a/clang/test/Driver/fuchsia.cpp +++ b/clang/test/Driver/fuchsia.cpp @@ -121,6 +121,26 @@ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: -fuse-ld=lld 2>&1\ // RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86 +// RUN: %clangxx %s -### --target=x86_64-fuchsia -fsanitize=hwaddress \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: -fuse-ld=lld 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-HWASAN-X86 +// RUN: %clangxx %s -### --target=x86_64-fuchsia -fsanitize=hwaddress -fno-exceptions \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: -fuse-ld=lld 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-HWASAN-NOEXCEPT-X86 +// RUN: %clangxx %s -### --target=x86_64-fuchsia -fexperimental-relative-c++-abi-vtables -fsanitize=hwaddress \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: -fuse-ld=lld 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-RELATIVE-VTABLES-HWASAN-X86 +// RUN: %clangxx %s -### --target=x86_64-fuchsia -fexperimental-relative-c++-abi-vtables -fno-exceptions -fsanitize=hwaddress \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: -fuse-ld=lld 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-RELATIVE-VTABLES-HWASAN-NOEXCEPT-X86 // CHECK-MULTILIB-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-MULTILIB-ASAN-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}asan" // CHECK-MULTILIB-NOEXCEPT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}noexcept" @@ -129,4 +149,8 @@ // CHECK-MULTILIB-RELATIVE-VTABLES-NOEXCEPT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}relative-vtables+noexcept" // CHECK-MULTILIB-RELATIVE-VTABLES-ASAN-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}relative-vtables+asan" // CHECK-MULTILIB-RELATIVE-VTABLES-ASAN-NOEXCEPT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}relative-vtables+asan+noexcept" +// CHECK-MULTILIB-HWASAN-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}hwasan" +// CHECK-MULTILIB-HWASAN-NOEXCEPT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}hwasan+noexcept" +// CHECK-MULTILIB-RELATIVE-VTABLES-HWASAN-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}relative-vtables+hwasan" +// CHECK-MULTILIB-RELATIVE-VTABLES-HWASAN-NOEXCEPT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}relative-vtables+hwasan+noexcept" // CHECK-MULTILIB-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++" diff --git a/clang/test/Driver/gcc-toolchain.cpp b/clang/test/Driver/gcc-toolchain.cpp index 6c872f4255c3..7cdba0841b8c 100644 --- a/clang/test/Driver/gcc-toolchain.cpp +++ b/clang/test/Driver/gcc-toolchain.cpp @@ -1,31 +1,39 @@ // Test that gcc-toolchain option is working correctly // -// RUN: %clangxx -no-canonical-prefixes %s -### -o %t 2>&1 \ -// RUN: --target=i386-unknown-linux -stdlib=libstdc++ \ -// RUN: --gcc-toolchain=%S/Inputs/ubuntu_11.04_multiarch_tree/usr \ -// RUN: --sysroot="" \ -// RUN: | FileCheck %s +/// Without --rtlib=libgcc the driver may pick clang_rt.crtbegin.o if +/// -DCLANG_DEFAULT_RTLIB=compiler-rt. +// RUN: %clangxx %s -### --target=x86_64-linux-gnu --sysroot= \ +// RUN: --gcc-toolchain=%S/Inputs/ubuntu_14.04_multiarch_tree/usr -stdlib=libstdc++ --rtlib=libgcc 2>&1 | \ +// RUN: FileCheck %s // // Additionally check that the legacy spelling of the flag works. -// RUN: %clangxx -no-canonical-prefixes %s -### -o %t 2>&1 \ -// RUN: --target=i386-unknown-linux -stdlib=libstdc++ \ -// RUN: -gcc-toolchain %S/Inputs/ubuntu_11.04_multiarch_tree/usr \ -// RUN: --sysroot="" \ -// RUN: | FileCheck %s +// RUN: %clangxx %s -### --target=x86_64-linux-gnu --sysroot= \ +// RUN: -gcc-toolchain %S/Inputs/ubuntu_14.04_multiarch_tree/usr -stdlib=libstdc++ --rtlib=libgcc 2>&1 | \ +// RUN: FileCheck %s // // Test for header search toolchain detection. // CHECK: "-internal-isystem" -// CHECK: "[[TOOLCHAIN:[^"]+]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5" +// CHECK: "[[TOOLCHAIN:[^"]+]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" // CHECK: "-internal-isystem" -// CHECK: "[[TOOLCHAIN]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5/i686-linux-gnu" +// CHECK: "[[TOOLCHAIN]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8" // CHECK: "-internal-isystem" -// CHECK: "[[TOOLCHAIN]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5/backward" -// CHECK: "-internal-isystem" "/usr/local/include" +// CHECK: "[[TOOLCHAIN]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" // // Test for linker toolchain detection. Note that only the '-L' flags will use // the same precise formatting of the path as the '-internal-system' flags // above, so we just blanket wildcard match the 'crtbegin.o'. // CHECK: "{{[^"]*}}ld{{(.exe)?}}" -// CHECK: "{{[^"]*}}/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK: "-L[[TOOLCHAIN]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5" -// CHECK: "-L[[TOOLCHAIN]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../.." +// CHECK-SAME: "{{[^"]*}}/usr/lib/gcc/x86_64-linux-gnu/4.8{{/|\\\\}}crtbegin.o" +// CHECK-SAME: "-L[[TOOLCHAIN]]/usr/lib/gcc/x86_64-linux-gnu/4.8" +/// On x86_64, there is an extra usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu but we should not test it. + +/// Test we don't detect GCC installation under -B. +// RUN: %clangxx %s -### --sysroot= 2>&1 \ +// RUN: --target=aarch64-suse-linux --gcc-toolchain=%S/Inputs/opensuse_42.2_aarch64_tree/usr | \ +// RUN: FileCheck %s --check-prefix=AARCH64 +// RUN: %clangxx %s -### --sysroot= 2>&1 \ +// RUN: --target=aarch64-suse-linux -B%S/Inputs/opensuse_42.2_aarch64_tree/usr | \ +// RUN: FileCheck %s --check-prefix=NO_AARCH64 + +// AARCH64: Inputs{{[^"]+}}aarch64-suse-linux/{{[^"]+}}crt1.o" +// NO_AARCH64-NOT: Inputs{{[^"]+}}aarch64-suse-linux/{{[^"]+}}crt1.o" diff --git a/clang/test/Driver/gcc-version-debug.c b/clang/test/Driver/gcc-version-debug.c deleted file mode 100644 index daa9606ef7a5..000000000000 --- a/clang/test/Driver/gcc-version-debug.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %clang -v --target=i386-unknown-linux \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree 2>&1 | FileCheck %s - -// CHECK: Found candidate GCC installation: {{.*}}Inputs{{.}}debian_multiarch_tree{{.}}usr{{.}}lib{{.}}gcc{{.}}i686-linux-gnu{{.}}4.5 -// CHECK-NEXT: Found candidate GCC installation: {{.*}}Inputs{{.}}debian_multiarch_tree{{.}}usr{{.}}lib{{.}}gcc{{.}}x86_64-linux-gnu{{.}}4.5 -// CHECK-NEXT: Selected GCC installation: {{.*}}Inputs{{.}}debian_multiarch_tree{{.}}usr{{.}}lib{{.}}gcc{{.}}i686-linux-gnu{{.}}4.5 diff --git a/clang/test/Driver/immediate-options.c b/clang/test/Driver/immediate-options.c index 723a6fa302f8..c398e0d41c6e 100644 --- a/clang/test/Driver/immediate-options.c +++ b/clang/test/Driver/immediate-options.c @@ -17,3 +17,15 @@ // Allow unspecified output because the value of CLANG_RESOURCE_DIR is unknown. // RUN: %clang -print-resource-dir | FileCheck %s -check-prefix=PRINT-RESOURCE-DIR // PRINT-RESOURCE-DIR: {{.+}} + +// Default resource-dir layout +// RUN: %clang -print-runtime-dir --target=x86_64-pc-windows-msvc \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: | FileCheck --check-prefix=PRINT-RUNTIME-DIR %s +// PRINT-RUNTIME-DIR: lib{{/|\\}}windows + +// Per target dir layout +// RUN: %clang -print-runtime-dir --target=x86_64-pc-windows-msvc \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: | FileCheck --check-prefix=PRINT-RUNTIME-DIR-PER-TARGET %s +// PRINT-RUNTIME-DIR-PER-TARGET: lib{{/|\\}}x86_64-pc-windows-msvc diff --git a/clang/test/Driver/linux-cross.cpp b/clang/test/Driver/linux-cross.cpp new file mode 100644 index 000000000000..bcc858d7804d --- /dev/null +++ b/clang/test/Driver/linux-cross.cpp @@ -0,0 +1,83 @@ +// UNSUPPORTED: system-windows + +/// Test native x86-64 in the tree. +// RUN: %clang -### %s --target=x86_64-linux-gnu --sysroot=%S/Inputs/debian_multiarch_tree \ +// RUN: -resource-dir=%S/Inputs/resource_dir --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=DEBIAN_X86_64 +// DEBIAN_X86_64: "-resource-dir" "[[RESOURCE:[^"]+]]" +// DEBIAN_X86_64: "-internal-isystem" +// DEBIAN_X86_64-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10" +// DEBIAN_X86_64-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10" +// DEBIAN_X86_64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward" +// DEBIAN_X86_64-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]/include" +// DEBIAN_X86_64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// DEBIAN_X86_64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include" +// DEBIAN_X86_64: "-L +// DEBIAN_X86_64-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10" +/// Debian patches MULTILIB_OSDIRNAMES (../lib64 -> ../lib), so gcc uses 'lib' instead of 'lib64'. +/// This difference does not matter in practice. +// DEBIAN_X86_64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib64" +// DEBIAN_X86_64-SAME: {{^}} "-L[[SYSROOT]]/lib/x86_64-linux-gnu" +// DEBIAN_X86_64-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// DEBIAN_X86_64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/x86_64-linux-gnu" +// DEBIAN_X86_64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib64" +/// /usr/x86_64-linux-gnu does not exist, so there is no /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/lib. +/// -ccc-install-dir is not within sysroot. No bin/../lib. +/// $sysroot/lib and $sysroot/usr/lib. Fallback when GCC installation is unavailable. +// DEBIAN_X86_64-SAME: {{^}} "-L[[SYSROOT]]/lib" +// DEBIAN_X86_64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +/// Test -m32. +// RUN: %clang -### %s --target=x86_64-linux-gnu -m32 --sysroot=%S/Inputs/debian_multiarch_tree \ +// RUN: -resource-dir=%S/Inputs/resource_dir --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=DEBIAN_X86_64_M32 +// DEBIAN_X86_64_M32: "-resource-dir" "[[RESOURCE:[^"]+]]" +// DEBIAN_X86_64_M32: "-internal-isystem" +// DEBIAN_X86_64_M32-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10" +// DEBIAN_X86_64_M32-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10/32" +// DEBIAN_X86_64_M32-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward" +// DEBIAN_X86_64_M32-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]/include" +// DEBIAN_X86_64_M32-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// DEBIAN_X86_64_M32-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include" +// DEBIAN_X86_64_M32: "-internal-externc-isystem" +// DEBIAN_X86_64_M32-SAME: {{^}} "[[SYSROOT]]/usr/include/i386-linux-gnu" +// DEBIAN_X86_64_M32: "-L +// DEBIAN_X86_64_M32-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/32" +// DEBIAN_X86_64_M32-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib32" +// DEBIAN_X86_64_M32-SAME: {{^}} "-L[[SYSROOT]]/lib/i386-linux-gnu" +// DEBIAN_X86_64_M32-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib32" +// DEBIAN_X86_64_M32-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/i386-linux-gnu" +// DEBIAN_X86_64_M32-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib32" +// DEBIAN_X86_64_M32-SAME: {{^}} "-L[[SYSROOT]]/lib" +// DEBIAN_X86_64_M32-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +/// Test a cross compiler. +// RUN: %clang -### %s --target=aarch64-linux-gnu --sysroot=%S/Inputs/debian_multiarch_tree \ +// RUN: -resource-dir=%S/Inputs/resource_dir --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=DEBIAN_AARCH64 +// DEBIAN_AARCH64: "-resource-dir" "[[RESOURCE:[^"]+]]" +// DEBIAN_AARCH64: "-internal-isystem" +// DEBIAN_AARCH64-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../aarch64-linux-gnu/include/c++/10" +// DEBIAN_AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../aarch64-linux-gnu/include/c++/10/aarch64-linux-gnu" +// DEBIAN_AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../aarch64-linux-gnu/include/c++/10/backward" +// DEBIAN_AARCH64-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]/include" +// DEBIAN_AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// DEBIAN_AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../aarch64-linux-gnu/include" +// DEBIAN_AARCH64: "-L +// DEBIAN_AARCH64-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc-cross/aarch64-linux-gnu/10" +/// Debian patches MULTILIB_OSDIRNAMES (../lib64 -> ../lib), so aarch64-linux-gnu-gcc uses 'lib' instead of 'lib64'. +/// This difference does not matter in practice. +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../lib64" +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib/aarch64-linux-gnu" +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/aarch64-linux-gnu" +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib64" +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../aarch64-linux-gnu/lib" +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib" +// DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +/// LDSO_ARCH is i386 for all x86-32 variants. +// RUN: %clang -### %s --target=i686-linux-musl --sysroot= \ +// RUN: --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=MUSL_I686 +// MUSL_I686: "-dynamic-linker" "/lib/ld-musl-i386.so.1" + +// RUN: %clang -### %s --target=x86_64-linux-muslx32 --sysroot= \ +// RUN: --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=MUSL_X32 +// MUSL_X32: "-dynamic-linker" "/lib/ld-musl-x32.so.1" diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp index 8c1fc99d79f3..9044ac2065a1 100644 --- a/clang/test/Driver/linux-header-search.cpp +++ b/clang/test/Driver/linux-header-search.cpp @@ -66,230 +66,7 @@ // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v2" // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// -// Test a very broken version of multiarch that shipped in Ubuntu 11.04. -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target i386-unknown-linux -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_11.04_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-11-04 %s -// CHECK-UBUNTU-11-04: "{{.*}}clang{{.*}}" "-cc1" -// CHECK-UBUNTU-11-04: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-UBUNTU-11-04: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-11-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5" -// CHECK-UBUNTU-11-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5/i686-linux-gnu" -// CHECK-UBUNTU-11-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5/backward" -// CHECK-UBUNTU-11-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-UBUNTU-11-04: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-UBUNTU-11-04: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-UBUNTU-11-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target x86_64-unknown-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_13.04_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-13-04 %s -// CHECK-UBUNTU-13-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-UBUNTU-13-04: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-UBUNTU-13-04: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7" -// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7" -// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" -// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-UBUNTU-13-04: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu" -// CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target x86_64-unknown-linux-gnux32 -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04 %s -// CHECK-UBUNTU-14-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-UBUNTU-14-04: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-UBUNTU-14-04: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" -// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/x32" -// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" -// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-UBUNTU-14-04: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu" -// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -/// -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target arm-linux-gnueabihf -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_13.04_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-13-04-CROSS %s -// CHECK-UBUNTU-13-04-CROSS: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-UBUNTU-13-04-CROSS: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-UBUNTU-13-04-CROSS: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7" -// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/arm-linux-gnueabihf/c++/4.7" -// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7/backward" -// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-UBUNTU-13-04-CROSS: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-UBUNTU-13-04-CROSS: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// -// Test Ubuntu/Debian's new version of multiarch, with -m32. -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target x86_64-unknown-linux-gnu -m32 -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_13.04_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-13-04-M32 %s -// CHECK-UBUNTU-13-04-M32: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-UBUNTU-13-04-M32: "-triple" "i386-unknown-linux-gnu" -// CHECK-UBUNTU-13-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7" -// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7/32" -// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" -// -// Test Ubuntu/Debian's Ubuntu 14.04 config variant, with -m32 -// and an empty 4.9 directory. -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target x86_64-unknown-linux-gnu -m32 -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-M32 %s -// CHECK-UBUNTU-14-04-M32: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-UBUNTU-14-04-M32: "-triple" "i386-unknown-linux-gnu" -// CHECK-UBUNTU-14-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" -// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/32" -// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" -// -// Test Ubuntu/Debian's Ubuntu 14.04 with -m32 and an i686 cross compiler -// installed rather than relying on multilib. Also happens to look like an -// actual i686 Ubuntu system. -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target x86_64-unknown-linux-gnu -m32 -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree2 \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-I686 %s -// CHECK-UBUNTU-14-04-I686: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-UBUNTU-14-04-I686: "-triple" "i386-unknown-linux-gnu" -// CHECK-UBUNTU-14-04-I686: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/c++/4.8" -// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/i386-linux-gnu/c++/4.8" -// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/c++/4.8/backward" -// -// Test Ubuntu/Debian's Ubuntu 14.04 for powerpc64le -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target powerpc64le-unknown-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s -// CHECK-UBUNTU-14-04-PPC64LE: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-UBUNTU-14-04-PPC64LE: "-triple" "powerpc64le-unknown-linux-gnu" -// CHECK-UBUNTU-14-04-PPC64LE: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/powerpc64le-linux-gnu/c++/4.8" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8/backward" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc64le-linux-gnu" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// -// Thoroughly exercise the Debian multiarch environment. -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target i686-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X86 %s -// CHECK-DEBIAN-X86: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-DEBIAN-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-DEBIAN-X86: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-X86: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5/../../../../include/c++/4.5" -// CHECK-DEBIAN-X86: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5/../../../../include/c++/4.5/i686-linux-gnu" -// CHECK-DEBIAN-X86: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5/../../../../include/c++/4.5/backward" -// CHECK-DEBIAN-X86: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-DEBIAN-X86: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-DEBIAN-X86: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/i386-linux-gnu" -// CHECK-DEBIAN-X86: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-DEBIAN-X86: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target x86_64-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X86-64 %s -// CHECK-DEBIAN-X86-64: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-DEBIAN-X86-64: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-DEBIAN-X86-64: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-X86-64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5/../../../../include/c++/4.5" -// CHECK-DEBIAN-X86-64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5/../../../../include/c++/4.5/x86_64-linux-gnu" -// CHECK-DEBIAN-X86-64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5/../../../../include/c++/4.5/backward" -// CHECK-DEBIAN-X86-64: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-DEBIAN-X86-64: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu" -// CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target powerpc-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC %s -// CHECK-DEBIAN-PPC: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-DEBIAN-PPC: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-DEBIAN-PPC: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-PPC: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5/../../../../include/c++/4.5" -// CHECK-DEBIAN-PPC: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5/../../../../include/c++/4.5/powerpc-linux-gnu" -// CHECK-DEBIAN-PPC: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5/../../../../include/c++/4.5/backward" -// CHECK-DEBIAN-PPC: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-DEBIAN-PPC: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-DEBIAN-PPC: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc-linux-gnu" -// CHECK-DEBIAN-PPC: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-DEBIAN-PPC: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target powerpc64-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC64 %s -// CHECK-DEBIAN-PPC64: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-DEBIAN-PPC64: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-DEBIAN-PPC64: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-PPC64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5/../../../../include/c++/4.5" -// CHECK-DEBIAN-PPC64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5/../../../../include/c++/4.5/powerpc64-linux-gnu" -// CHECK-DEBIAN-PPC64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5/../../../../include/c++/4.5/backward" -// CHECK-DEBIAN-PPC64: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-DEBIAN-PPC64: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-DEBIAN-PPC64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc64-linux-gnu" -// CHECK-DEBIAN-PPC64: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-DEBIAN-PPC64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target sparc-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC %s -// CHECK-DEBIAN-SPARC: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-DEBIAN-SPARC-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-DEBIAN-SPARC-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-SPARC-SAME: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/sparc-linux-gnu/4.5/../../../../include/c++/4.5" -// CHECK-DEBIAN-SPARC-SAME: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/sparc-linux-gnu/4.5/../../../../include/c++/4.5/sparc-linux-gnu" -// CHECK-DEBIAN-SPARC-SAME: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/sparc-linux-gnu/4.5/../../../../include/c++/4.5/backward" -// CHECK-DEBIAN-SPARC-SAME: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-DEBIAN-SPARC-SAME: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-DEBIAN-SPARC-SAME: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/sparc-linux-gnu" -// CHECK-DEBIAN-SPARC-SAME: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-DEBIAN-SPARC-SAME: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ -// RUN: -target sparc64-linux-gnu -stdlib=libstdc++ \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: --gcc-toolchain="" \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC64 %s -// CHECK-DEBIAN-SPARC64: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-DEBIAN-SPARC64-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-DEBIAN-SPARC64-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/sparc64-linux-gnu/4.5/../../../../include/c++/4.5" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/sparc64-linux-gnu/4.5/../../../../include/c++/4.5/sparc64-linux-gnu" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/sparc64-linux-gnu/4.5/../../../../include/c++/4.5/backward" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/sparc64-linux-gnu" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-DEBIAN-SPARC64-SAME: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// + // Test Gentoo's weirdness both before and after they changed it in their GCC // 4.6.4 release. // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ @@ -303,8 +80,8 @@ // CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4" // CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/x86_64-pc-linux-gnu" // CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/backward" -// CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-6-2: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-6-2: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-6-2: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ @@ -318,8 +95,8 @@ // CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.4/include/g++-v4.6" // CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.4/include/g++-v4.6/x86_64-pc-linux-gnu" // CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.4/include/g++-v4.6/backward" -// CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-6-4: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-6-4: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-6-4: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ @@ -333,8 +110,8 @@ // CHECK-GENTOO-4-9-3: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3" // CHECK-GENTOO-4-9-3: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/x86_64-pc-linux-gnu" // CHECK-GENTOO-4-9-3: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/backward" -// CHECK-GENTOO-4-9-3: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-3: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-9-3: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-3: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-9-3: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // @@ -359,8 +136,8 @@ // CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3" // CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/x86_64-pc-linux-gnu/x32" // CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/backward" -// CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-3-X32: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-9-3-X32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // @@ -375,8 +152,8 @@ // CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3" // CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/x86_64-pc-linux-gnu/32" // CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/backward" -// CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-3-32: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-9-3-32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // @@ -396,8 +173,8 @@ // CHECK-GENTOO-4-9-X: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3" // CHECK-GENTOO-4-9-X: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3/x86_64-pc-linux-gnu" // CHECK-GENTOO-4-9-X: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3/backward" -// CHECK-GENTOO-4-9-X: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-X: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-9-X: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-X: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-9-X: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // @@ -412,8 +189,8 @@ // CHECK-GENTOO-4-9-X-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3" // CHECK-GENTOO-4-9-X-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3/x86_64-pc-linux-gnu/x32" // CHECK-GENTOO-4-9-X-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3/backward" -// CHECK-GENTOO-4-9-X-X32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-X-X32: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-9-X-X32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-X-X32: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-9-X-X32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // @@ -428,8 +205,8 @@ // CHECK-GENTOO-4-9-X-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3" // CHECK-GENTOO-4-9-X-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3/x86_64-pc-linux-gnu/32" // CHECK-GENTOO-4-9-X-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4.9.3/backward" -// CHECK-GENTOO-4-9-X-32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-X-32: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-GENTOO-4-9-X-32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-GENTOO-4-9-X-32: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-GENTOO-4-9-X-32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // @@ -445,8 +222,8 @@ // CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9" // CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9/mips64-linux-gnuabi64" // CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9/backward" -// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-MIPS64-GNUABI: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/mips64-linux-gnuabi64" // CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" @@ -463,8 +240,8 @@ // CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9" // CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9/mips64el-linux-gnuabi64" // CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9/backward" -// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/mips64el-linux-gnuabi64" // CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c index 5263928ff3b9..cc505588331b 100644 --- a/clang/test/Driver/linux-ld.c +++ b/clang/test/Driver/linux-ld.c @@ -1,3 +1,4 @@ +// UNSUPPORTED: system-windows // General tests that ld invocations on Linux targets sane. Note that we use // sysroot to make these tests independent of the host system. // @@ -8,10 +9,9 @@ // RUN: | FileCheck --check-prefix=CHECK-LD-32 %s // CHECK-LD-32-NOT: warning: // CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-LD-32: "{{.*}}/usr/lib/gcc/i386-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0" -// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib" -// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../.." +// CHECK-LD-32: "{{.*}}/usr/lib/gcc/i386-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0" +// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/lib" // CHECK-LD-32: "-L[[SYSROOT]]/lib" // CHECK-LD-32: "-L[[SYSROOT]]/usr/lib" // @@ -25,10 +25,9 @@ // CHECK-LD-64: "--eh-frame-hdr" // CHECK-LD-64: "-m" "elf_x86_64" // CHECK-LD-64: "-dynamic-linker" -// CHECK-LD-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-LD-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-LD-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-LD-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-LD-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-LD-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0" +// CHECK-LD-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-LD-64: "-L[[SYSROOT]]/lib" // CHECK-LD-64: "-L[[SYSROOT]]/usr/lib" // CHECK-LD-64: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" @@ -63,9 +62,8 @@ // CHECK-LD-RT: "-m" "elf_x86_64" // CHECK-LD-RT: "-dynamic-linker" // CHECK-LD-RT: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}clang_rt.crtbegin-x86_64.o" -// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0" +// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-LD-RT: "-L[[SYSROOT]]/lib" // CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib" // CHECK-LD-RT: libclang_rt.builtins-x86_64.a" @@ -87,9 +85,8 @@ // CHECK-LD-RT-I686: "-m" "elf_i386" // CHECK-LD-RT-I686: "-dynamic-linker" // CHECK-LD-RT-I686: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}clang_rt.crtbegin-i386.o" -// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0" -// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0/../../../../i686-unknown-linux/lib" -// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0/../../.." +// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/10.2.0" +// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/10.2.0/../../../../i686-unknown-linux/lib" // CHECK-LD-RT-I686: "-L[[SYSROOT]]/lib" // CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib" // CHECK-LD-RT-I686: libclang_rt.builtins-i386.a" @@ -122,10 +119,9 @@ // CHECK-LD-GCC: "--eh-frame-hdr" // CHECK-LD-GCC: "-m" "elf_x86_64" // CHECK-LD-GCC: "-dynamic-linker" -// CHECK-LD-GCC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-LD-GCC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0" +// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-LD-GCC: "-L[[SYSROOT]]/lib" // CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib" // CHECK-LD-GCC: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" @@ -143,10 +139,9 @@ // CHECK-LD-64-STATIC-LIBGCC: "--eh-frame-hdr" // CHECK-LD-64-STATIC-LIBGCC: "-m" "elf_x86_64" // CHECK-LD-64-STATIC-LIBGCC: "-dynamic-linker" -// CHECK-LD-64-STATIC-LIBGCC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-LD-64-STATIC-LIBGCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-LD-64-STATIC-LIBGCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-LD-64-STATIC-LIBGCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-LD-64-STATIC-LIBGCC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-LD-64-STATIC-LIBGCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0" +// CHECK-LD-64-STATIC-LIBGCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-LD-64-STATIC-LIBGCC: "-L[[SYSROOT]]/lib" // CHECK-LD-64-STATIC-LIBGCC: "-L[[SYSROOT]]/usr/lib" // CHECK-LD-64-STATIC-LIBGCC: "-lgcc" "-lgcc_eh" @@ -288,7 +283,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-ANDROID-NONE %s // CHECK-CLANG-ANDROID-NONE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-CLANG-ANDROID-NONE: "-lgcc" "-ldl" "-lc" +// CHECK-CLANG-ANDROID-NONE: "-l:libunwind.a" "-ldl" "-lc" // // RUN: %clang -shared -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ @@ -296,7 +291,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-ANDROID-SHARED %s // CHECK-CLANG-ANDROID-SHARED: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-CLANG-ANDROID-SHARED: "-lgcc" "-ldl" "-lc" +// CHECK-CLANG-ANDROID-SHARED: "-l:libunwind.a" "-ldl" "-lc" // // RUN: %clang -static -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ @@ -304,7 +299,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-ANDROID-STATIC %s // CHECK-CLANG-ANDROID-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-CLANG-ANDROID-STATIC: "--start-group" "-lgcc" "-lc" "--end-group" +// CHECK-CLANG-ANDROID-STATIC: "--start-group" "{{[^"]*}}{{/|\\\\}}libclang_rt.builtins-aarch64-android.a" "-l:libunwind.a" "-lc" "--end-group" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ @@ -318,10 +313,9 @@ // CHECK-LD-64-STATIC: "-m" "elf_x86_64" // CHECK-LD-64-STATIC-NOT: "-dynamic-linker" // CHECK-LD-64-STATIC: "-static" -// CHECK-LD-64-STATIC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbeginT.o" -// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-LD-64-STATIC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtbeginT.o" +// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0" +// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-LD-64-STATIC: "-L[[SYSROOT]]/lib" // CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib" // CHECK-LD-64-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group" @@ -340,14 +334,13 @@ // RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-32-TO-32 %s // CHECK-32-TO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-32-TO-32: "{{.*}}/usr/lib/gcc/i386-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0" -// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib/../lib32" -// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../lib32" +// CHECK-32-TO-32: "{{.*}}/usr/lib/gcc/i386-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0" +// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/lib/../lib32" +// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../lib32" // CHECK-32-TO-32: "-L[[SYSROOT]]/lib/../lib32" // CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/../lib32" -// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib" -// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../.." +// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/lib" // CHECK-32-TO-32: "-L[[SYSROOT]]/lib" // CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib" // @@ -357,15 +350,13 @@ // RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-32-TO-64 %s // CHECK-32-TO-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-32-TO-64: "{{.*}}/usr/lib/gcc/i386-unknown-linux/4.6.0/64{{/|\\\\}}crtbegin.o" -// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/64" -// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib/../lib64" -// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../lib64" +// CHECK-32-TO-64: "{{.*}}/usr/lib/gcc/i386-unknown-linux/10.2.0/64{{/|\\\\}}crtbegin.o" +// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/64" +// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/lib/../lib64" +// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../lib64" // CHECK-32-TO-64: "-L[[SYSROOT]]/lib/../lib64" // CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/../lib64" -// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0" -// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib" -// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../.." +// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/lib" // CHECK-32-TO-64: "-L[[SYSROOT]]/lib" // CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib" // @@ -375,14 +366,13 @@ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-64-TO-64 %s // CHECK-64-TO-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-64-TO-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../lib64" -// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../lib64" +// CHECK-64-TO-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0" +// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib/../lib64" +// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../lib64" // CHECK-64-TO-64: "-L[[SYSROOT]]/lib/../lib64" // CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/../lib64" -// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-64-TO-64: "-L[[SYSROOT]]/lib" // CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib" // @@ -392,15 +382,13 @@ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-64-TO-32 %s // CHECK-64-TO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-64-TO-32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32{{/|\\\\}}crtbegin.o" -// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32" -// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../lib32" -// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../lib32" +// CHECK-64-TO-32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32{{/|\\\\}}crtbegin.o" +// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32" +// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib/../lib32" +// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../lib32" // CHECK-64-TO-32: "-L[[SYSROOT]]/lib/../lib32" // CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/../lib32" -// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-64-TO-32: "-L[[SYSROOT]]/lib" // CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib" // @@ -410,15 +398,13 @@ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-X32 %s // CHECK-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32{{/|\\\\}}crtbegin.o" -// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32" -// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../libx32" -// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../libx32" +// CHECK-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32{{/|\\\\}}crtbegin.o" +// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32" +// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib/../libx32" +// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../libx32" // CHECK-X32: "-L[[SYSROOT]]/lib/../libx32" // CHECK-X32: "-L[[SYSROOT]]/usr/lib/../libx32" -// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-X32: "-L[[SYSROOT]]/lib" // CHECK-X32: "-L[[SYSROOT]]/usr/lib" // @@ -428,15 +414,13 @@ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-64-TO-X32 %s // CHECK-64-TO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-64-TO-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32{{/|\\\\}}crtbegin.o" -// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32" -// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../libx32" -// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../libx32" +// CHECK-64-TO-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32{{/|\\\\}}crtbegin.o" +// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32" +// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib/../libx32" +// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../libx32" // CHECK-64-TO-X32: "-L[[SYSROOT]]/lib/../libx32" // CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/../libx32" -// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-64-TO-X32: "-L[[SYSROOT]]/lib" // CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib" // @@ -446,15 +430,13 @@ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-32-TO-X32 %s // CHECK-32-TO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-32-TO-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32{{/|\\\\}}crtbegin.o" -// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32" -// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../libx32" -// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../libx32" +// CHECK-32-TO-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32{{/|\\\\}}crtbegin.o" +// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32" +// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib/../libx32" +// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../libx32" // CHECK-32-TO-X32: "-L[[SYSROOT]]/lib/../libx32" // CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/../libx32" -// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-32-TO-X32: "-L[[SYSROOT]]/lib" // CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib" // @@ -464,14 +446,13 @@ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-X32-TO-64 %s // CHECK-X32-TO-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-X32-TO-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../lib64" -// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../lib64" +// CHECK-X32-TO-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" +// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0" +// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib/../lib64" +// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../lib64" // CHECK-X32-TO-64: "-L[[SYSROOT]]/lib/../lib64" // CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/../lib64" -// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-X32-TO-64: "-L[[SYSROOT]]/lib" // CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib" // @@ -481,15 +462,13 @@ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-X32-TO-32 %s // CHECK-X32-TO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-X32-TO-32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32{{/|\\\\}}crtbegin.o" -// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32" -// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../lib32" -// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../lib32" +// CHECK-X32-TO-32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32{{/|\\\\}}crtbegin.o" +// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32" +// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib/../lib32" +// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../lib32" // CHECK-X32-TO-32: "-L[[SYSROOT]]/lib/../lib32" // CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/../lib32" -// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib" -// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.." +// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib" // CHECK-X32-TO-32: "-L[[SYSROOT]]/lib" // CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib" // @@ -499,36 +478,13 @@ // RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-64-TO-32-SYSROOT %s // CHECK-64-TO-32-SYSROOT: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-64-TO-32-SYSROOT: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32{{/|\\\\}}crtbegin.o" -// CHECK-64-TO-32-SYSROOT: "-L{{[^"]*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32" +// CHECK-64-TO-32-SYSROOT: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32{{/|\\\\}}crtbegin.o" +// CHECK-64-TO-32-SYSROOT: "-L{{[^"]*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32" // CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/lib/../lib32" // CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/usr/lib/../lib32" -// CHECK-64-TO-32-SYSROOT: "-L{{[^"]*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0" // CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/lib" // CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/usr/lib" // -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \ -// RUN: -ccc-install-dir %S/Inputs/fake_install_tree/bin \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: | FileCheck --check-prefix=CHECK-INSTALL-DIR-32 %s -// CHECK-INSTALL-DIR-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-INSTALL-DIR-32: "{{.*}}/Inputs/fake_install_tree/bin/../lib/gcc/i386-unknown-linux/4.7.0{{/|\\\\}}crtbegin.o" -// CHECK-INSTALL-DIR-32: "-L{{.*}}/Inputs/fake_install_tree/bin/../lib/gcc/i386-unknown-linux/4.7.0" -// -// Check that with 64-bit builds, we don't actually use the install directory -// as its version of GCC is lower than our sysrooted version. -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=x86_64-unknown-linux -rtlib=platform -m64 \ -// RUN: -ccc-install-dir %S/Inputs/fake_install_tree/bin \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: | FileCheck --check-prefix=CHECK-INSTALL-DIR-64 %s -// CHECK-INSTALL-DIR-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-INSTALL-DIR-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-INSTALL-DIR-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0" -// // Check that we support unusual patch version formats, including missing that // component. // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -538,45 +494,8 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-GCC-VERSION1 %s // CHECK-GCC-VERSION1: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-GCC-VERSION1: "{{.*}}/Inputs/gcc_version_parsing1/bin/../lib/gcc/i386-unknown-linux/4.7{{/|\\\\}}crtbegin.o" -// CHECK-GCC-VERSION1: "-L{{.*}}/Inputs/gcc_version_parsing1/bin/../lib/gcc/i386-unknown-linux/4.7" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \ -// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing2/bin \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: | FileCheck --check-prefix=CHECK-GCC-VERSION2 %s -// CHECK-GCC-VERSION2: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-GCC-VERSION2: "{{.*}}/Inputs/gcc_version_parsing2/bin/../lib/gcc/i386-unknown-linux/4.7.x{{/|\\\\}}crtbegin.o" -// CHECK-GCC-VERSION2: "-L{{.*}}/Inputs/gcc_version_parsing2/bin/../lib/gcc/i386-unknown-linux/4.7.x" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \ -// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing3/bin \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: | FileCheck --check-prefix=CHECK-GCC-VERSION3 %s -// CHECK-GCC-VERSION3: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-GCC-VERSION3: "{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5{{/|\\\\}}crtbegin.o" -// CHECK-GCC-VERSION3: "-L{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \ -// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing4/bin \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: | FileCheck --check-prefix=CHECK-GCC-VERSION4 %s -// CHECK-GCC-VERSION4: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-GCC-VERSION4: "{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99{{/|\\\\}}crtbegin.o" -// CHECK-GCC-VERSION4: "-L{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \ -// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing5/bin \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: | FileCheck --check-prefix=CHECK-GCC-VERSION5 %s -// CHECK-GCC-VERSION5: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-GCC-VERSION5: "{{.*}}/Inputs/gcc_version_parsing5/bin/../lib/gcc/i386-unknown-linux/5{{/|\\\\}}crtbegin.o" -// CHECK-GCC-VERSION5: "-L{{.*}}/Inputs/gcc_version_parsing5/bin/../lib/gcc/i386-unknown-linux/5" -// +// CHECK-GCC-VERSION1: "{{.*}}/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o" + // Test a simulated installation of libc++ on Linux, both through sysroot and // the installation path of Clang. // RUN: %clangxx -no-canonical-prefixes -x c++ %s -### -o %t.o 2>&1 \ @@ -624,21 +543,6 @@ // CHECK-BASIC-LIBCXX-C-LINK: "--sysroot=[[SYSROOT]]" // CHECK-BASIC-LIBCXX-C-LINK: "-L[[SYSROOT]]/usr/bin/../lib" // -// Test a very broken version of multiarch that shipped in Ubuntu 11.04. -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=i386-unknown-linux -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/ubuntu_11.04_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-11-04 %s -// CHECK-UBUNTU-11-04: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-11-04: "{{.*}}/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5" -// CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../i386-linux-gnu" -// CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/usr/lib/i386-linux-gnu" -// CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../.." -// CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/lib" -// CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/usr/lib" -// // Check multi arch support on Ubuntu 12.04 LTS. // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-unknown-linux-gnueabihf -rtlib=platform \ @@ -646,16 +550,14 @@ // RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM-HF %s // CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf{{/|\\\\}}crt1.o" -// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf{{/|\\\\}}crti.o" +// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/arm-linux-gnueabihf{{/|\\\\}}crt1.o" +// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/arm-linux-gnueabihf{{/|\\\\}}crti.o" // CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3{{/|\\\\}}crtbegin.o" // CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabihf/4.6.3" -// CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf" // CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/lib/arm-linux-gnueabihf" // CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/arm-linux-gnueabihf" -// CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../.." // CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3{{/|\\\\}}crtend.o" -// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf{{/|\\\\}}crtn.o" +// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/arm-linux-gnueabihf{{/|\\\\}}crtn.o" // // Check Ubuntu 13.10 on x86-64 targeting arm-linux-gnueabihf. // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -702,16 +604,14 @@ // RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s // CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crt1.o" -// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crti.o" +// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/powerpc64le-linux-gnu{{/|\\\\}}crt1.o" +// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/powerpc64le-linux-gnu{{/|\\\\}}crti.o" // CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8{{/|\\\\}}crtbegin.o" // CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8" -// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu" // CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/lib/powerpc64le-linux-gnu" // CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/powerpc64le-linux-gnu" -// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../.." // CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8{{/|\\\\}}crtend.o" -// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crtn.o" +// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/powerpc64le-linux-gnu{{/|\\\\}}crtn.o" // // Check Ubuntu 14.04 on x32. // "/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32/crtn.o" @@ -725,12 +625,9 @@ // CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crti.o" // CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/x32{{/|\\\\}}crtbegin.o" // CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/x32" -// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32" -// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/lib/../libx32" -// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/../libx32" -// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/x86_64-linux-gnu/../../libx32" -// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8" -// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.." +// CHECK-UBUNTU-14-04-X32-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32" +// CHECK-UBUNTU-14-04-X32-SAME: {{^}} "-L[[SYSROOT]]/lib/../libx32" +// CHECK-UBUNTU-14-04-X32-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../libx32" // CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/x32{{/|\\\\}}crtend.o" // CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crtn.o" // @@ -790,16 +687,14 @@ // RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM %s // CHECK-UBUNTU-12-04-ARM: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi{{/|\\\\}}crt1.o" -// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi{{/|\\\\}}crti.o" +// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/arm-linux-gnueabi{{/|\\\\}}crt1.o" +// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/arm-linux-gnueabi{{/|\\\\}}crti.o" // CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1{{/|\\\\}}crtbegin.o" // CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabi/4.6.1" -// CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi" // CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/lib/arm-linux-gnueabi" // CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/arm-linux-gnueabi" -// CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../.." // CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1{{/|\\\\}}crtend.o" -// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi{{/|\\\\}}crtn.o" +// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/arm-linux-gnueabi{{/|\\\\}}crtn.o" // // Test the setup that shipped in SUSE 10.3 on ppc64. // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -901,13 +796,12 @@ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_ppc_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-PPC %s // CHECK-OPENSUSE-TW-PPC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|\\\\}}crt1.o" -// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|\\\\}}crti.o" +// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib{{/|\\\\}}crt1.o" +// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib{{/|\\\\}}crti.o" // CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|\\\\}}crtbegin.o" // CHECK-OPENSUSE-TW-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9" -// CHECK-OPENSUSE-TW-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9/../../.." // CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|\\\\}}crtend.o" -// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|\\\\}}crtn.o" +// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/crtn.o" // // Check dynamic-linker for different archs // RUN: %clang %s -### -o %t.o 2>&1 \ @@ -1098,11 +992,11 @@ // CHECK-ANDROID-NOEXECSTACK-NOT: "-z,execstack" // CHECK-ANDROID-NOEXECSTACK-NOT: "-zexecstack" -+// RUN: %clang %s -### -o %t.o 2>&1 \ -+// RUN: --target=armv7-linux-android21 \ -+// RUN: | FileCheck --check-prefix=CHECK-ANDROID-WARN-SHARED-TEXTREL %s -+// CHECK-ANDROID-WARN-SHARED-TEXTREL: "{{.*}}ld{{(.exe)?}}" -+// CHECK-ANDROID-WARN-SHARED-TEXTREL: "--warn-shared-textrel" +// RUN: %clang %s -### -o %t.o 2>&1 \ +// RUN: --target=armv7-linux-android21 \ +// RUN: | FileCheck --check-prefix=CHECK-ANDROID-WARN-SHARED-TEXTREL %s +// CHECK-ANDROID-WARN-SHARED-TEXTREL: "{{.*}}ld{{(.exe)?}}" +// CHECK-ANDROID-WARN-SHARED-TEXTREL: "--warn-shared-textrel" // RUN: %clang %s -### -o %t.o 2>&1 --target=mips64-linux-gnuabin32 \ // RUN: | FileCheck --check-prefix=CHECK-MIPS64EL-GNUABIN32 %s @@ -1138,174 +1032,8 @@ // CHECK-SPARCV9: "{{.*}}ld{{(.exe)?}}" // CHECK-SPARCV9: "-m" "elf64_sparc" // CHECK-SPARCV9: "-dynamic-linker" "{{(/usr/sparcv9-unknown-linux-gnu)?}}/lib{{(64)?}}/ld-linux.so.2" -// -// Thoroughly exercise the Debian multiarch environment. -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=i686-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X86 %s -// CHECK-DEBIAN-X86: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-X86: "{{.*}}/usr/lib/gcc/i686-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5" -// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5/../../../i386-linux-gnu" -// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/usr/lib/i386-linux-gnu" -// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=x86_64-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X86-64 %s -// CHECK-DEBIAN-X86-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-X86-64: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5" -// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5/../../../x86_64-linux-gnu" -// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/usr/lib/x86_64-linux-gnu" -// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=powerpc-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC %s -// CHECK-DEBIAN-PPC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-PPC: "{{.*}}/usr/lib/gcc/powerpc-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5" -// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5/../../../powerpc-linux-gnu" -// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/usr/lib/powerpc-linux-gnu" -// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=powerpc64le-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC64LE %s -// CHECK-DEBIAN-PPC64LE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.5" -// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.5/../../../powerpc64le-linux-gnu" -// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/usr/lib/powerpc64le-linux-gnu" -// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=powerpc64-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC64 %s -// CHECK-DEBIAN-PPC64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-PPC64: "{{.*}}/usr/lib/gcc/powerpc64-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5" -// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5/../../../powerpc64-linux-gnu" -// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/usr/lib/powerpc64-linux-gnu" -// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=mips-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS %s -// CHECK-DEBIAN-MIPS: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-MIPS: "{{.*}}/usr/lib/gcc/mips-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5" -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5/../../../mips-linux-gnu" -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/mips-linux-gnu" -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=mipsel-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPSEL %s -// CHECK-DEBIAN-MIPSEL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-MIPSEL: "{{.*}}/usr/lib/gcc/mipsel-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5" -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5/../../../mipsel-linux-gnu" -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/mipsel-linux-gnu" -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=mips64-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64 %s -// CHECK-DEBIAN-MIPS64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-MIPS64: "{{.*}}/usr/lib/gcc/mips-linux-gnu/4.5/64{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-MIPS64: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5/64" -// CHECK-DEBIAN-MIPS64: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5" -// CHECK-DEBIAN-MIPS64: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-MIPS64: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-MIPS64: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=mips64el-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64EL %s -// CHECK-DEBIAN-MIPS64EL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-MIPS64EL: "{{.*}}/usr/lib/gcc/mipsel-linux-gnu/4.5/64{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-MIPS64EL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5/64" -// CHECK-DEBIAN-MIPS64EL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5" -// CHECK-DEBIAN-MIPS64EL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-MIPS64EL: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-MIPS64EL: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=mips64-linux-gnu -rtlib=platform -mabi=n32 \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64-N32 %s -// CHECK-DEBIAN-MIPS64-N32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-MIPS64-N32: "{{.*}}/usr/lib/gcc/mips-linux-gnu/4.5/n32{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-MIPS64-N32: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5/n32" -// CHECK-DEBIAN-MIPS64-N32: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5" -// CHECK-DEBIAN-MIPS64-N32: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-MIPS64-N32: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-MIPS64-N32: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=mips64el-linux-gnu -rtlib=platform -mabi=n32 \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64EL-N32 %s -// CHECK-DEBIAN-MIPS64EL-N32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-MIPS64EL-N32: "{{.*}}/usr/lib/gcc/mipsel-linux-gnu/4.5/n32{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5/n32" -// CHECK-DEBIAN-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5" -// CHECK-DEBIAN-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-MIPS64EL-N32: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=sparc-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC %s -// CHECK-DEBIAN-SPARC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-SPARC-SAME: "{{.*}}/usr/lib/gcc/sparc-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-SPARC-SAME: "-L[[SYSROOT]]/usr/lib/gcc/sparc-linux-gnu/4.5" -// CHECK-DEBIAN-SPARC-SAME: "-L[[SYSROOT]]/usr/lib/gcc/sparc-linux-gnu/4.5/../../../sparc-linux-gnu" -// CHECK-DEBIAN-SPARC-SAME: "-L[[SYSROOT]]/usr/lib/sparc-linux-gnu" -// CHECK-DEBIAN-SPARC-SAME: "-L[[SYSROOT]]/usr/lib/gcc/sparc-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-SPARC-SAME: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-SPARC-SAME: "-L[[SYSROOT]]/usr/lib" -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: --target=sparc64-linux-gnu -rtlib=platform \ -// RUN: --gcc-toolchain="" \ -// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ -// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC64 %s -// CHECK-DEBIAN-SPARC64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-SPARC64-SAME: "{{.*}}/usr/lib/gcc/sparc64-linux-gnu/4.5{{/|\\\\}}crtbegin.o" -// CHECK-DEBIAN-SPARC64-SAME: "-L[[SYSROOT]]/usr/lib/gcc/sparc64-linux-gnu/4.5" -// CHECK-DEBIAN-SPARC64-SAME: "-L[[SYSROOT]]/usr/lib/gcc/sparc64-linux-gnu/4.5/../../../sparc64-linux-gnu" -// CHECK-DEBIAN-SPARC64-SAME: "-L[[SYSROOT]]/usr/lib/sparc64-linux-gnu" -// CHECK-DEBIAN-SPARC64-SAME: "-L[[SYSROOT]]/usr/lib/gcc/sparc64-linux-gnu/4.5/../../.." -// CHECK-DEBIAN-SPARC64-SAME: "-L[[SYSROOT]]/lib" -// CHECK-DEBIAN-SPARC64-SAME: "-L[[SYSROOT]]/usr/lib" -// + + // Test linker invocation on Android. // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ @@ -1353,10 +1081,12 @@ // CHECK-ANDROID: "--enable-new-dtags" // CHECK-ANDROID: "{{.*}}{{/|\\\\}}crtbegin_dynamic.o" // CHECK-ANDROID: "-L[[SYSROOT]]/usr/lib" -// CHECK-ANDROID-NOT: "gcc_s" -// CHECK-ANDROID: "-lgcc" +// CHECK-ANDROID-NOT: "-lgcc_s" +// CHECK-ANDROID-NOT: "-lgcc" +// CHECK-ANDROID: "-l:libunwind.a" // CHECK-ANDROID: "-ldl" -// CHECK-ANDROID-NOT: "gcc_s" +// CHECK-ANDROID-NOT: "-lgcc_s" +// CHECK-ANDROID-NOT: "-lgcc" // CHECK-ANDROID: "{{.*}}{{/|\\\\}}crtend_android.o" // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ @@ -1409,10 +1139,12 @@ // CHECK-ANDROID-SO-NOT: "-Bsymbolic" // CHECK-ANDROID-SO: "{{.*}}{{/|\\\\}}crtbegin_so.o" // CHECK-ANDROID-SO: "-L[[SYSROOT]]/usr/lib" -// CHECK-ANDROID-SO-NOT: "gcc_s" -// CHECK-ANDROID-SO: "-lgcc" +// CHECK-ANDROID-SO-NOT: "-lgcc_s" +// CHECK-ANDROID-SO-NOT: "-lgcc" +// CHECK-ANDROID-SO: "-l:libunwind.a" // CHECK-ANDROID-SO: "-ldl" -// CHECK-ANDROID-SO-NOT: "gcc_s" +// CHECK-ANDROID-SO-NOT: "-lgcc_s" +// CHECK-ANDROID-SO-NOT: "-lgcc" // CHECK-ANDROID-SO: "{{.*}}{{/|\\\\}}crtend_so.o" // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ @@ -1463,10 +1195,12 @@ // CHECK-ANDROID-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-ANDROID-STATIC: "{{.*}}{{/|\\\\}}crtbegin_static.o" // CHECK-ANDROID-STATIC: "-L[[SYSROOT]]/usr/lib" -// CHECK-ANDROID-STATIC-NOT: "gcc_s" -// CHECK-ANDROID-STATIC: "-lgcc" +// CHECK-ANDROID-STATIC-NOT: "-lgcc_eh" +// CHECK-ANDROID-STATIC-NOT: "-lgcc" +// CHECK-ANDROID-STATIC: "-l:libunwind.a" // CHECK-ANDROID-STATIC-NOT: "-ldl" -// CHECK-ANDROID-STATIC-NOT: "gcc_s" +// CHECK-ANDROID-STATIC-NOT: "-lgcc_eh" +// CHECK-ANDROID-STATIC-NOT: "-lgcc" // CHECK-ANDROID-STATIC: "{{.*}}{{/|\\\\}}crtend_android.o" // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ @@ -1519,9 +1253,11 @@ // CHECK-ANDROID-PIE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-ANDROID-PIE: "{{.*}}{{/|\\\\}}crtbegin_dynamic.o" // CHECK-ANDROID-PIE: "-L[[SYSROOT]]/usr/lib" -// CHECK-ANDROID-PIE-NOT: "gcc_s" -// CHECK-ANDROID-PIE: "-lgcc" -// CHECK-ANDROID-PIE-NOT: "gcc_s" +// CHECK-ANDROID-PIE-NOT: "-lgcc_s" +// CHECK-ANDROID-PIE-NOT: "-lgcc" +// CHECK-ANDROID-PIE: "-l:libunwind.a" +// CHECK-ANDROID-PIE-NOT: "-lgcc_s" +// CHECK-ANDROID-PIE-NOT: "-lgcc" // CHECK-ANDROID-PIE: "{{.*}}{{/|\\\\}}crtend_android.o" // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-linux-androideabi \ @@ -1677,7 +1413,6 @@ // CHECK-DEBIAN-ML-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.4/../../../../lib" // CHECK-DEBIAN-ML-MIPSEL: "-L[[SYSROOT]]/lib/../lib" // CHECK-DEBIAN-ML-MIPSEL: "-L[[SYSROOT]]/usr/lib/../lib" -// CHECK-DEBIAN-ML-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.4/../../.." // CHECK-DEBIAN-ML-MIPSEL: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-ML-MIPSEL: "-L[[SYSROOT]]/usr/lib" // @@ -1694,7 +1429,6 @@ // CHECK-DEBIAN-ML-MIPS64EL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.4/../../../../lib64" // CHECK-DEBIAN-ML-MIPS64EL: "-L[[SYSROOT]]/lib/../lib64" // CHECK-DEBIAN-ML-MIPS64EL: "-L[[SYSROOT]]/usr/lib/../lib64" -// CHECK-DEBIAN-ML-MIPS64EL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.4/../../.." // CHECK-DEBIAN-ML-MIPS64EL: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-ML-MIPS64EL: "-L[[SYSROOT]]/usr/lib" // @@ -1711,7 +1445,6 @@ // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.4/../../../../lib32" // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/lib/../lib32" // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib/../lib32" -// CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.4/../../.." // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib" // @@ -1726,19 +1459,16 @@ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s // CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crt1.o" -// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crti.o" +// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/mips64-linux-gnuabi64{{/|\\\\}}crt1.o" +// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/mips64-linux-gnuabi64{{/|\\\\}}crti.o" // CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9{{/|\\\\}}crtbegin.o" // CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9" -// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64" // CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/lib/mips64-linux-gnuabi64" // CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/mips64-linux-gnuabi64" -// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9" -// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../.." // CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib" // CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9{{/|\\\\}}crtend.o" -// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crtn.o" +// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/mips64-linux-gnuabi64{{/|\\\\}}crtn.o" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=mips64el-unknown-linux-gnu -rtlib=platform \ @@ -1751,19 +1481,16 @@ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crt1.o" -// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crti.o" +// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/mips64el-linux-gnuabi64{{/|\\\\}}crt1.o" +// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/mips64el-linux-gnuabi64{{/|\\\\}}crti.o" // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9{{/|\\\\}}crtbegin.o" // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9" -// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64" // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/lib/mips64el-linux-gnuabi64" // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/mips64el-linux-gnuabi64" -// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9" -// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../.." // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib" // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9{{/|\\\\}}crtend.o" -// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crtn.o" +// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/mips64el-linux-gnuabi64{{/|\\\\}}crtn.o" // // Test linker invocation for Freescale SDK (OpenEmbedded). // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -1785,7 +1512,6 @@ // CHECK-FSL-PPC64: "-m" "elf64ppc" // CHECK-FSL-PPC64: "{{.*}}{{/|\\\\}}crt1.o" // CHECK-FSL-PPC64: "{{.*}}{{/|\\\\}}crtbegin.o" -// CHECK-FSL-PPC64: "-L[[SYSROOT]]/usr/lib64/powerpc64-fsl-linux/4.6.2/../.." // // Check that crtfastmath.o is linked with -ffast-math and with -Ofast. // RUN: %clang --target=x86_64-unknown-linux -### %s \ @@ -1838,7 +1564,7 @@ // RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s -// CHECK-CRTFASTMATH: usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtfastmath.o +// CHECK-CRTFASTMATH: usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtfastmath.o // CHECK-NOCRTFASTMATH-NOT: crtfastmath.o // Check that we link in gcrt1.o when compiling with -pg @@ -2050,7 +1776,6 @@ // CHECK-LD-GENTOO: "{{.*}}/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3{{/|\\\\}}crtbegin.o" // CHECK-LD-GENTOO: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3" // CHECK-LD-GENTOO: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../../../x86_64-pc-linux-gnu/lib" -// CHECK-LD-GENTOO: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../.." // CHECK-LD-GENTOO: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" // CHECK-LD-GENTOO: "-lc" // CHECK-LD-GENTOO: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" @@ -2067,7 +1792,6 @@ // CHECK-LD-GENTOO-32: "{{.*}}/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/32{{/|\\\\}}crtbegin.o" // CHECK-LD-GENTOO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/32" // CHECK-LD-GENTOO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../../../x86_64-pc-linux-gnu/lib" -// CHECK-LD-GENTOO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../.." // CHECK-LD-GENTOO-32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" // CHECK-LD-GENTOO-32: "-lc" // CHECK-LD-GENTOO-32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" @@ -2084,7 +1808,6 @@ // CHECK-LD-GENTOO-X32: "{{.*}}/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/x32{{/|\\\\}}crtbegin.o" // CHECK-LD-GENTOO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/x32" // CHECK-LD-GENTOO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../../../x86_64-pc-linux-gnu/lib" -// CHECK-LD-GENTOO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../.." // CHECK-LD-GENTOO-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" // CHECK-LD-GENTOO-X32: "-lc" // CHECK-LD-GENTOO-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" @@ -2113,7 +1836,6 @@ // CHECK-LD-AMI: "{{.*}}/usr/lib/gcc/x86_64-amazon-linux/7{{/|\\\\}}crtbegin.o" // CHECK-LD-AMI: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-amazon-linux/7" // CHECK-LD-AMI: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-amazon-linux/7/../../../../lib64" -// CHECK-LD-AMI: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-amazon-linux/7/../../.." // CHECK-LD-AMI: "-L[[SYSROOT]]/lib" // CHECK-LD-AMI: "-L[[SYSROOT]]/usr/lib" // CHECK-LD-AMI: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" @@ -2134,7 +1856,6 @@ // CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0/../../../lib{{/|\\\\}}crti.o" // CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0{{/|\\\\}}crtbegin.o" // CHECK-OE-ARM: "-L[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0" -// CHECK-OE-ARM: "-L[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi" // CHECK-OE-ARM: "-L[[SYSROOT]]/usr/lib" // CHECK-OE-ARM: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" // CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0{{/|\\\\}}crtend.o" diff --git a/clang/test/Driver/lit.local.cfg b/clang/test/Driver/lit.local.cfg index 7ab6c29ec948..fe5d67a0f45b 100644 --- a/clang/test/Driver/lit.local.cfg +++ b/clang/test/Driver/lit.local.cfg @@ -1,5 +1,5 @@ config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.F90', '.f95', - '.cu', '.rs', '.cl', '.hip'] + '.cu', '.rs', '.cl', '.clcpp', '.hip'] config.substitutions = list(config.substitutions) config.substitutions.insert(0, ('%clang_cc1', diff --git a/clang/test/Driver/mips-reduced-toolchain.cpp b/clang/test/Driver/mips-reduced-toolchain.cpp index 894bdb5a756b..13e30a5687f1 100644 --- a/clang/test/Driver/mips-reduced-toolchain.cpp +++ b/clang/test/Driver/mips-reduced-toolchain.cpp @@ -9,9 +9,7 @@ // CHECK-DEBIAN-MIPS: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-DEBIAN-MIPS: "{{.*}}/usr/lib/gcc/mips-linux-gnu/4.7{{/|\\\\}}crtbegin.o" // CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7" -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7/../../../mips-linux-gnu" // CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/mips-linux-gnu" -// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7/../../.." // CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib" @@ -23,8 +21,6 @@ // CHECK-DEBIAN-MIPSEL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-DEBIAN-MIPSEL: "{{.*}}/usr/lib/gcc/mipsel-linux-gnu/4.7{{/|\\\\}}crtbegin.o" // CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7" -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7/../../../mipsel-linux-gnu" // CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/mipsel-linux-gnu" -// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7/../../.." // CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib" diff --git a/clang/test/Driver/msvc-link.c b/clang/test/Driver/msvc-link.c index 13dccd21bfd8..1ee17fc63c32 100644 --- a/clang/test/Driver/msvc-link.c +++ b/clang/test/Driver/msvc-link.c @@ -1,4 +1,4 @@ -// RUN: %clang -target i686-pc-windows-msvc -### %s 2>&1 | FileCheck --check-prefix=BASIC %s +// RUN: %clang -target i686-pc-windows-msvc -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=BASIC %s // BASIC: link.exe" // BASIC: "-out:a.exe" // BASIC: "-defaultlib:libcmt" @@ -6,7 +6,7 @@ // BASIC: "-nologo" // BASIC-NOT: "-Brepro" -// RUN: %clang -target i686-pc-windows-msvc -shared -o a.dll -### %s 2>&1 | FileCheck --check-prefix=DLL %s +// RUN: %clang -target i686-pc-windows-msvc -shared -o a.dll -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=DLL %s // DLL: link.exe" // DLL: "-out:a.dll" // DLL: "-defaultlib:libcmt" @@ -19,13 +19,13 @@ // LIBPATH: "-libpath:/usr/lib" // LIBPATH: "-nologo" -// RUN: %clang_cl /Brepro -### -- %s 2>&1 | FileCheck --check-prefix=REPRO %s +// RUN: %clang_cl /Brepro -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=REPRO %s // REPRO: link.exe" // REPRO: "-out:msvc-link.exe" // REPRO: "-nologo" // REPRO: "-Brepro" -// RUN: %clang_cl /Brepro- -### -- %s 2>&1 | FileCheck --check-prefix=NOREPRO %s +// RUN: %clang_cl /Brepro- -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=NOREPRO %s // NOREPRO: link.exe" // NOREPRO: "-out:msvc-link.exe" // NOREPRO: "-nologo" diff --git a/clang/test/Driver/nostdincxx.cpp b/clang/test/Driver/nostdincxx.cpp index dc87336ece54..3fc7a5e76842 100644 --- a/clang/test/Driver/nostdincxx.cpp +++ b/clang/test/Driver/nostdincxx.cpp @@ -1,4 +1,6 @@ +// RUN: not %clangxx -nostdinc %s 2>&1 | FileCheck %s // RUN: not %clangxx -nostdinc++ %s 2>&1 | FileCheck %s +// RUN: not %clangxx -nostdlibinc %s 2>&1 | FileCheck %s // CHECK: file not found #include diff --git a/clang/test/Driver/ppc-mprivileged-support-check.c b/clang/test/Driver/ppc-mprivileged-support-check.c new file mode 100644 index 000000000000..164b4d9483d3 --- /dev/null +++ b/clang/test/Driver/ppc-mprivileged-support-check.c @@ -0,0 +1,26 @@ +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr10 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power10 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr9 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power9 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr8 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power8 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV + +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr7 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=NOPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power7 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=NOPRIV + +#ifdef __PRIVILEGED__ +static_assert(false, "Privileged instructions enabled"); +#endif + +// HASPRIV: Privileged instructions enabled +// HASPRIV-NOT: option '-mprivileged' cannot be specified with +// NOPRIV: option '-mprivileged' cannot be specified with + diff --git a/clang/test/Driver/ppc-mrop-protection-support-check.c b/clang/test/Driver/ppc-mrop-protection-support-check.c index c2761d21c9d1..50eaef3ed770 100644 --- a/clang/test/Driver/ppc-mrop-protection-support-check.c +++ b/clang/test/Driver/ppc-mrop-protection-support-check.c @@ -1,26 +1,26 @@ // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=pwr10 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: -mcpu=pwr10 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=HASROP // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=power10 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: -mcpu=power10 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=HASROP // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=pwr9 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: -mcpu=pwr9 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=HASROP // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=power9 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: -mcpu=power9 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=HASROP // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=pwr8 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: -mcpu=pwr8 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=HASROP // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=power8 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: -mcpu=power8 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=HASROP // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=pwr7 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=NOROP +// RUN: -mcpu=pwr7 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=NOROP // RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ -// RUN: -mcpu=power7 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=NOROP +// RUN: -mcpu=power7 -mrop-protect %s 2>&1 | FileCheck %s --check-prefix=NOROP -#ifdef __ROP_PROTECTION__ -static_assert(false, "ROP Protection enabled"); +#ifdef __ROP_PROTECT__ +static_assert(false, "ROP Protect enabled"); #endif -// HASROP: ROP Protection enabled -// HASROP-NOT: option '-mrop-protection' cannot be specified with -// NOROP: option '-mrop-protection' cannot be specified with +// HASROP: ROP Protect enabled +// HASROP-NOT: option '-mrop-protect' cannot be specified with +// NOROP: option '-mrop-protect' cannot be specified with diff --git a/clang/test/Driver/print-multi-directory.c b/clang/test/Driver/print-multi-directory.c index 5fb6a118e115..2504c28ba994 100644 --- a/clang/test/Driver/print-multi-directory.c +++ b/clang/test/Driver/print-multi-directory.c @@ -19,7 +19,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>/dev/null \ // RUN: -target arm-linux-androideabi21 \ // RUN: -mthumb \ -// RUN: -B%S/Inputs/basic_android_ndk_tree \ +// RUN: --gcc-toolchain=%S/Inputs/basic_android_ndk_tree \ // RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \ // RUN: -print-multi-directory \ // RUN: | FileCheck --match-full-lines --check-prefix=CHECK-ARM-MULTILIBS %s diff --git a/clang/test/Driver/relative-vtables-flag.cpp b/clang/test/Driver/relative-vtables-flag.cpp new file mode 100644 index 000000000000..1253809e1d42 --- /dev/null +++ b/clang/test/Driver/relative-vtables-flag.cpp @@ -0,0 +1,7 @@ +// RUN: %clangxx --target=aarch64-unknown-fuchsia -fexperimental-relative-c++-abi-vtables -c %s -### 2>&1 | FileCheck %s --check-prefix=RV +// RUN: %clangxx --target=aarch64-unknown-fuchsia -fno-experimental-relative-c++-abi-vtables -c %s -### 2>&1 | FileCheck %s --check-prefix=NO-RV +// RUN: %clangxx --target=aarch64-unknown-fuchsia -c %s -### 2>&1 | FileCheck %s --check-prefix=NO-RV +// RUN: %clangxx --target=aarch64-unknown-linux-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=NO-RV + +// RV: "-fexperimental-relative-c++-abi-vtables" +// NO-RV-NOT: "-fexperimental-relative-c++-abi-vtables" diff --git a/clang/test/Driver/rocm-detect.hip b/clang/test/Driver/rocm-detect.hip index cd3c2d90fe88..1e21323ba218 100644 --- a/clang/test/Driver/rocm-detect.hip +++ b/clang/test/Driver/rocm-detect.hip @@ -21,6 +21,20 @@ // RUN: --rocm-path=%S/Inputs/rocm %s 2>&1 \ // RUN: | FileCheck -check-prefixes=COMMON,NODEFAULTLIBS %s +// Test environment variable ROCM_PATH. +// RUN: env ROCM_PATH=%S/Inputs/rocm %clang -### -target x86_64-linux-gnu \ +// RUN: --print-rocm-search-dirs %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=ROCM-ENV %s + +// Test detecting latest /opt/rocm-{release} directory. +// RUN: rm -rf %T/opt +// RUN: mkdir -p %T/opt +// RUN: cp -r %S/Inputs/rocm %T/opt/rocm-3.9.0-1234 +// RUN: cp -r %S/Inputs/rocm %T/opt/rocm-3.10.0 +// RUN: %clang -### -target x86_64-linux-gnu --sysroot=%T \ +// RUN: --print-rocm-search-dirs %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=ROCM-REL %s + // Test ROCm installation built by SPACK by invoke clang at %T/rocm-spack/llvm-amdgpu-* // directory through a soft link. @@ -60,6 +74,11 @@ // COMMON: "-triple" "amdgcn-amd-amdhsa" +// ROCM-ENV: ROCm installation search path: {{.*}}/Inputs/rocm + +// ROCM-REL: ROCm installation search path: {{.*}}/opt/rocm +// ROCM-REL: ROCm installation search path: {{.*}}/opt/rocm-3.10.0 + // SPACK: ROCm installation search path (Spack 4.0.0): [[DIR:.*]] // SPACK: ROCm installation search path: [[CLANG:.*]] // SPACK: ROCm installation search path: [[CLANG]]/lib/clang/{{[0-9.]+}} diff --git a/clang/test/Driver/stdlibxx-isystem.cpp b/clang/test/Driver/stdlibxx-isystem.cpp index 827cdf9a7c71..cadfa25c0db9 100644 --- a/clang/test/Driver/stdlibxx-isystem.cpp +++ b/clang/test/Driver/stdlibxx-isystem.cpp @@ -43,11 +43,19 @@ // RUN: FileCheck -check-prefix=NOCC1 %s // NOCC1-NOT: "-stdlib++-isystem" "/tmp" -// It should respect -nostdinc++. +// It should respect -nostdinc++ // RUN: %clang -target aarch64-linux-gnu -ccc-install-dir %t/bin \ // RUN: -stdlib++-isystem /tmp/foo -stdlib++-isystem /tmp/bar -nostdinc++ \ // RUN: -fsyntax-only %s -### 2>&1 | FileCheck -check-prefix=NOSTDINCXX %s // RUN: %clang -target x86_64-apple-darwin -ccc-install-dir %t/bin \ // RUN: -stdlib++-isystem /tmp/foo -stdlib++-isystem /tmp/bar -nostdinc++ \ // RUN: -fsyntax-only %s -### 2>&1 | FileCheck -check-prefix=NOSTDINCXX %s + +// ... and -nostdinc and -nostdlibinc. +// RUN: %clang -target aarch64-linux-gnu -ccc-install-dir %t/bin \ +// RUN: -stdlib++-isystem /tmp/foo -stdlib++-isystem /tmp/bar -nostdinc \ +// RUN: -fsyntax-only %s -### 2>&1 | FileCheck --check-prefix=NOSTDINCXX %s +// RUN: %clang -target aarch64-linux-gnu -ccc-install-dir %t/bin \ +// RUN: -stdlib++-isystem /tmp/foo -stdlib++-isystem /tmp/bar -nostdlibinc \ +// RUN: -fsyntax-only %s -### 2>&1 | FileCheck --check-prefix=NOSTDINCXX %s // NOSTDINCXX-NOT: "-internal-isystem" "/tmp/foo" "-internal-isystem" "/tmp/bar" diff --git a/clang/test/Driver/verify-debug-info-preservation.c b/clang/test/Driver/verify-debug-info-preservation.c new file mode 100644 index 000000000000..81c1ff7d02a2 --- /dev/null +++ b/clang/test/Driver/verify-debug-info-preservation.c @@ -0,0 +1,19 @@ +// We support the CC1 options for testing whether each LLVM pass preserves +// original debug info. + +// RUN: %clang -g -Xclang -fverify-debuginfo-preserve -### %s 2>&1 \ +// RUN: | FileCheck --check-prefix=VERIFYDIPRESERVE %s + +// VERIFYDIPRESERVE: "-fverify-debuginfo-preserve" + +// RUN: %clang -g -Xclang -fverify-debuginfo-preserve \ +// RUN: -Xclang -fverify-debuginfo-preserve-export=%t.json -### %s 2>&1 \ +// RUN: | FileCheck --check-prefix=VERIFYDIPRESERVE-JSON-EXPORT %s + +// VERIFYDIPRESERVE-JSON-EXPORT: "-fverify-debuginfo-preserve" +// VERIFYDIPRESERVE-JSON-EXPORT: "-fverify-debuginfo-preserve-export={{.*}}" + +// RUN: %clang -g -Xclang -fverify-debuginfo-preserve-export=%t.json %s -S -o /dev/null 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN %s + +// WARN: warning: ignoring -fverify-debuginfo-preserve-export diff --git a/clang/test/Driver/wasm-toolchain.c b/clang/test/Driver/wasm-toolchain.c index 17037819cfda..d2e6de4667ac 100644 --- a/clang/test/Driver/wasm-toolchain.c +++ b/clang/test/Driver/wasm-toolchain.c @@ -79,6 +79,21 @@ // RUN: | FileCheck -check-prefix=PTHREAD_NO_SIGN_EXT %s // PTHREAD_NO_SIGN_EXT: invalid argument '-pthread' not allowed with '-mno-sign-ext' +// '-mllvm -emscripten-cxx-exceptions-allowed=foo,bar' sets +// '-mllvm --force-attribute=foo:noinline -mllvm --force-attribute=bar:noinline' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -enable-emscripten-cxx-exceptions \ +// RUN: -mllvm -emscripten-cxx-exceptions-allowed=foo,bar 2>&1 \ +// RUN: | FileCheck -check-prefix=EMSCRIPTEN_EH_ALLOWED_NOINLINE %s +// EMSCRIPTEN_EH_ALLOWED_NOINLINE: clang{{.*}}" "-cc1" {{.*}} "-mllvm" "--force-attribute=foo:noinline" "-mllvm" "--force-attribute=bar:noinline" + +// '-mllvm -emscripten-cxx-exceptions-allowed' only allowed with +// '-mllvm -enable-emscripten-cxx-exceptions' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -emscripten-cxx-exceptions-allowed 2>&1 \ +// RUN: | FileCheck -check-prefix=EMSCRIPTEN_EH_ALLOWED_WO_ENABLE %s +// EMSCRIPTEN_EH_ALLOWED_WO_ENABLE: invalid argument '-mllvm -emscripten-cxx-exceptions-allowed' only allowed with '-mllvm -enable-emscripten-cxx-exceptions' + // '-fwasm-exceptions' sets +exception-handling // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ // RUN: --sysroot=/foo %s -fwasm-exceptions 2>&1 \ diff --git a/clang/test/FixIt/fixit-c++11.cpp b/clang/test/FixIt/fixit-c++11.cpp index 70342075a15e..9a2020c41870 100644 --- a/clang/test/FixIt/fixit-c++11.cpp +++ b/clang/test/FixIt/fixit-c++11.cpp @@ -56,8 +56,12 @@ void S2::f(int i) { (void)[&, &i, &i]{}; // expected-error 2{{'&' cannot precede a capture when the capture default is '&'}} (void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}} (void)[&, i, i]{ }; // expected-error{{'i' can appear only once in a capture list}} - (void)[] mutable { }; // expected-error{{lambda requires '()' before 'mutable'}} - (void)[] -> int { }; // expected-error{{lambda requires '()' before return type}} + (void)[] mutable {}; + (void)[]->int{}; +#if __cplusplus <= 202002L + // expected-warning@-3{{is a C++2b extension}} + // expected-warning@-3{{is a C++2b extension}} +#endif delete []() { return new int; }(); // expected-error{{'[]' after delete interpreted as 'delete[]'}} delete [] { return new int; }(); // expected-error{{'[]' after delete interpreted as 'delete[]'}} diff --git a/clang/test/FixIt/fixit-cxx-init-order.cpp b/clang/test/FixIt/fixit-cxx-init-order.cpp new file mode 100644 index 000000000000..f39c8bf2a15c --- /dev/null +++ b/clang/test/FixIt/fixit-cxx-init-order.cpp @@ -0,0 +1,22 @@ +// Due to the fix having multiple edits we can't use +// '-fdiagnostics-parseable-fixits' to determine if fixes are correct. However, +// running fixit recompile with 'Werror' should fail if the fixes are invalid. + +// RUN: %clang_cc1 %s -Werror=reorder-ctor -fixit-recompile -fixit-to-temporary +// RUN: %clang_cc1 %s -Wreorder-ctor -verify -verify-ignore-unexpected=note + +struct Foo { + int A, B, C; + + Foo() : A(1), B(3), C(2) {} + Foo(int) : A(1), C(2), B(3) {} // expected-warning {{field 'C' will be initialized after field 'B'}} + Foo(unsigned) : C(2), B(3), A(1) {} // expected-warning {{initializer order does not match the declaration order}} +}; + +struct Bar : Foo { + int D, E, F; + + Bar() : Foo(), D(1), E(2), F(3) {} + Bar(int) : D(1), E(2), F(3), Foo(4) {} // expected-warning {{field 'F' will be initialized after base 'Foo'}} + Bar(unsigned) : F(3), E(2), D(1), Foo(4) {} // expected-warning {{initializer order does not match the declaration order}} +}; diff --git a/clang/test/FixIt/format.m b/clang/test/FixIt/format.m index ef27b1bac353..0d173846d0ad 100644 --- a/clang/test/FixIt/format.m +++ b/clang/test/FixIt/format.m @@ -169,6 +169,12 @@ void test_char(char c, signed char s, unsigned char u, uint8_t n) { NSLog(@"%@", 'abcd'); // expected-warning{{format specifies type 'id' but the argument has type 'int'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d" + + NSLog(@"%hhd", 'a'); // expected-warning{{format specifies type 'char' but the argument has type 'int'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:15}:"%d" + + NSLog(@"%hhu", 'a'); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'int'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:15}:"%d" } void multichar_constants_false_negative() { diff --git a/clang/test/Frontend/optimization-remark-options.c b/clang/test/Frontend/optimization-remark-options.c index 38dbbfbaccec..3509a388d0f6 100644 --- a/clang/test/Frontend/optimization-remark-options.c +++ b/clang/test/Frontend/optimization-remark-options.c @@ -1,6 +1,7 @@ +// REQUIRES: x86-registered-target // RUN: %clang -O1 -fvectorize -target x86_64-unknown-unknown -Rpass-analysis=loop-vectorize -emit-llvm -S %s -o - 2>&1 | FileCheck %s -// CHECK: {{.*}}:9:11: remark: loop not vectorized: cannot prove it is safe to reorder floating-point operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop or by providing the compiler option '-ffast-math'. +// CHECK: {{.*}}:10:11: remark: loop not vectorized: cannot prove it is safe to reorder floating-point operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop or by providing the compiler option '-ffast-math'. double foo(int N) { double v = 0.0; @@ -11,7 +12,7 @@ double foo(int N) { return v; } -// CHECK: {{.*}}:17:3: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied! +// CHECK: {{.*}}:18:3: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied! void foo2(int *dw, int *uw, int *A, int *B, int *C, int *D, int N) { for (long i = 0; i < N; i++) { diff --git a/clang/test/Frontend/sycl-aux-triple.cpp b/clang/test/Frontend/sycl-aux-triple.cpp index ae36b53c28b7..38b6a24fb3ce 100644 --- a/clang/test/Frontend/sycl-aux-triple.cpp +++ b/clang/test/Frontend/sycl-aux-triple.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -triple spir -aux-triple x86_64-unknown-linux-gnu -E -dM | FileCheck %s -// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -triple spir -aux-triple x86_64-unknown-linux-gnu -E -dM | FileCheck --check-prefix=CHECK-SYCL %s +// RUN: %clang_cc1 %s -fsycl-is-device -triple spir -aux-triple x86_64-unknown-linux-gnu -E -dM | FileCheck --check-prefix=CHECK-SYCL %s // CHECK-NOT:#define __x86_64__ 1 // CHECK-SYCL:#define __x86_64__ 1 diff --git a/clang/test/Frontend/sycl.cpp b/clang/test/Frontend/sycl.cpp new file mode 100644 index 000000000000..61a30d561d83 --- /dev/null +++ b/clang/test/Frontend/sycl.cpp @@ -0,0 +1,13 @@ +// Test that we disallow -cc1 -fsycl, even when specifying device or host mode. + +// RUN: not %clang_cc1 -fsycl %s 2>&1 | FileCheck --check-prefix=ERROR %s +// RUN: not %clang_cc1 -fsycl -fsycl-is-device %s 2>&1 | FileCheck --check-prefix=ERROR %s +// RUN: not %clang_cc1 -fsycl -fsycl-is-host %s 2>&1 | FileCheck --check-prefix=ERROR %s + +// ERROR: error: unknown argument: '-fsycl' + +// Test that you cannot specify -fsycl-is-device and -fsycl-is-host at the same time. +// RUN: not %clang_cc1 -fsycl-is-device -fsycl-is-host %s 2>&1 | FileCheck --check-prefix=ERROR-BOTH %s +// RUN: not %clang_cc1 -fsycl-is-host -fsycl-is-device %s 2>&1 | FileCheck --check-prefix=ERROR-BOTH %s + +// ERROR-BOTH: error: invalid argument '-fsycl-is-device' not allowed with '-fsycl-is-host' diff --git a/clang/test/Headers/opencl-c-header.cl b/clang/test/Headers/opencl-c-header.cl index 432c5e461d55..f72cea61fcd9 100644 --- a/clang/test/Headers/opencl-c-header.cl +++ b/clang/test/Headers/opencl-c-header.cl @@ -2,6 +2,7 @@ // RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL1.1 | FileCheck %s // RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL1.2 | FileCheck %s // RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=clc++ | FileCheck %s --check-prefix=CHECK20 +// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL3.0 | FileCheck %s // Test including the default header as a module. // The module should be compiled only once and loaded from cache afterwards. @@ -81,7 +82,7 @@ void test_atomics(__generic volatile unsigned int* a) { #endif // Verify that ATOMIC_VAR_INIT is defined. -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ == CL_VERSION_2_0) global atomic_int z = ATOMIC_VAR_INIT(99); #endif //__OPENCL_C_VERSION__ // CHECK-MOD: Reading modules diff --git a/clang/test/Headers/riscv-vector-header.c b/clang/test/Headers/riscv-vector-header.c new file mode 100644 index 000000000000..beb54a30ee70 --- /dev/null +++ b/clang/test/Headers/riscv-vector-header.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple riscv64 -fsyntax-only \ +// RUN: -target-feature +m -target-feature +a -target-feature +f \ +// RUN: -target-feature +d -target-feature +experimental-v %s +// expected-no-diagnostics + +#include diff --git a/clang/test/Index/cxx.cl b/clang/test/Index/cxx.cl index f4b03d78740e..997d4288669f 100644 --- a/clang/test/Index/cxx.cl +++ b/clang/test/Index/cxx.cl @@ -3,5 +3,5 @@ void test(int *ptr) { addrspace_cast<__global int*>(ptr); } -// RUN: c-index-test -test-load-source all %s -cl-std=clc++ | FileCheck %s +// RUN: c-index-test -test-load-source all %s -cl-std=clc++ -target spir | FileCheck %s // CHECK: cxx.cl:3:3: CXXAddrspaceCastExpr diff --git a/clang/test/Index/opencl-types.cl b/clang/test/Index/opencl-types.cl index 496f38752fa2..485060167d21 100644 --- a/clang/test/Index/opencl-types.cl +++ b/clang/test/Index/opencl-types.cl @@ -1,4 +1,4 @@ -// RUN: c-index-test -test-print-type %s -cl-std=CL2.0 | FileCheck %s +// RUN: c-index-test -test-print-type %s -cl-std=CL2.0 -target spir | FileCheck %s #pragma OPENCL EXTENSION cl_khr_fp16 : enable #pragma OPENCL EXTENSION cl_khr_fp64 : enable diff --git a/clang/test/Index/symbol-visibility.c b/clang/test/Index/symbol-visibility.c index 014e80f81878..4a8179dddff3 100644 --- a/clang/test/Index/symbol-visibility.c +++ b/clang/test/Index/symbol-visibility.c @@ -1,4 +1,4 @@ -// RUN: c-index-test -test-print-visibility %s | FileCheck %s +// RUN: c-index-test -test-print-visibility -fvisibility=default %s | FileCheck %s __attribute__ ((visibility ("default"))) void foo1(); __attribute__ ((visibility ("hidden"))) void foo2(); diff --git a/clang/test/Layout/itanium-union-bitfield.cpp b/clang/test/Layout/itanium-union-bitfield.cpp index 961bf5b6f3b4..febfc46dfee5 100644 --- a/clang/test/Layout/itanium-union-bitfield.cpp +++ b/clang/test/Layout/itanium-union-bitfield.cpp @@ -1,15 +1,23 @@ // RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -fdump-record-layouts %s 2>/dev/null \ // RUN: | FileCheck %s +// On z/OS, a bit-field has single byte alignment. Add aligned(4) on z/OS so the union has +// the same size & alignment as expected. +#ifdef __MVS__ +#define ALIGN4 __attribute__((aligned(4))) +#else +#define ALIGN4 +#endif + union A { - int f1: 3; + int f1 : 3 ALIGN4; A(); }; A::A() {} union B { - char f1: 35; + char f1 : 35 ALIGN4; B(); }; diff --git a/clang/test/Lexer/c2x_digit_separators.c b/clang/test/Lexer/c2x_digit_separators.c new file mode 100644 index 000000000000..3eff8f7cf700 --- /dev/null +++ b/clang/test/Lexer/c2x_digit_separators.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -std=c2x -verify %s + +_Static_assert(1'2'3 == 12'3, ""); +_Static_assert(1'000'000 == 0xf'4240, ""); +_Static_assert(0'004'000'000 == 0x10'0000, ""); +_Static_assert(0b0101'0100 == 0x54, ""); + +int a0 = 123'; //'; // expected-error {{expected ';'}} +int b0 = 0'xff; // expected-error {{digit separator cannot appear at end of digit sequence}} expected-error {{suffix 'xff' on integer}} +int c0 = 0x'ff; // expected-error {{suffix 'x'ff' on integer}} +int d0 = 0'1234; // ok, octal +int e0 = 0'b1010; // expected-error {{digit 'b' in octal constant}} +int f0 = 0b'1010; // expected-error {{invalid digit 'b' in octal}} +int h0 = 0x1e+1; // expected-error {{invalid suffix '+1' on integer constant}} +int i0 = 0x1'e+1; // ok, 'e+' is not recognized after a digit separator + +float a1 = 1'e1; // expected-error {{digit separator cannot appear at end of digit sequence}} +float b1 = 1'0e1; +float c1 = 1.'0e1; // expected-error {{digit separator cannot appear at start of digit sequence}} +float d1 = 1.0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}} +float e1 = 1e'1; // expected-error {{digit separator cannot appear at start of digit sequence}} +float g1 = 0.'0; // expected-error {{digit separator cannot appear at start of digit sequence}} +float h1 = .'0; // '; // expected-error {{expected expression}}, lexed as . followed by character literal +float i1 = 0x.'0p0; // expected-error {{digit separator cannot appear at start of digit sequence}} +float j1 = 0x'0.0p0; // expected-error {{invalid suffix 'x'0.0p0'}} +float k1 = 0x0'.0p0; // '; // expected-error {{expected ';'}} +float l1 = 0x0.'0p0; // expected-error {{digit separator cannot appear at start of digit sequence}} +float m1 = 0x0.0'p0; // expected-error {{digit separator cannot appear at end of digit sequence}} +float n1 = 0x0.0p'0; // expected-error {{digit separator cannot appear at start of digit sequence}} +float p1 = 0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}} +float q1 = 0'0e1; +float r1 = 0.'0e1; // expected-error {{digit separator cannot appear at start of digit sequence}} +float s1 = 0.0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}} +float t1 = 0.0e'1; // expected-error {{digit separator cannot appear at start of digit sequence}} +float u1 = 0x.'p1f; // expected-error {{hexadecimal floating constant requires a significand}} +float v1 = 0e'f; // expected-error {{exponent has no digits}} +float w1 = 0x0p'f; // expected-error {{exponent has no digits}} +float x1 = 0'e+1; // expected-error {{digit separator cannot appear at end of digit sequence}} +float y1 = 0x0'p+1; // expected-error {{digit separator cannot appear at end of digit sequence}} + +#line 123'456 +_Static_assert(__LINE__ == 123456, ""); + +// UCNs can appear before digit separators but not after. +int a2 = 0\u1234'5; // expected-error {{invalid suffix '\u1234'5' on integer constant}} +int b2 = 0'\u12345; // '; // expected-error {{expected ';'}} + +// extended characters can appear before digit separators but not after. +int a3 = 0ሴ'5; // expected-error {{invalid suffix 'ሴ'5' on integer constant}} +int b3 = 0'ሴ5; // '; // expected-error {{expected ';'}} + diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp index 2f46f354ee83..22ac5567c1d8 100644 --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -29,6 +29,12 @@ #define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23) (cxx23 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx23) #endif +// --- C++2b features --- + +#if check(size_t_suffix, 0, 0, 0, 0, 0, 202011) +#error "wrong value for __cpp_size_t_suffix" +#endif + // --- C++20 features --- #if check(aggregate_paren_init, 0, 0, 0, 0, 0, 0) diff --git a/clang/test/Lexer/size_t-literal.cpp b/clang/test/Lexer/size_t-literal.cpp new file mode 100644 index 000000000000..3e3e8094b070 --- /dev/null +++ b/clang/test/Lexer/size_t-literal.cpp @@ -0,0 +1,167 @@ +// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify %s + +#if 1z != 1 +#error "z suffix must be recognized by preprocessor" +#endif +#if 1uz != 1 +#error "uz suffix must be recognized by preprocessor" +#endif +#if !(-1z < 0) +#error "z suffix must be interpreted as signed" +#endif +#if !(-1uz > 0) +#error "uz suffix must be interpreted as unsigned" +#endif + +void ValidSuffix() { + // Decimal literals. + { + auto a1 = 1z; + auto a2 = 1Z; + + auto a3 = 1uz; + auto a4 = 1uZ; + auto a5 = 1Uz; + auto a6 = 1UZ; + + auto a7 = 1zu; + auto a8 = 1Zu; + auto a9 = 1zU; + auto a10 = 1ZU; + + auto a11 = 1'2z; + auto a12 = 1'2Z; + } + // Hexadecimal literals. + { + auto a1 = 0x1z; + auto a2 = 0x1Z; + + auto a3 = 0x1uz; + auto a4 = 0x1uZ; + auto a5 = 0x1Uz; + auto a6 = 0x1UZ; + + auto a7 = 0x1zu; + auto a8 = 0x1Zu; + auto a9 = 0x1zU; + auto a10 = 0x1ZU; + + auto a11 = 0x1'2z; + auto a12 = 0x1'2Z; + } + // Binary literals. + { + auto a1 = 0b1z; + auto a2 = 0b1Z; + + auto a3 = 0b1uz; + auto a4 = 0b1uZ; + auto a5 = 0b1Uz; + auto a6 = 0b1UZ; + + auto a7 = 0b1zu; + auto a8 = 0b1Zu; + auto a9 = 0b1zU; + auto a10 = 0b1ZU; + + auto a11 = 0b1'1z; + auto a12 = 0b1'1Z; + } + // Octal literals. + { + auto a1 = 01z; + auto a2 = 01Z; + + auto a3 = 01uz; + auto a4 = 01uZ; + auto a5 = 01Uz; + auto a6 = 01UZ; + + auto a7 = 01zu; + auto a8 = 01Zu; + auto a9 = 01zU; + auto a10 = 01ZU; + + auto a11 = 0'1z; + auto a12 = 0'1Z; + } +} + +void InvalidSuffix() { + // Long. + { + auto a1 = 1lz; // expected-error {{invalid suffix}} + auto a2 = 1lZ; // expected-error {{invalid suffix}} + auto a3 = 1Lz; // expected-error {{invalid suffix}} + auto a4 = 1LZ; // expected-error {{invalid suffix}} + + auto a5 = 1zl; // expected-error {{invalid suffix}} + auto a6 = 1Zl; // expected-error {{invalid suffix}} + auto a7 = 1zL; // expected-error {{invalid suffix}} + auto a8 = 1ZL; // expected-error {{invalid suffix}} + + auto a9 = 1ulz; // expected-error {{invalid suffix}} + auto a10 = 1ulZ; // expected-error {{invalid suffix}} + auto a11 = 1uLz; // expected-error {{invalid suffix}} + auto a12 = 1uLZ; // expected-error {{invalid suffix}} + + auto a13 = 1uzl; // expected-error {{invalid suffix}} + auto a14 = 1uZl; // expected-error {{invalid suffix}} + auto a15 = 1uzL; // expected-error {{invalid suffix}} + auto a16 = 1uZL; // expected-error {{invalid suffix}} + } + // Long long. + { + auto a1 = 1llz; // expected-error {{invalid suffix}} + auto a2 = 1llZ; // expected-error {{invalid suffix}} + auto a3 = 1LLz; // expected-error {{invalid suffix}} + auto a4 = 1LLZ; // expected-error {{invalid suffix}} + + auto a5 = 1zll; // expected-error {{invalid suffix}} + auto a6 = 1Zll; // expected-error {{invalid suffix}} + auto a7 = 1zLL; // expected-error {{invalid suffix}} + auto a8 = 1ZLL; // expected-error {{invalid suffix}} + + auto a9 = 1ullz; // expected-error {{invalid suffix}} + auto a10 = 1ullZ; // expected-error {{invalid suffix}} + auto a11 = 1uLLz; // expected-error {{invalid suffix}} + auto a12 = 1uLLZ; // expected-error {{invalid suffix}} + + auto a13 = 1uzll; // expected-error {{invalid suffix}} + auto a14 = 1uZll; // expected-error {{invalid suffix}} + auto a15 = 1uzLL; // expected-error {{invalid suffix}} + auto a16 = 1uZLL; // expected-error {{invalid suffix}} + } + // Floating point. + { + auto a1 = 0.1z; // expected-error {{invalid suffix}} + auto a2 = 0.1Z; // expected-error {{invalid suffix}} + auto a3 = 0.1uz; // expected-error {{invalid suffix}} + auto a4 = 0.1uZ; // expected-error {{invalid suffix}} + auto a5 = 0.1Uz; // expected-error {{invalid suffix}} + auto a6 = 0.1UZ; // expected-error {{invalid suffix}} + auto a7 = 0.1zu; // expected-error {{invalid suffix}} + auto a8 = 0.1Zu; // expected-error {{invalid suffix}} + auto a9 = 0.1zU; // expected-error {{invalid suffix}} + auto a10 = 0.1ZU; // expected-error {{invalid suffix}} + + auto a11 = 0.1fz; // expected-error {{invalid suffix}} + auto a12 = 0.1fZ; // expected-error {{invalid suffix}} + auto a13 = 0.1fuz; // expected-error {{invalid suffix}} + auto a14 = 0.1fuZ; // expected-error {{invalid suffix}} + auto a15 = 0.1fUz; // expected-error {{invalid suffix}} + auto a16 = 0.1fUZ; // expected-error {{invalid suffix}} + auto a17 = 0.1fzu; // expected-error {{invalid suffix}} + auto a18 = 0.1fZu; // expected-error {{invalid suffix}} + auto a19 = 0.1fzU; // expected-error {{invalid suffix}} + auto a110 = 0.1fZU; // expected-error {{invalid suffix}} + } + // Repetitive suffix. + { + auto a1 = 1zz; // expected-error {{invalid suffix}} + auto a2 = 1zZ; // expected-error {{invalid suffix}} + auto a3 = 1Zz; // expected-error {{invalid suffix}} + auto a4 = 1ZZ; // expected-error {{invalid suffix}} + } +} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index dd9cd79e69dc..fd56bd197586 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -154,6 +154,7 @@ // CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property) // CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member) // CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method) +// CHECK-NEXT: StandaloneDebug (SubjectMatchRule_record) // CHECK-NEXT: SwiftAsync (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: SwiftAsyncError (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: SwiftAsyncName (SubjectMatchRule_objc_method, SubjectMatchRule_function) diff --git a/clang/test/Modules/Inputs/lsv-private-macro/mod.map b/clang/test/Modules/Inputs/lsv-private-macro/mod.map new file mode 100644 index 000000000000..62b92fb63e79 --- /dev/null +++ b/clang/test/Modules/Inputs/lsv-private-macro/mod.map @@ -0,0 +1,7 @@ +module self { + header "self.h" +} + +module other { + header "other.h" +} diff --git a/clang/test/Modules/Inputs/lsv-private-macro/other.h b/clang/test/Modules/Inputs/lsv-private-macro/other.h new file mode 100644 index 000000000000..356eccaec27f --- /dev/null +++ b/clang/test/Modules/Inputs/lsv-private-macro/other.h @@ -0,0 +1,7 @@ +#define OTHER_PRIVATE +#__private_macro OTHER_PRIVATE + +#define OTHER_PUBLIC +#__public_macro OTHER_PUBLIC + +#define OTHER_DEFAULT diff --git a/clang/test/Modules/Inputs/lsv-private-macro/self.h b/clang/test/Modules/Inputs/lsv-private-macro/self.h new file mode 100644 index 000000000000..5a361308a10d --- /dev/null +++ b/clang/test/Modules/Inputs/lsv-private-macro/self.h @@ -0,0 +1,7 @@ +#define SELF_PRIVATE +#__private_macro SELF_PRIVATE + +#define SELF_PUBLIC +#__public_macro SELF_PUBLIC + +#define SELF_DEFAULT diff --git a/clang/test/Modules/lsv-private-macro.cpp b/clang/test/Modules/lsv-private-macro.cpp new file mode 100644 index 000000000000..6564558453e3 --- /dev/null +++ b/clang/test/Modules/lsv-private-macro.cpp @@ -0,0 +1,53 @@ +// RUN: rm -rf %t +// +// RUN: %clang_cc1 %s \ +// RUN: -fmodules-local-submodule-visibility \ +// RUN: -fmodule-map-file=%S/Inputs/lsv-private-macro/mod.map \ +// RUN: -I%S/Inputs/lsv-private-macro -fmodule-name=self \ +// RUN: -verify=expected-lsv +// +// RUN: %clang_cc1 %s \ +// RUN: -fmodules -fmodules-cache-path=%t \ +// RUN: -fmodule-map-file=%S/Inputs/lsv-private-macro/mod.map \ +// RUN: -I%S/Inputs/lsv-private-macro -fmodule-name=self \ +// RUN: -verify=expected-nolsv +// +// RUN: %clang_cc1 %s \ +// RUN: -fmodules -fmodules-cache-path=%t \ +// RUN: -fmodules-local-submodule-visibility \ +// RUN: -fmodule-map-file=%S/Inputs/lsv-private-macro/mod.map \ +// RUN: -I%S/Inputs/lsv-private-macro -fmodule-name=self \ +// RUN: -verify=expected-lsv + +#include "self.h" + +// With local submodule visibility enabled, private macros don't leak out of +// their respective submodules, even within the same top-level module. +// expected-lsv-no-diagnostics + +// expected-nolsv-error@+2 {{SELF_PRIVATE defined}} +#ifdef SELF_PRIVATE +#error SELF_PRIVATE defined +#endif + +#ifndef SELF_PUBLIC +#error SELF_PUBLIC not defined +#endif + +#ifndef SELF_DEFAULT +#error SELF_DEFAULT not defined +#endif + +#include "other.h" + +#ifdef OTHER_PRIVATE +#error OTHER_PRIVATE defined +#endif + +#ifndef OTHER_PUBLIC +#error OTHER_PUBLIC not defined +#endif + +#ifndef OTHER_DEFAULT +#error OTHER_DEFAULT not defined +#endif diff --git a/clang/test/OpenMP/atomic_codegen.cpp b/clang/test/OpenMP/atomic_codegen.cpp index 47ab0b4e1804..ada47d44cc5d 100644 --- a/clang/test/OpenMP/atomic_codegen.cpp +++ b/clang/test/OpenMP/atomic_codegen.cpp @@ -58,7 +58,7 @@ void parallel_atomic_ewc() { // CHECK: {{invoke|call}} void @_ZN2StD1Ev(%struct.St* {{[^,]*}} [[TEMP_ST_ADDR]]) #pragma omp atomic St().get() %= b; -#pragma omp atomic +#pragma omp atomic hint(6) s.field++; // CHECK: invoke void @_ZN2StC1Ev(%struct.St* {{[^,]*}} [[TEMP_ST_ADDR:%.+]]) // CHECK: [[SCALAR_ADDR:%.+]] = invoke nonnull align 4 dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* {{[^,]*}} [[TEMP_ST_ADDR]]) diff --git a/clang/test/OpenMP/critical_codegen.cpp b/clang/test/OpenMP/critical_codegen.cpp index 46fad63b3bd8..d84f2b2af22b 100644 --- a/clang/test/OpenMP/critical_codegen.cpp +++ b/clang/test/OpenMP/critical_codegen.cpp @@ -68,6 +68,31 @@ int main() { return a; } +// ALL-LABEL: lambda_critical +// TERM_DEBUG-LABEL: lambda_critical +void lambda_critical(int a, int b) { + auto l = [=]() { +#pragma omp critical + { + // ALL: call void @__kmpc_critical( + int c = a + b; + } + }; + + l(); + + auto l1 = [=]() { +#pragma omp parallel +#pragma omp critical + { + // ALL: call void @__kmpc_critical( + int c = a + b; + } + }; + + l1(); +} + struct S { int a; }; diff --git a/clang/test/OpenMP/debug-info-complex-byval.cpp b/clang/test/OpenMP/debug-info-complex-byval.cpp new file mode 100644 index 000000000000..f67bdae20aff --- /dev/null +++ b/clang/test/OpenMP/debug-info-complex-byval.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s + +// RUN: %clang_cc1 -fopenmp-simd -x c++ %s -verify -debug-info-kind=limited -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} +// expected-no-diagnostics + +void a() { + float _Complex b; + // CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* {{.*}}, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* [[OUTLINED:@.+]] to void (i32*, i32*, ...)*), i64 %{{.*}}) +#pragma omp parallel firstprivate(b) + ; +} + +// CHECK: define internal void [[OUTLINED_DEBUG:@.+]](i32* {{.*}}, i32* {{.*}}, <2 x float> {{.*}}) + +// CHECK: define internal void [[OUTLINED]](i32* {{.*}}, i32* {{.*}}, i64 [[B_VAL:%.+]]) +// CHECK: [[B_ADDR:%.+]] = alloca i64, +// CHECK: store i64 [[B_VAL]], i64* [[B_ADDR]], +// CHECK: [[CONV:%.+]] = bitcast i64* [[B_ADDR]] to { float, float }*, +// CHECK: [[BC:%.+]] = bitcast { float, float }* [[CONV]] to <2 x float>*, +// CHECK: [[B_VAL:%.+]] = load <2 x float>, <2 x float>* [[BC]], +// CHECK: call void [[OUTLINED_DEBUG]](i32* %{{.+}}, i32* %{{.+}}, <2 x float> [[B_VAL]]) diff --git a/clang/test/OpenMP/declare_mapper_codegen.cpp b/clang/test/OpenMP/declare_mapper_codegen.cpp index 7ccb361a2d0a..2c488c556a5e 100644 --- a/clang/test/OpenMP/declare_mapper_codegen.cpp +++ b/clang/test/OpenMP/declare_mapper_codegen.cpp @@ -500,7 +500,8 @@ void foo(int a){ // CK0-DAG: [[PFPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPTRADDR_P:%.+]], align // CK0-DAG: [[SIZEFPADDR]] = load [1 x i64]*, [1 x i64]** [[FPPTRADDR_SIZE:%.+]], align // CK0-DAG: [[MPRFPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPTRADDR_MPR:%.+]], align -// CK0-DAG: call void (i8*, ...) %1(i8* %2, {{.+}}[[FPPTRADDR_BP]], {{.+}}[[FPPTRADDR_P]], {{.+}}[[FPPTRADDR_SIZE]], {{.+}}[[FPPTRADDR_MPR]]) +// CK0-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* %1 to void (i8*, [1 x i8*]**, [1 x i8*]**, [1 x i64]**, [1 x i8*]**)* +// CK0-DAG: call void [[FN]](i8* %2, {{.+}}[[FPPTRADDR_BP]], {{.+}}[[FPPTRADDR_P]], {{.+}}[[FPPTRADDR_SIZE]], {{.+}}[[FPPTRADDR_MPR]]) // CK0-DAG: call void [[KERNEL_2:@.+]](%class.C* [[KERNELARG:%.+]]) // CK0-DAG: [[KERNELARG]] = load %class.C*, %class.C** [[KERNELARGGEP:%.+]], align // CK0-DAG: [[KERNELARGGEP]] = getelementptr inbounds [[ANON_T]], [[ANON_T]]* [[CTX:%.+]], i32 0, i32 0 @@ -531,7 +532,8 @@ void foo(int a){ // CK0-DAG: [[PFPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPTRADDR_P:%.+]], align // CK0-DAG: [[SIZEFPADDR]] = load [1 x i64]*, [1 x i64]** [[FPPTRADDR_SIZE:%.+]], align // CK0-DAG: [[MPRFPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPTRADDR_MPR:%.+]], align -// CK0-DAG: call void (i8*, ...) %1(i8* %2, {{.+}}[[FPPTRADDR_BP]], {{.+}}[[FPPTRADDR_P]], {{.+}}[[FPPTRADDR_SIZE]], {{.+}}[[FPPTRADDR_MPR]]) +// CK0-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* %1 to void (i8*, +// CK0-DAG: call void [[FN]](i8* %2, {{.+}}[[FPPTRADDR_BP]], {{.+}}[[FPPTRADDR_P]], {{.+}}[[FPPTRADDR_SIZE]], {{.+}}[[FPPTRADDR_MPR]]) // CK0-DAG: call void [[KERNEL_2:@.+]](%class.C* [[KERNELARG:%.+]]) // CK0-DAG: [[KERNELARG]] = load %class.C*, %class.C** [[KERNELARGGEP:%.+]], align // CK0-DAG: [[KERNELARGGEP]] = getelementptr inbounds [[ANON_T_0]], [[ANON_T_0]]* [[CTX:%.+]], i32 0, i32 0 @@ -562,7 +564,8 @@ void foo(int a){ // CK0-DAG: [[PADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPADDR:%[^,]+]], align // CK0-DAG: [[SZADDR]] = load [1 x i64]*, [1 x i64]** [[FPSZADDR:%[^,]+]], align // CK0-DAG: [[MPRADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPMPRADDR:%[^,]+]], align -// CK0-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]], [1 x i8*]** [[FPMPRADDR]]) +// CK0-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.+}} to void (i8*, +// CK0-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]], [1 x i8*]** [[FPMPRADDR]]) // CK0: ret void // CK0: } @@ -581,7 +584,8 @@ void foo(int a){ // CK0-DAG: [[PADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPADDR:%[^,]+]], align // CK0-DAG: [[SZADDR]] = load [1 x i64]*, [1 x i64]** [[FPSZADDR:%[^,]+]], align // CK0-DAG: [[MPRADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPMPRADDR:%[^,]+]], align -// CK0-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]], [1 x i8*]** [[FPMPRADDR]]) +// CK0-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.+}} to void (i8*, +// CK0-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]], [1 x i8*]** [[FPMPRADDR]]) // CK0: } // CK0: define internal {{.*}}i32 [[OMP_TASK_ENTRY_25]](i32 {{.*}}%{{[^,]+}}, [[KMP_TASK_T_WITH_PRIVATES_7]]* noalias %{{[^,]+}}) @@ -599,7 +603,8 @@ void foo(int a){ // CK0-DAG: [[PADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPADDR:%[^,]+]], align // CK0-DAG: [[SZADDR]] = load [1 x i64]*, [1 x i64]** [[FPSZADDR:%[^,]+]], align // CK0-DAG: [[MPRADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPMPRADDR:%[^,]+]], align -// CK0-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]], [1 x i8*]** [[FPMPRADDR]]) +// CK0-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.+}} to void (i8*, +// CK0-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]], [1 x i8*]** [[FPMPRADDR]]) // CK0: } // CK0: define internal {{.*}}i32 [[OMP_TASK_ENTRY_34]](i32 {{.*}}%{{[^,]+}}, [[KMP_TASK_T_WITH_PRIVATES_10]]* noalias %{{[^,]+}}) diff --git a/clang/test/OpenMP/declare_reduction_ast_print.c b/clang/test/OpenMP/declare_reduction_ast_print.c index 37b722e5f8ca..a421886dd3fe 100644 --- a/clang/test/OpenMP/declare_reduction_ast_print.c +++ b/clang/test/OpenMP/declare_reduction_ast_print.c @@ -47,13 +47,18 @@ int main() { : omp_out = omp_out > omp_in ? omp_in : omp_out) \ initializer(omp_priv = 2147483647) +#pragma omp declare reduction(mymin \ + : struct SSS \ + : omp_out = omp_out.field > omp_in.field ? omp_in : omp_out) + int foo(int argc, char **argv) { int x; -#pragma omp parallel for reduction(mymin : x) + struct SSS ss; +#pragma omp parallel for reduction(mymin : x, ss) for (int i = 0; i < 1000; i++) ; return 0; } -// CHECK: #pragma omp parallel for reduction(mymin: x) +// CHECK: #pragma omp parallel for reduction(mymin: x,ss) #endif diff --git a/clang/test/OpenMP/declare_reduction_codegen.c b/clang/test/OpenMP/declare_reduction_codegen.c index f5695ffaac34..71f4be57f7c5 100644 --- a/clang/test/OpenMP/declare_reduction_codegen.c +++ b/clang/test/OpenMP/declare_reduction_codegen.c @@ -17,6 +17,9 @@ // CHECK: [[SSS_INT:.+]] = type { i32 } // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 } +// CHECK-DAG: [[SSS_INIT:@.+]] = private constant %struct.SSS zeroinitializer +// CHECK-DAG: [[INT_INIT:@.+]] = private constant i32 0 + #pragma omp declare reduction(+ : int, char : omp_out *= omp_in) // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) // CHECK: [[MUL:%.+]] = mul nsw i32 @@ -163,4 +166,27 @@ int main() { // OMP45-LOAD-NEXT: store i8 [[TRUNC]], i8* // OMP45-LOAD-NEXT: ret void // OMP45-LOAD-NEXT: } + +// CHECK-LABEL: bar +struct SSS ss; +int in; +void bar() { + // CHECK: [[SS_PRIV:%.+]] = alloca %struct.SSS, + // CHECK: [[IN_PRIV:%.+]] = alloca i32, + // CHECK: [[BC:%.+]] = bitcast %struct.SSS* [[SS_PRIV]] to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{64|32}}(i8* {{.*}}[[BC]], i8* {{.*}}bitcast (%struct.SSS* [[SSS_INIT]] to i8*), i{{64|32}} 4, i1 false) + // CHECK: [[IN_VAL:%.+]] = load i32, i32* [[INT_INIT]], + // CHECK: store i32 [[IN_VAL]], i32* [[IN_PRIV]], + // CHECK: call void @__kmpc_for_static_init_4( +#pragma omp declare reduction(+ \ + : struct SSS \ + : omp_out = omp_in) +#pragma omp declare reduction(+ \ + : int \ + : omp_out = omp_in) +#pragma omp for reduction(+ \ + : ss, in) + for (int i = 0; i < 10; ++i) + ; +} #endif diff --git a/clang/test/OpenMP/declare_reduction_messages.c b/clang/test/OpenMP/declare_reduction_messages.c index 69b73f4c72b5..411a1c0f1820 100644 --- a/clang/test/OpenMP/declare_reduction_messages.c +++ b/clang/test/OpenMP/declare_reduction_messages.c @@ -49,9 +49,9 @@ struct S { #pragma omp declare reduction(|: struct S: omp_out.s += omp_in.s) initializer(omp_priv = { 0 }) int fun(int arg) { - struct S s;// expected-note {{'s' defined here}} + struct S s; s.s = 0; -#pragma omp parallel for reduction(+ : s) // expected-error {{list item of type 'struct S' is not valid for specified reduction operation: unable to provide default initialization value}} +#pragma omp parallel for reduction(+ : s) for (arg = 0; arg < 10; ++arg) s.s += arg; #pragma omp declare reduction(red : int : omp_out++) diff --git a/clang/test/OpenMP/declare_target_ast_print.cpp b/clang/test/OpenMP/declare_target_ast_print.cpp index c086f8526147..dbd0b923a7d6 100644 --- a/clang/test/OpenMP/declare_target_ast_print.cpp +++ b/clang/test/OpenMP/declare_target_ast_print.cpp @@ -277,4 +277,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: int ts = 1; // CHECK-NEXT: #pragma omp end declare target +// Do not expect anything here since the region is empty. +#pragma omp declare target +#pragma omp end declare target + #endif diff --git a/clang/test/OpenMP/declare_target_codegen.cpp b/clang/test/OpenMP/declare_target_codegen.cpp index 1ce211a34d5f..4b9bb41bd917 100644 --- a/clang/test/OpenMP/declare_target_codegen.cpp +++ b/clang/test/OpenMP/declare_target_codegen.cpp @@ -26,6 +26,7 @@ // CHECK-NOT: define {{.*}}{{baz1|baz4|maini1|Base|virtual_}} // CHECK-DAG: Bake // CHECK-NOT: @{{hhh|ggg|fff|eee}} = +// CHECK-DAG: @flag = hidden global i8 undef, // CHECK-DAG: @aaa = external global i32, // CHECK-DAG: @bbb ={{ hidden | }}global i32 0, // CHECK-DAG: weak constant %struct.__tgt_offload_entry { i8* bitcast (i32* @bbb to i8*), @@ -53,8 +54,8 @@ #ifndef HEADER #define HEADER - #pragma omp declare target +bool flag [[clang::loader_uninitialized]]; extern int bbb; #pragma omp end declare target #pragma omp declare target diff --git a/clang/test/OpenMP/dispatch_ast_print.cpp b/clang/test/OpenMP/dispatch_ast_print.cpp new file mode 100644 index 000000000000..3dea4cbcd3f9 --- /dev/null +++ b/clang/test/OpenMP/dispatch_ast_print.cpp @@ -0,0 +1,215 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fopenmp -fopenmp-version=51 \ +// RUN: -fsyntax-only -verify %s + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -fsyntax-only -verify %s + +// expected-no-diagnostics + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -ast-print %s | FileCheck %s --check-prefix=PRINT + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -ast-dump %s | FileCheck %s --check-prefix=DUMP + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -emit-pch -o %t %s + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT + +#ifndef HEADER +#define HEADER + +int foo_gpu(int A, int *B) { return 0;} +//PRINT: #pragma omp declare variant(foo_gpu) +//DUMP: FunctionDecl{{.*}} foo +//DUMP: OMPDeclareVariantAttr {{.*}}Implicit construct{{.*}} +#pragma omp declare variant(foo_gpu) \ + match(construct={dispatch}, device={arch(arm)}) +int foo(int, int*); + +template +void fooTemp() { + T a; + TP b; + //PRINT: #pragma omp dispatch nowait + //DUMP: OMPDispatchDirective + //DUMP: OMPNowaitClause + #pragma omp dispatch nowait + foo(a, b); +} + +int *get_device_ptr(); +int get_device(); +int other(); + +//DUMP: FunctionDecl{{.*}} test_one +void test_one() +{ + int aaa, bbb, var; + //PRINT: #pragma omp dispatch depend(in : var) nowait + //DUMP: OMPDispatchDirective + //DUMP: OMPDependClause + //DUMP: OMPNowaitClause + #pragma omp dispatch depend(in:var) nowait + foo(aaa, &bbb); + + int *dp = get_device_ptr(); + int dev = get_device(); + //PRINT: #pragma omp dispatch device(dev) is_device_ptr(dp) + //DUMP: OMPDispatchDirective + //DUMP: OMPDeviceClause + //DUMP: OMPIs_device_ptrClause + #pragma omp dispatch device(dev) is_device_ptr(dp) + foo(aaa, dp); + + //PRINT: #pragma omp dispatch + //PRINT: foo(other(), &bbb); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + foo(other(), &bbb); + + fooTemp(); +} + +struct Obj { + Obj(); + ~Obj(); + int disp_method_variant1(); + #pragma omp declare variant(disp_method_variant1) \ + match(construct={dispatch}, device={arch(arm)}) + int disp_method1(); + + static int disp_method_variant2() { return 1; } + #pragma omp declare variant(disp_method_variant2) \ + match(construct={dispatch}, device={arch(arm)}) + static int disp_method2() { return 2; } +}; + +Obj foo_vari(); +#pragma omp declare variant(foo_vari) \ + match(construct={dispatch}, device={arch(arm)}) +Obj foo_obj(); + +//DUMP: FunctionDecl{{.*}} test_two +void test_two(Obj o1, Obj &o2, Obj *o3) +{ + //PRINT: #pragma omp dispatch + //PRINT: o1.disp_method1(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + o1.disp_method1(); + + //PRINT: #pragma omp dispatch + //PRINT: o2.disp_method1(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + o2.disp_method1(); + + //PRINT: #pragma omp dispatch + //PRINT: o3->disp_method1(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + o3->disp_method1(); + + //PRINT: #pragma omp dispatch + //PRINT: Obj::disp_method2(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + Obj::disp_method2(); + + int ret; + //PRINT: #pragma omp dispatch + //PRINT: ret = o1.disp_method1(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + ret = o1.disp_method1(); + + //PRINT: #pragma omp dispatch + //PRINT: ret = o2.disp_method1(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + ret = o2.disp_method1(); + + //PRINT: #pragma omp dispatch + //PRINT: ret = o3->disp_method1(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + ret = o3->disp_method1(); + + //PRINT: #pragma omp dispatch + //PRINT: ret = Obj::disp_method2(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + ret = Obj::disp_method2(); + + //PRINT: #pragma omp dispatch + //PRINT: (void)Obj::disp_method2(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + (void)Obj::disp_method2(); + + // Full C++ operator= case with temps and EH. + Obj o; + //PRINT: #pragma omp dispatch + //PRINT: o = foo_obj(); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + o = foo_obj(); +} + +struct A { + A& disp_operator(A other); + #pragma omp declare variant(disp_operator) \ + match(construct={dispatch}, device={arch(arm)}) + A& operator=(A other); +}; + +struct Obj2 { + A xx; + Obj2& disp_operator(Obj2 other); + #pragma omp declare variant(disp_operator) \ + match(construct={dispatch}, device={arch(arm)}) + Obj2& operator=(Obj2 other); + + void foo() { + Obj2 z; + //PRINT: #pragma omp dispatch + //PRINT: z = z; + //DUMP: OMPDispatchDirective + #pragma omp dispatch + z = z; + //PRINT: #pragma omp dispatch + //PRINT: z.operator=(z); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + z.operator=(z); + } + void bar() { + Obj2 j; + //PRINT: #pragma omp dispatch + //PRINT: j = {this->xx}; + //DUMP: OMPDispatchDirective + #pragma omp dispatch + j = {this->xx}; + //PRINT: #pragma omp dispatch + //PRINT: j.operator=({this->xx}); + //DUMP: OMPDispatchDirective + #pragma omp dispatch + j.operator=({this->xx}); + } +}; + +void test_three() +{ + Obj2 z1, z; + #pragma omp dispatch + z1 = z; + #pragma omp dispatch + z1.operator=(z); +} +#endif // HEADER diff --git a/clang/test/OpenMP/dispatch_messages.cpp b/clang/test/OpenMP/dispatch_messages.cpp new file mode 100644 index 000000000000..221c7b784c00 --- /dev/null +++ b/clang/test/OpenMP/dispatch_messages.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp \ +// RUN: -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s + +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -verify -fopenmp \ +// RUN: -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s + +int disp_variant(); +#pragma omp declare variant(disp_variant) \ + match(construct = {dispatch}, device = {arch(arm)}) +int disp_call(); + +struct Obj { + int disp_method_variant1(); + #pragma omp declare variant(disp_method_variant1) \ + match(construct={dispatch}, device={arch(arm)}) + int disp_method1(); + int disp_method_variant2(); + #pragma omp declare variant(disp_method_variant2) \ + match(construct={dispatch}, device={arch(arm)}) + int disp_method2(); +}; + +void testit_one(int dnum) { + // expected-error@+1 {{cannot contain more than one 'device' clause}} + #pragma omp dispatch device(dnum) device(3) + disp_call(); + + // expected-error@+1 {{cannot contain more than one 'nowait' clause}} + #pragma omp dispatch nowait device(dnum) nowait + disp_call(); +} + +void testit_two() { + //expected-error@+2 {{cannot return from OpenMP region}} + #pragma omp dispatch + return disp_call(); +} + +void testit_three(int (*fptr)(void), Obj *obj, int (Obj::*mptr)(void)) { + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + fptr(); + + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + (obj->*mptr)(); + + int ret; + + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + ret = fptr(); + + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + ret = (obj->*mptr)(); +} + +void testit_four(int *x, int y, Obj *obj) +{ + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + *x = y; + + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + y = disp_call() + disp_call(); + + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + y = (y = disp_call()); + + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + y += disp_call(); + + //expected-error@+2 {{statement after '#pragma omp dispatch' must be a direct call to a target function or an assignment to one}} + #pragma omp dispatch + for (int I = 0; I < 8; ++I) { + disp_call(); + } +} diff --git a/clang/test/OpenMP/interop_ast_print.cpp b/clang/test/OpenMP/interop_ast_print.cpp new file mode 100644 index 000000000000..8f8ddc839c72 --- /dev/null +++ b/clang/test/OpenMP/interop_ast_print.cpp @@ -0,0 +1,279 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -fsyntax-only -verify %s + +// expected-no-diagnostics + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -ast-print %s | FileCheck %s --check-prefix=PRINT + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -ast-dump %s | FileCheck %s --check-prefix=DUMP + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -emit-pch -o %t %s + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \ +// RUN: -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT + +#ifndef HEADER +#define HEADER + +typedef void *omp_interop_t; + +//PRINT-LABEL: void foo1( +//DUMP-LABEL: FunctionDecl {{.*}} foo1 +void foo1(int *ap, int dev) { + omp_interop_t I; + omp_interop_t &IRef = I; + + //PRINT: #pragma omp interop init(target : I) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + #pragma omp interop init(target:I) + + //PRINT: #pragma omp interop use(I) + //DUMP: OMPInteropDirective + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + #pragma omp interop use(I) + + //PRINT: #pragma omp interop destroy(I) + //DUMP: OMPInteropDirective + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + #pragma omp interop destroy(I) + + //PRINT: #pragma omp interop init(target : IRef) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'IRef' + #pragma omp interop init(target:IRef) + + //PRINT: #pragma omp interop use(IRef) + //DUMP: OMPInteropDirective + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'IRef' + #pragma omp interop use(IRef) + + //PRINT: #pragma omp interop destroy(IRef) + //DUMP: OMPInteropDirective + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'IRef' + #pragma omp interop destroy(IRef) + + const omp_interop_t CI = (omp_interop_t)0; + //PRINT: #pragma omp interop use(CI) + //DUMP: OMPInteropDirective + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'const omp_interop_t'{{.*}}Var{{.*}}'CI' + #pragma omp interop use(CI) + + //PRINT: #pragma omp interop device(dev) depend(inout : ap) init(targetsync : I) + //DUMP: OMPInteropDirective + //DUMP: OMPDeviceClause + //DUMP: DeclRefExpr{{.*}}'dev' 'int' + //DUMP: OMPDependClause + //DUMP: DeclRefExpr{{.*}}'ap' 'int *' + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + #pragma omp interop device(dev) depend(inout:ap) init(targetsync:I) + + //PRINT: #pragma omp interop device(dev) depend(inout : ap) use(I) + //DUMP: OMPInteropDirective + //DUMP: OMPDeviceClause + //DUMP: DeclRefExpr{{.*}}'dev' 'int' + //DUMP: OMPDependClause + //DUMP: DeclRefExpr{{.*}}'ap' 'int *' + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + #pragma omp interop device(dev) depend(inout:ap) use(I) + + //PRINT: #pragma omp interop device(dev) depend(inout : ap) destroy(I) + //DUMP: OMPInteropDirective + //DUMP: OMPDeviceClause + //DUMP: DeclRefExpr{{.*}}'dev' 'int' + //DUMP: OMPDependClause + //DUMP: DeclRefExpr{{.*}}'ap' 'int *' + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + #pragma omp interop device(dev) depend(inout:ap) destroy(I) + + //PRINT: #pragma omp interop init(prefer_type(1,2,3,4,5,6), targetsync : I) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: IntegerLiteral{{.*}}1 + //DUMP: IntegerLiteral{{.*}}2 + //DUMP: IntegerLiteral{{.*}}3 + //DUMP: IntegerLiteral{{.*}}4 + //DUMP: IntegerLiteral{{.*}}5 + //DUMP: IntegerLiteral{{.*}}6 + #pragma omp interop init(prefer_type(1,2,3,4,5,6),targetsync:I) + + //PRINT: #pragma omp interop init(prefer_type(2,4,6,1), targetsync : I) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: IntegerLiteral{{.*}}2 + //DUMP: IntegerLiteral{{.*}}4 + //DUMP: IntegerLiteral{{.*}}6 + //DUMP: IntegerLiteral{{.*}}1 + #pragma omp interop init(prefer_type(2,4,6,1),targetsync:I) + + //PRINT: #pragma omp interop init(prefer_type("cuda","cuda_driver","opencl","sycl","hip","level_zero"), targetsync : I) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: StringLiteral{{.*}}"cuda" + //DUMP: StringLiteral{{.*}}"cuda_driver" + //DUMP: StringLiteral{{.*}}"opencl" + //DUMP: StringLiteral{{.*}}"sycl" + //DUMP: StringLiteral{{.*}}"hip" + //DUMP: StringLiteral{{.*}}"level_zero" + #pragma omp interop init( \ + prefer_type("cuda","cuda_driver","opencl","sycl","hip","level_zero"), \ + targetsync:I) + + //PRINT: #pragma omp interop init(prefer_type("level_zero",2,4), targetsync : I) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: StringLiteral{{.*}}"level_zero" + //DUMP: IntegerLiteral{{.*}}2 + //DUMP: IntegerLiteral{{.*}}4 + #pragma omp interop init(prefer_type("level_zero",2,4),targetsync:I) + + omp_interop_t J; + + //PRINT: #pragma omp interop init(target : I) init(targetsync : J) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J' + #pragma omp interop init(target:I) init(targetsync:J) + + //PRINT: #pragma omp interop init(target : I) use(J) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J' + #pragma omp interop init(target:I) use(J) + + //PRINT: #pragma omp interop use(I) use(J) + //DUMP: OMPInteropDirective + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J' + #pragma omp interop use(I) use(J) + + //PRINT: #pragma omp interop destroy(I) destroy(J) + //DUMP: OMPInteropDirective + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J' + #pragma omp interop destroy(I) destroy(J) + + //PRINT: #pragma omp interop init(target : I) destroy(J) + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J' + #pragma omp interop init(target:I) destroy(J) + + //PRINT: #pragma omp interop destroy(I) use(J) + //DUMP: OMPInteropDirective + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I' + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J' + #pragma omp interop destroy(I) use(J) +} + +//DUMP: FunctionTemplateDecl{{.*}}fooTemp +//DUMP-NEXT: NonTypeTemplateParmDecl{{.*}}'int{{.*}}I +template +void fooTemp() { + omp_interop_t interop_var; + //PRINT: #pragma omp interop init(prefer_type(I,4,"level_one"), target : interop_var) + //DUMP: FunctionDecl{{.*}}fooTemp + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}'interop_var' + //DUMP: DeclRefExpr{{.*}}NonTypeTemplateParm{{.*}}'I' 'int' + //DUMP: IntegerLiteral{{.*}}'int' 4 + //DUMP: StringLiteral{{.*}}"level_one" + + //PRINT: #pragma omp interop init(prefer_type(3,4,"level_one"), target : interop_var) + //DUMP: FunctionDecl{{.*}}fooTemp + //DUMP: TemplateArgument integral 3 + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}'interop_var' + //DUMP: SubstNonTypeTemplateParmExpr{{.*}}'int' + //DUMP: NonTypeTemplateParmDecl{{.*}}'int'{{.*}}I + //DUMP: IntegerLiteral{{.*}}'int' 3 + //DUMP: IntegerLiteral{{.*}}'int' 4 + //DUMP: StringLiteral{{.*}}"level_one" + #pragma omp interop init(prefer_type(I,4,"level_one"), target: interop_var) +} + +//DUMP: FunctionTemplateDecl{{.*}}barTemp +//DUMP-NEXT: TemplateTypeParmDecl{{.*}}typename{{.*}}T +template +void barTemp(T t) { + //PRINT: #pragma omp interop init(prefer_type(4,"level_one"), target : t) + //DUMP: FunctionDecl{{.*}}barTemp 'void (T)' + //DUMP: ParmVarDecl{{.*}}t 'T' + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'T' + //DUMP: IntegerLiteral{{.*}}'int' 4 + //DUMP: StringLiteral{{.*}}"level_one" + #pragma omp interop init(prefer_type(4,"level_one"), target: t) + + //PRINT: #pragma omp interop use(t) + //DUMP: OMPInteropDirective + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'T' + #pragma omp interop use(t) + + //PRINT: #pragma omp interop destroy(t) + //DUMP: OMPInteropDirective + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'T' + #pragma omp interop destroy(t) + + //DUMP: FunctionDecl{{.*}}barTemp 'void (void *)' + //DUMP: TemplateArgument type 'void *' + //DUMP: ParmVarDecl{{.*}}t 'void *' + //DUMP: OMPInteropDirective + //DUMP: OMPInitClause + //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'void *' + //PRINT: #pragma omp interop init(prefer_type(4,"level_one"), target : t) + //DUMP: OMPInteropDirective + //DUMP: OMPUseClause + //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'void *' + //PRINT: #pragma omp interop use(t) + //DUMP: OMPInteropDirective + //DUMP: OMPDestroyClause + //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'void *' + //PRINT: #pragma omp interop destroy(t) +} + +void bar() +{ + fooTemp<3>(); + omp_interop_t Ivar; + barTemp(Ivar); +} + +#endif // HEADER diff --git a/clang/test/OpenMP/interop_messages.cpp b/clang/test/OpenMP/interop_messages.cpp new file mode 100644 index 000000000000..50f1efb5a6a9 --- /dev/null +++ b/clang/test/OpenMP/interop_messages.cpp @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - -DWITHDEF %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - -DWITHOUTDEF %s + +#ifdef WITHDEF +typedef void *omp_interop_t; + +void foo(int *Ap) { + omp_interop_t InteropVar; + omp_interop_t Another; + + //expected-error@+1 {{expected interop type: 'target' and/or 'targetsync'}} + #pragma omp interop init(target,foo:InteropVar) init(target:Another) + + //expected-error@+1 {{use of undeclared identifier 'NoDeclVar'}} + #pragma omp interop init(target:NoDeclVar) init(target:Another) + + //expected-error@+1 {{use of undeclared identifier 'NoDeclVar'}} + #pragma omp interop use(NoDeclVar) use(Another) + + //expected-error@+1 {{use of undeclared identifier 'NoDeclVar'}} + #pragma omp interop destroy(NoDeclVar) destroy(Another) + + //expected-error@+2 {{expected interop type: 'target' and/or 'targetsync'}} + //expected-error@+1 {{expected expression}} + #pragma omp interop init(InteropVar) init(target:Another) + + //expected-warning@+1 {{missing ':' after interop types}} + #pragma omp interop init(target InteropVar) + + //expected-error@+1 {{expected expression}} + #pragma omp interop init(prefer_type(1,+,3),target:InteropVar) \ + init(target:Another) + + int IntVar; + struct S { int I; } SVar; + + //expected-error@+1 {{interop variable must be of type 'omp_interop_t'}} + #pragma omp interop init(prefer_type(1,"sycl",3),target:IntVar) \ + init(target:Another) + + //expected-error@+1 {{interop variable must be of type 'omp_interop_t'}} + #pragma omp interop use(IntVar) use(Another) + + //expected-error@+1 {{interop variable must be of type 'omp_interop_t'}} + #pragma omp interop destroy(IntVar) destroy(Another) + + //expected-error@+1 {{interop variable must be of type 'omp_interop_t'}} + #pragma omp interop init(prefer_type(1,"sycl",3),target:SVar) \ + init(target:Another) + + //expected-error@+1 {{interop variable must be of type 'omp_interop_t'}} + #pragma omp interop use(SVar) use(Another) + + //expected-error@+1 {{interop variable must be of type 'omp_interop_t'}} + #pragma omp interop destroy(SVar) destroy(Another) + + int a, b; + //expected-error@+1 {{expected variable of type 'omp_interop_t'}} + #pragma omp interop init(target:a+b) init(target:Another) + + //expected-error@+1 {{expected variable of type 'omp_interop_t'}} + #pragma omp interop use(a+b) use(Another) + + //expected-error@+1 {{expected variable of type 'omp_interop_t'}} + #pragma omp interop destroy(a+b) destroy(Another) + + const omp_interop_t C = (omp_interop_t)5; + //expected-error@+1 {{expected non-const variable of type 'omp_interop_t'}} + #pragma omp interop init(target:C) init(target:Another) + + //expected-error@+1 {{expected non-const variable of type 'omp_interop_t'}} + #pragma omp interop destroy(C) destroy(Another) + + //expected-error@+1 {{prefer_list item must be a string literal or constant integral expression}} + #pragma omp interop init(prefer_type(1.0),target:InteropVar) \ + init(target:Another) + + //expected-error@+1 {{prefer_list item must be a string literal or constant integral expression}} + #pragma omp interop init(prefer_type(a),target:InteropVar) \ + init(target:Another) + + //expected-error@+1 {{expected at least one 'init', 'use', 'destroy', or 'nowait' clause for '#pragma omp interop'}} + #pragma omp interop device(0) + + //expected-warning@+1 {{interop type 'target' cannot be specified more than once}} + #pragma omp interop init(target,targetsync,target:InteropVar) + + //expected-error@+1 {{'depend' clause requires the 'targetsync' interop type}} + #pragma omp interop init(target:InteropVar) depend(inout:Ap) + + //expected-error@+1 {{interop variable 'InteropVar' used in multiple action clauses}} + #pragma omp interop init(target:InteropVar) init(target:InteropVar) + + //expected-error@+1 {{interop variable 'InteropVar' used in multiple action clauses}} + #pragma omp interop use(InteropVar) use(InteropVar) + + //expected-error@+1 {{interop variable 'InteropVar' used in multiple action clauses}} + #pragma omp interop destroy(InteropVar) destroy(InteropVar) + + //expected-error@+1 {{interop variable 'InteropVar' used in multiple action clauses}} + #pragma omp interop init(target:InteropVar) use(InteropVar) + + //expected-error@+1 {{interop variable 'InteropVar' used in multiple action clauses}} + #pragma omp interop init(target:InteropVar) destroy(InteropVar) + + //expected-error@+1 {{interop variable 'InteropVar' used in multiple action clauses}} + #pragma omp interop use(InteropVar) destroy(InteropVar) + + //expected-error@+1 {{directive '#pragma omp interop' cannot contain more than one 'device' clause}} + #pragma omp interop init(target:InteropVar) device(0) device(1) + + //expected-error@+1 {{argument to 'device' clause must be a non-negative integer value}} + #pragma omp interop init(target:InteropVar) device(-4) + + //expected-error@+1 {{directive '#pragma omp interop' cannot contain more than one 'nowait' clause}} + #pragma omp interop nowait init(target:InteropVar) nowait +} +#endif +#ifdef WITHOUTDEF +void foo() { + int InteropVar; + //expected-error@+1 {{'omp_interop_t' type not found; include }} + #pragma omp interop init(prefer_type(1,"sycl",3),target:InteropVar) nowait + //expected-error@+1 {{'omp_interop_t' type not found; include }} + #pragma omp interop use(InteropVar) nowait + //expected-error@+1 {{'omp_interop_t' type not found; include }} + #pragma omp interop destroy(InteropVar) nowait +} +#endif diff --git a/clang/test/OpenMP/linking.c b/clang/test/OpenMP/linking.c index 802553c1be75..1c4439626470 100644 --- a/clang/test/OpenMP/linking.c +++ b/clang/test/OpenMP/linking.c @@ -81,7 +81,7 @@ // CHECK-LD-OVERRIDE-64: "-lgomp" "-lrt" // CHECK-LD-OVERRIDE-64: "-lpthread" "-lc" // -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: %clang -no-canonical-prefixes -fuse-ld=link %s -### -o %t.o 2>&1 \ // RUN: -fopenmp=libomp -target x86_64-msvc-win32 -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-MSVC-LINK-64 %s // CHECK-MSVC-LINK-64: link.exe @@ -95,7 +95,7 @@ // SIMD-ONLY11-NOT: libomp // SIMD-ONLY11-NOT: libgomp // -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: %clang -no-canonical-prefixes %s -fuse-ld=link -### -o %t.o 2>&1 \ // RUN: -fopenmp=libiomp5 -target x86_64-msvc-win32 -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-MSVC-ILINK-64 %s diff --git a/clang/test/OpenMP/master_codegen.cpp b/clang/test/OpenMP/master_codegen.cpp index 8554ad8e7dec..353284ea8541 100644 --- a/clang/test/OpenMP/master_codegen.cpp +++ b/clang/test/OpenMP/master_codegen.cpp @@ -55,6 +55,41 @@ int main() { return a; } +// ALL-LABEL: lambda_master +// TERM_DEBUG-LABEL: lambda_master +void lambda_master(int a, int b) { + auto l = [=]() { +#pragma omp master + { + // ALL: call i32 @__kmpc_master( + int c = a + b; + } + }; + + l(); + + auto l1 = [=]() { +#pragma omp parallel +#pragma omp master + { + // ALL: call i32 @__kmpc_master( + int c = a + b; + } + }; + + l1(); + + auto l2 = [=]() { +#pragma omp parallel master + { + // ALL: call i32 @__kmpc_master( + int c = a + b; + } + }; + + l2(); +} + // ALL-LABEL: parallel_master // TERM_DEBUG-LABEL: parallel_master void parallel_master() { diff --git a/clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp b/clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp index 3f8b34564854..9aa1affc4bb5 100644 --- a/clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp @@ -298,7 +298,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -447,7 +448,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp b/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp index e6cc39c5345a..ec791de82401 100644 --- a/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp @@ -71,7 +71,8 @@ int main(int argc, char **argv) { // CHECK-NEXT: } // CHECK: define internal {{.*}} [[OMP_TASK]]( -// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.*}} to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) // CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]], // CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]], // CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds % diff --git a/clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp b/clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp index 62aeb9f5e915..a7d2d792af89 100644 --- a/clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp @@ -276,7 +276,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -443,7 +444,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/master_taskloop_private_codegen.cpp b/clang/test/OpenMP/master_taskloop_private_codegen.cpp index 5743390b81e1..d70f367d3ba5 100644 --- a/clang/test/OpenMP/master_taskloop_private_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_private_codegen.cpp @@ -237,7 +237,8 @@ int main() { // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -365,7 +366,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp index 6f2748f0015c..75cb0c0cbb67 100644 --- a/clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp @@ -277,7 +277,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -426,7 +427,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp b/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp index aca7f0f47244..a38c126554d5 100644 --- a/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp @@ -64,7 +64,8 @@ int main(int argc, char **argv) { // CHECK-NEXT: } // CHECK: define internal {{.*}} [[OMP_TASK]]( -// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) // CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]], // CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]], // CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds % diff --git a/clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp index 4014a9b44574..cd4ec48f493f 100644 --- a/clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp @@ -267,7 +267,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -434,7 +435,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp b/clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp index db348c3f788e..26f7d6ff0730 100644 --- a/clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp @@ -230,7 +230,8 @@ int main() { // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -358,7 +359,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/nvptx_parallel_codegen.cpp b/clang/test/OpenMP/nvptx_parallel_codegen.cpp index 593f7fa49bf4..f85d1d43336d 100644 --- a/clang/test/OpenMP/nvptx_parallel_codegen.cpp +++ b/clang/test/OpenMP/nvptx_parallel_codegen.cpp @@ -4,7 +4,7 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ -// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns -disable-O0-optnone | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // expected-no-diagnostics @@ -318,7 +318,8 @@ int bar(int n){ // CHECK: [[EXIT]] // CHECK: ret void -// CHECK: define internal void [[PARALLEL_FN4]]( +// CHECK: noinline +// CHECK-NEXT: define internal void [[PARALLEL_FN4]]( // CHECK: [[A:%.+]] = alloca i[[SZ:32|64]], // CHECK: store i[[SZ]] 45, i[[SZ]]* %a, // CHECK: call void @__kmpc_barrier(%struct.ident_t* @{{.+}}, i32 %{{.+}}) @@ -326,6 +327,9 @@ int bar(int n){ // CHECK: declare void @__kmpc_barrier(%struct.ident_t*, i32) #[[#CONVERGENT:]] +// CHECK: Function Attrs: convergent noinline norecurse nounwind +// CHECK-NEXT: [[PARALLEL_FN4]]_wrapper + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l58}}_worker() // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l58}}( // CHECK-32: [[A_ADDR:%.+]] = alloca i32, @@ -373,7 +377,6 @@ int bar(int n){ // CHECK: store i32 [[NEW_CC_VAL]], i32* [[CC]], // CHECK: br label - // CHECK: declare i32 @__kmpc_warp_active_thread_mask() #[[#CONVERGENT:]] // CHECK: declare void @__kmpc_syncwarp(i32) #[[#CONVERGENT:]] diff --git a/clang/test/OpenMP/nvptx_param_translate.c b/clang/test/OpenMP/nvptx_param_translate.c index ec123ce3811b..4b59d299269c 100644 --- a/clang/test/OpenMP/nvptx_param_translate.c +++ b/clang/test/OpenMP/nvptx_param_translate.c @@ -3,7 +3,8 @@ // expected-no-diagnostics // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** % -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* % int main() { double a, b; diff --git a/clang/test/OpenMP/nvptx_target_codegen.cpp b/clang/test/OpenMP/nvptx_target_codegen.cpp index 56f04cb01f0a..7e32f7391f12 100644 --- a/clang/test/OpenMP/nvptx_target_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_codegen.cpp @@ -394,6 +394,12 @@ int baz(int f, double &a) { return f; } +extern void assert(int) throw() __attribute__((__noreturn__)); +void unreachable_call() { +#pragma omp target + assert(0); +} + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+347}}_worker() // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8, // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*, @@ -632,6 +638,12 @@ int baz(int f, double &a) { // CHECK: [[RES:%.+]] = load i32, i32* [[RET]], // CHECK: ret i32 [[RES]] +// CHECK: define {{.*}}void {{@__omp_offloading_.+unreachable_call.+l399}}() +// CHECK: call void @{{.*}}assert{{.*}}(i32 0) +// CHECK: unreachable +// CHECK: call void @__kmpc_kernel_deinit(i16 1) +// CHECK: ret void + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l331}}_worker() // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8, // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*, diff --git a/clang/test/OpenMP/omp_with_loop_pragma_instr_profile.c b/clang/test/OpenMP/omp_with_loop_pragma_instr_profile.c new file mode 100644 index 000000000000..9667f9cc549d --- /dev/null +++ b/clang/test/OpenMP/omp_with_loop_pragma_instr_profile.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c -emit-llvm %s -triple x86_64-unknown-linux -o - -femit-all-decls -disable-llvm-passes -fprofile-instrument=clang | FileCheck %s +// expected-no-diagnostics + +void sub(double *restrict a, double *restrict b, int n) { + int i; + +#pragma omp parallel for +#pragma clang loop vectorize(disable) + for (i = 0; i < n; i++) { + a[i] = a[i] + b[i]; + } +} + +// CHECK-LABEL: @.omp_outlined.( +// CHECK-NEXT: entry: +// CHECK: call void @llvm.instrprof.increment( +// CHECK: omp.precond.then: +// CHECK-NEXT: call void @llvm.instrprof.increment( +// CHECK: cond.true: +// CEHCK-NEXT: call void @llvm.instrprof.increment( +// CHECK: omp.inner.for.body: +// CHECK-NEXT: call void @llvm.instrprof.increment( diff --git a/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp index 5869e4861e1c..fa8d1f600a22 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp @@ -286,7 +286,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -424,7 +425,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp index 059f83c2505d..1b978e9b0485 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp @@ -264,7 +264,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -425,7 +426,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp index 7b7cc87efa90..5122aeafeee8 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp @@ -229,7 +229,8 @@ int main() { // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -351,7 +352,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp index d76df2e06b90..5ee554eda315 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp @@ -286,7 +286,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -424,7 +425,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp index 4c7c87367267..81802179a79e 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp @@ -264,7 +264,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -425,7 +426,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp index e6d941d1264f..aa51ca51a200 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp @@ -229,7 +229,8 @@ int main() { // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -351,7 +352,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/simd_null_pointer_access.cpp b/clang/test/OpenMP/simd_null_pointer_access.cpp index 11a828501d1f..3b539fd3aa64 100644 --- a/clang/test/OpenMP/simd_null_pointer_access.cpp +++ b/clang/test/OpenMP/simd_null_pointer_access.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fopenmp-simd -fsycl -fsycl-is-device -triple spir64 -verify -fsyntax-only %s +// RUN: %clang_cc1 -fopenmp-simd -fsycl-is-device -triple spir64 -verify -fsyntax-only %s // Test that in the presence of SYCL options, that null function // declarations are accounted for when checking to emit diagnostics. diff --git a/clang/test/OpenMP/target_codegen.cpp b/clang/test/OpenMP/target_codegen.cpp index 7dafa6ba13d4..5dec70b0ad25 100644 --- a/clang/test/OpenMP/target_codegen.cpp +++ b/clang/test/OpenMP/target_codegen.cpp @@ -404,7 +404,8 @@ int foo(int n) { // CHECK-DAG: [[BPRADDR]] = load [2 x i8*]*, [2 x i8*]** [[FPPTR_BPR:%.+]], align // CHECK-DAG: [[PRADDR]] = load [2 x i8*]*, [2 x i8*]** [[FPPTR_PR:%.+]], align // CHECK-DAG: [[SIZEADDR]] = load [2 x i64]*, [2 x i64]** [[FPPTR_SIZE:%.+]], align -// CHECK-DAG: call void (i8*, ...) {{%[0-9]+}}(i8* {{%[^,]+}}, i[[SZ]]*** [[FPPTR_PLOCAL:%.+]], i32** [[FPPTR_GLOBAL:%.+]], [2 x i8*]** [[FPPTR_BPR]], [2 x i8*]** [[FPPTR_PR]], [2 x i64]** [[FPPTR_SIZE]]) +// CHECK-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%[0-9]+}} to void (i8*, +// CHECK-DAG: call void [[FN]](i8* {{%[^,]+}}, i[[SZ]]*** [[FPPTR_PLOCAL:%.+]], i32** [[FPPTR_GLOBAL:%.+]], [2 x i8*]** [[FPPTR_BPR]], [2 x i8*]** [[FPPTR_PR]], [2 x i64]** [[FPPTR_SIZE]]) // CHECK-DAG: [[PLOCALADDR:%.+]] = load i[[SZ]]**, i[[SZ]]*** [[FPPTR_PLOCAL]], align // CHECK-DAG: {{%.+}} = load i32*, i32** [[FPPTR_GLOBAL:%.+]], align // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 diff --git a/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp b/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp index 73ef18651b52..dfeb350877e6 100644 --- a/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp +++ b/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp @@ -383,10 +383,10 @@ struct ST { a++; // CK2: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 1 - // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double*** - // CK2: store double** [[RVAL:%.+]], double*** [[CBP]], + // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double**** + // CK2: store double*** [[RVAL:%.+]], double**** [[CBP]], // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE01]] - // CK2: [[CBP1:%.+]] = bitcast double*** [[CBP]] to double** + // CK2: [[CBP1:%.+]] = bitcast double**** [[CBP]] to double** // CK2: [[VAL:%.+]] = load double*, double** [[CBP1]], // CK2: store double* [[VAL]], double** [[PVT:%.+]], // CK2: store double** [[PVT]], double*** [[PVT2:%.+]], @@ -428,8 +428,8 @@ struct ST { la++; // CK2: [[BP1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* %{{.+}}, i32 0, i32 1 - // CK2: [[CBP1:%.+]] = bitcast i8** [[BP1]] to double*** - // CK2: store double** [[RVAL1:%.+]], double*** [[CBP1]], + // CK2: [[CBP1:%.+]] = bitcast i8** [[BP1]] to double**** + // CK2: store double*** [[RVAL1:%.+]], double**** [[CBP1]], // CK2: [[BP2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* %{{.+}}, i32 0, i32 2 // CK2: [[CBP2:%.+]] = bitcast i8** [[BP2]] to double*** // CK2: store double** [[RVAL2:%.+]], double*** [[CBP2]], @@ -438,7 +438,7 @@ struct ST { // CK2: [[VAL2:%.+]] = load double*, double** [[_CBP2]], // CK2: store double* [[VAL2]], double** [[PVT2:%.+]], // CK2: store double** [[PVT2]], double*** [[_PVT2:%.+]], - // CK2: [[_CBP1:%.+]] = bitcast double*** [[CBP1]] to double** + // CK2: [[_CBP1:%.+]] = bitcast double**** [[CBP1]] to double** // CK2: [[VAL1:%.+]] = load double*, double** [[_CBP1]], // CK2: store double* [[VAL1]], double** [[PVT1:%.+]], // CK2: store double** [[PVT1]], double*** [[_PVT1:%.+]], diff --git a/clang/test/OpenMP/target_depend_codegen.cpp b/clang/test/OpenMP/target_depend_codegen.cpp index 45b53f553a11..2dfc346acd85 100644 --- a/clang/test/OpenMP/target_depend_codegen.cpp +++ b/clang/test/OpenMP/target_depend_codegen.cpp @@ -246,7 +246,8 @@ int foo(int n) { // CHECK: define internal void [[MAPPER_ID]](i8* %{{.+}}, i8* %{{.+}}, i8* %{{.+}}, i64 %{{.+}}, i64 %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %{{.+}}) -// CHECK: call void (i8*, ...) %{{.+}}(i8* %{{.+}}, i[[SZ]]*** %{{.+}}, i32** %{{.+}}, [3 x i8*]** [[BPTR_ADDR:%.+]], [3 x i8*]** [[PTR_ADDR:%.+]], [3 x i64]** [[SZ_ADDR:%.+]], [3 x i8*]** [[M_ADDR:%.+]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.+}} to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i[[SZ]]*** %{{.+}}, i32** %{{.+}}, [3 x i8*]** [[BPTR_ADDR:%.+]], [3 x i8*]** [[PTR_ADDR:%.+]], [3 x i64]** [[SZ_ADDR:%.+]], [3 x i8*]** [[M_ADDR:%.+]]) // CHECK: [[BPTR_REF:%.+]] = load [3 x i8*]*, [3 x i8*]** [[BPTR_ADDR]], // CHECK: [[PTR_REF:%.+]] = load [3 x i8*]*, [3 x i8*]** [[PTR_ADDR]], // CHECK: [[SZ_REF:%.+]] = load [3 x i64]*, [3 x i64]** [[SZ_ADDR]], @@ -275,7 +276,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -295,7 +297,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_enter_data_codegen.cpp b/clang/test/OpenMP/target_enter_data_codegen.cpp index 8d9eaa352c5c..d0643467dece 100644 --- a/clang/test/OpenMP/target_enter_data_codegen.cpp +++ b/clang/test/OpenMP/target_enter_data_codegen.cpp @@ -232,7 +232,8 @@ void foo(int arg) { // CK1-DAG: [[FPBPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPBP:%[^,]+]], align // CK1-DAG: [[FPPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPP:%[^,]+]], align // CK1-DAG: [[FPSZADDR]] = load [1 x i64]*, [1 x i64]** [[FPSZ:%[^,]+]], align -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[FPBP]], [1 x i8*]** [[FPP]], [1 x i64]** [[FPSZ]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[FPBP]], [1 x i8*]** [[FPP]], [1 x i64]** [[FPSZ]]) // CK1: ret i32 0 // CK1: } diff --git a/clang/test/OpenMP/target_enter_data_depend_codegen.cpp b/clang/test/OpenMP/target_enter_data_depend_codegen.cpp index 65e8477b8662..5f39a37c7d61 100644 --- a/clang/test/OpenMP/target_enter_data_depend_codegen.cpp +++ b/clang/test/OpenMP/target_enter_data_depend_codegen.cpp @@ -382,7 +382,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1: ret i32 0 // CK1: } @@ -394,7 +395,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1: ret i32 0 // CK1: } @@ -406,7 +408,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1-NOT: __tgt_target_data_end // CK1: ret i32 0 // CK1: } @@ -419,7 +422,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [2 x i8*]*, [2 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [2 x i8*]*, [2 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [2 x i64]*, [2 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [2 x i8*]** [[BP_PRIV]], [2 x i8*]** [[P_PRIV]], [2 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [2 x i8*]** [[BP_PRIV]], [2 x i8*]** [[P_PRIV]], [2 x i64]** [[S_PRIV]]) // CK1-NOT: __tgt_target_data_end // CK1: ret i32 0 // CK1: } diff --git a/clang/test/OpenMP/target_exit_data_codegen.cpp b/clang/test/OpenMP/target_exit_data_codegen.cpp index a9e0bff1b7fd..f056ee1074eb 100644 --- a/clang/test/OpenMP/target_exit_data_codegen.cpp +++ b/clang/test/OpenMP/target_exit_data_codegen.cpp @@ -229,7 +229,8 @@ void foo(int arg) { // CK1-DAG: [[BPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPBPADDR:%[^,]+]], align // CK1-DAG: [[PADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPADDR:%[^,]+]], align // CK1-DAG: [[SZADDR]] = load [1 x i64]*, [1 x i64]** [[FPSZADDR:%[^,]+]], align -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]]) // CK1: ret i32 0 // CK1: } diff --git a/clang/test/OpenMP/target_exit_data_depend_codegen.cpp b/clang/test/OpenMP/target_exit_data_depend_codegen.cpp index 46573dd421d9..5f2103db7d4e 100644 --- a/clang/test/OpenMP/target_exit_data_depend_codegen.cpp +++ b/clang/test/OpenMP/target_exit_data_depend_codegen.cpp @@ -382,7 +382,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1: ret i32 0 // CK1: } @@ -394,7 +395,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1: ret i32 0 // CK1: } @@ -406,7 +408,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1-NOT: __tgt_target_data_end_mapper // CK1: ret i32 0 // CK1: } @@ -419,7 +422,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [2 x i8*]*, [2 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [2 x i8*]*, [2 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [2 x i64]*, [2 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [2 x i8*]** [[BP_PRIV]], [2 x i8*]** [[P_PRIV]], [2 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [2 x i8*]** [[BP_PRIV]], [2 x i8*]** [[P_PRIV]], [2 x i64]** [[S_PRIV]]) // CK1-NOT: __tgt_target_data_end_mapper // CK1: ret i32 0 // CK1: } diff --git a/clang/test/OpenMP/target_map_codegen_28.cpp b/clang/test/OpenMP/target_map_codegen_28.cpp index 32fcfc9e439f..9d561eb5a0e5 100644 --- a/clang/test/OpenMP/target_map_codegen_28.cpp +++ b/clang/test/OpenMP/target_map_codegen_28.cpp @@ -37,13 +37,13 @@ // CK29: [[SSB:%.+]] = type { [[SSA]]*, [[SSA]]** } // CK29-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 -// CK29: [[MTYPE00:@.+]] = private {{.*}}constant [3 x i64] [i64 32, i64 281474976710672, i64 19] +// CK29: [[MTYPE00:@.+]] = private {{.*}}constant [2 x i64] [i64 32, i64 281474976710675] // CK29-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK29: [[MTYPE01:@.+]] = private {{.*}}constant [3 x i64] [i64 32, i64 281474976710672, i64 19] // CK29-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 -// CK29: [[MTYPE02:@.+]] = private {{.*}}constant [3 x i64] [i64 32, i64 281474976710672, i64 19] +// CK29: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i64] [i64 32, i64 281474976710675] struct SSA{ double *p; @@ -60,7 +60,7 @@ struct SSB{ void foo() { // Region 00 - // CK29-DAG: call i32 @__tgt_target_mapper(%struct.ident_t* @{{.+}}, i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z:64|32]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE00]]{{.+}}, i8** null, i8** null) + // CK29-DAG: call i32 @__tgt_target_mapper(%struct.ident_t* @{{.+}}, i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z:64|32]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}}, i8** null, i8** null) // CK29-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] // CK29-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] @@ -70,32 +70,22 @@ struct SSB{ // CK29-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 // CK29-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 // CK29-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SSB]]** - // CK29-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SSA]]** + // CK29-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SSA]]*** // CK29-DAG: store [[SSB]]* [[VAR0:%.+]], [[SSB]]** [[CBP0]] // CK29-DAG: store [[SSA]]** [[VAR00:%.+]], [[SSA]]*** [[CP0]] // CK29-DAG: store i64 %{{.+}}, i64* [[S0]] // CK29-DAG: [[VAR0]] = load [[SSB]]*, [[SSB]]** % // CK29-DAG: [[VAR00]] = getelementptr inbounds [[SSB]], [[SSB]]* [[VAR0]], i32 0, i32 0 - // CK29-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 - // CK29-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 - // CK29-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 - // CK29-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SSA]]*** - // CK29-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to double*** - // CK29-DAG: store [[SSA]]** [[VAR00]], [[SSA]]*** [[CBP1]] - // CK29-DAG: store double** [[VAR1:%.+]], double*** [[CP1]] - // CK29-DAG: store i64 {{8|4}}, i64* [[S1]] - // CK29-DAG: [[VAR1]] = load double**, double*** [[VAR1_REF:%.+]], - // CK29-DAG: [[VAR1_REF]] = getelementptr inbounds [[SSA]], [[SSA]]* %{{.+}}, i32 0, i32 1 - - // CK29-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 - // CK29-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 - // CK29-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 - // CK29-DAG: [[CBP2:%.+]] = bitcast i8** [[BP2]] to double*** + // CK29-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK29-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK29-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK29-DAG: [[CBP2:%.+]] = bitcast i8** [[BP2]] to double**** // CK29-DAG: [[CP2:%.+]] = bitcast i8** [[P2]] to double** - // CK29-DAG: store double** [[VAR1]], double*** [[CBP2]] + // CK29-DAG: store double*** [[VAR1:%.+]], double**** [[CBP2]] // CK29-DAG: store double* [[VAR2:%.+]], double** [[CP2]] // CK29-DAG: store i64 80, i64* [[S2]] + // CK29-DAG: [[VAR1]] = getelementptr inbounds [[SSA]], [[SSA]]* %{{.+}}, i32 0, i32 1 // CK29-DAG: [[VAR2]] = getelementptr inbounds double, double* [[VAR22:%.+]], i{{.+}} 0 // CK29-DAG: [[VAR22]] = load double*, double** %{{.+}}, @@ -116,19 +106,18 @@ struct SSB{ // CK29-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 // CK29-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 // CK29-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SSB]]** - // CK29-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SSA]]** + // CK29-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SSA]]**** // CK29-DAG: store [[SSB]]* [[VAR0]], [[SSB]]** [[CBP0]] - // CK29-DAG: store [[SSA]]** [[VAR00:%.+]], [[SSA]]*** [[CP0]] + // CK29-DAG: store [[SSA]]*** [[VAR000:%.+]], [[SSA]]**** [[CP0]] // CK29-DAG: store i64 %{{.+}}, i64* [[S0]] - // CK29-DAG: [[VAR00]] = load [[SSA]]**, [[SSA]]*** [[VAR000:%.+]], // CK29-DAG: [[VAR000]] = getelementptr inbounds [[SSB]], [[SSB]]* [[VAR0]], i32 0, i32 1 // CK29-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 // CK29-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 // CK29-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 - // CK29-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SSA]]*** + // CK29-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SSA]]**** // CK29-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to double*** - // CK29-DAG: store [[SSA]]** [[VAR00]], [[SSA]]*** [[CBP1]] + // CK29-DAG: store [[SSA]]*** [[VAR000]], [[SSA]]**** [[CBP1]] // CK29-DAG: store double** [[VAR1:%.+]], double*** [[CP1]] // CK29-DAG: store i64 {{8|4}}, i64* [[S1]] // CK29-DAG: [[VAR1]] = getelementptr inbounds [[SSA]], [[SSA]]* %{{.+}}, i32 0, i32 0 @@ -151,7 +140,7 @@ struct SSB{ } // Region 02 - // CK29-DAG: call i32 @__tgt_target_mapper(%struct.ident_t* @{{.+}}, i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE02]]{{.+}}, i8** null, i8** null) + // CK29-DAG: call i32 @__tgt_target_mapper(%struct.ident_t* @{{.+}}, i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}}, i8** null, i8** null) // CK29-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] // CK29-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] @@ -161,32 +150,21 @@ struct SSB{ // CK29-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 // CK29-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 // CK29-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SSB]]** - // CK29-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SSA]]** + // CK29-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SSA]]**** // CK29-DAG: store [[SSB]]* [[VAR0]], [[SSB]]** [[CBP0]] - // CK29-DAG: store [[SSA]]** [[VAR00:%.+]], [[SSA]]*** [[CP0]] + // CK29-DAG: store [[SSA]]*** [[VAR000:%.+]], [[SSA]]**** [[CP0]] // CK29-DAG: store i64 %{{.+}}, i64* [[S0]] - // CK29-DAG: [[VAR00]] = load [[SSA]]**, [[SSA]]*** [[VAR000:%.+]], // CK29-DAG: [[VAR000]] = getelementptr inbounds [[SSB]], [[SSB]]* [[VAR0]], i32 0, i32 1 - // CK29-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 - // CK29-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 - // CK29-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 - // CK29-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SSA]]*** - // CK29-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to double*** - // CK29-DAG: store [[SSA]]** [[VAR00]], [[SSA]]*** [[CBP1]] - // CK29-DAG: store double** [[VAR1:%.+]], double*** [[CP1]] - // CK29-DAG: store i64 {{8|4}}, i64* [[S1]] - // CK29-DAG: [[VAR1]] = load double**, double*** [[VAR1_REF:%.+]], - // CK29-DAG: [[VAR1_REF]] = getelementptr inbounds [[SSA]], [[SSA]]* %{{.+}}, i32 0, i32 1 - - // CK29-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 - // CK29-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 - // CK29-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 - // CK29-DAG: [[CBP2:%.+]] = bitcast i8** [[BP2]] to double*** + // CK29-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK29-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK29-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK29-DAG: [[CBP2:%.+]] = bitcast i8** [[BP2]] to double**** // CK29-DAG: [[CP2:%.+]] = bitcast i8** [[P2]] to double** - // CK29-DAG: store double** [[VAR1]], double*** [[CBP2]] + // CK29-DAG: store double*** [[VAR1:%.+]], double**** [[CBP2]] // CK29-DAG: store double* [[VAR2:%.+]], double** [[CP2]] // CK29-DAG: store i64 80, i64* [[S2]] + // CK29-DAG: [[VAR1]] = getelementptr inbounds [[SSA]], [[SSA]]* %{{.+}}, i32 0, i32 1 // CK29-DAG: [[VAR2]] = getelementptr inbounds double, double* [[VAR22:%.+]], i{{.+}} 0 // CK29-DAG: [[VAR22]] = load double*, double** %{{.+}}, diff --git a/clang/test/OpenMP/target_map_codegen_35.cpp b/clang/test/OpenMP/target_map_codegen_35.cpp new file mode 100644 index 000000000000..74fbcf703958 --- /dev/null +++ b/clang/test/OpenMP/target_map_codegen_35.cpp @@ -0,0 +1,182 @@ +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +///==========================================================================/// +// RUN: %clang_cc1 -DCK35 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK35 --check-prefix CK35-64 +// RUN: %clang_cc1 -DCK35 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK35 --check-prefix CK35-64 +// RUN: %clang_cc1 -DCK35 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK35 --check-prefix CK35-32 +// RUN: %clang_cc1 -DCK35 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK35 --check-prefix CK35-32 + +// RUN: %clang_cc1 -DCK35 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// RUN: %clang_cc1 -DCK35 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// RUN: %clang_cc1 -DCK35 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// RUN: %clang_cc1 -DCK35 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// SIMD-ONLY32-NOT: {{__kmpc|__tgt}} +#ifdef CK35 + +class S { +public: + S(double &b) : b(b) {} + int a; + double &b; + void foo(); +}; + +// TARGET_PARAM = 0x20 +// MEMBER_OF_1 | TO = 0x1000000000001 +// MEMBER_OF_1 | PTR_AND_OBJ | TO = 0x1000000000011 +// CK35-DAG: [[MTYPE_TO:@.+]] = {{.+}}constant [4 x i64] [i64 [[#0x20]], i64 [[#0x1000000000001]], i64 [[#0x1000000000001]], i64 [[#0x1000000000011]]] +// TARGET_PARAM = 0x20 +// MEMBER_OF_1 | PTR_AND_OBJ | FROM = 0x1000000000012 +// CK35-DAG: [[MTYPE_FROM:@.+]] = {{.+}}constant [2 x i64] [i64 [[#0x20]], i64 [[#0x1000000000012]]] + +void ref_map() { + double b; + S s(b); + + // CK35-DAG: call i32 @__tgt_target_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{.+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE_TO]]{{.+}}, i8** null, i8** null) + // CK35-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK35-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK35-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // pass TARGET_PARAM {&s, &s, ((void*)(&s+1)-(void*)&s)} + + // CK35-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK35-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK35-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK35-DAG: [[BPC0:%.+]] = bitcast i8** [[BP0]] to %class.S** + // CK35-DAG: [[PC0:%.+]] = bitcast i8** [[P0]] to %class.S** + + // CK35-DAG: store %class.S* [[S_ADDR:%.+]], %class.S** [[BPC0]], + // CK35-DAG: store %class.S* [[S_ADDR]], %class.S** [[PC0]], + // CK35-DAG: store i64 [[S_SIZE:%.+]], i64* [[S0]], + + // CK35-DAG: [[S_SIZE]] = sdiv exact i64 [[SZ:%.+]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) + // CK35-DAG: [[SZ]] = sub i64 [[S_1_INTPTR:%.+]], [[S_INTPTR:%.+]] + // CK35-DAG: [[S_1_INTPTR]] = ptrtoint i8* [[S_1_VOID:%.+]] to i64 + // CK35-DAG: [[S_INTPTR]] = ptrtoint i8* [[S_VOID:%.+]] to i64 + // CK35-DAG: [[S_1_VOID]] = bitcast %class.S* [[S_1:%.+]] to i8* + // CK35-DAG: [[S_VOID]] = bitcast %class.S* [[S_ADDR]] to i8* + // CK35-DAG: [[S_1]] = getelementptr %class.S, %class.S* [[S_ADDR]], i32 1 + + // pass MEMBER_OF_1 | TO {&s, &s, ((void*)(&s.a+1)-(void*)&s)} to copy the data of s.a. + + // CK35-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK35-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK35-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + + // CK35-DAG: [[BPC1:%.+]] = bitcast i8** [[BP1]] to %class.S** + // CK35-DAG: [[PC1:%.+]] = bitcast i8** [[P1]] to %class.S** + + // CK35-DAG: store %class.S* [[S_ADDR]], %class.S** [[BPC1]], + // CK35-DAG: store %class.S* [[S_ADDR]], %class.S** [[PC1]], + // CK35-DAG: store i64 [[A_SIZE:%.+]], i64* [[S1]], + + // CK35-DAG: [[A_SIZE]] = sdiv exact i64 [[SZ:%.+]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) + // CK35-DAG: [[SZ]] = sub i64 [[B_BEGIN_INTPTR:%.+]], [[S_INTPTR:%.+]] + // CK35-DAG: [[S_INTPTR]] = ptrtoint i8* [[S_VOID:%.+]] to i64 + // CK35-DAG: [[B_BEGIN_INTPTR]] = ptrtoint i8* [[B_BEGIN_VOID:%.+]] to i64 + // CK35-DAG: [[S_VOID]] = bitcast %class.S* [[S_ADDR]] to i8* + // CK35-DAG: [[B_BEGIN_VOID]] = bitcast double** [[B_ADDR:%.+]] to i8* + // CK35-DAG: [[B_ADDR]] = getelementptr inbounds %class.S, %class.S* [[S_ADDR]], i32 0, i32 1 + + // pass MEMBER_OF_1 | TO {&s, &s.b+1, ((void*)(&s+1)-(void*)(&s.b+1))} to copy the data of remainder of s. + + // CK35-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK35-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK35-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 + + // CK35-DAG: [[BPC2:%.+]] = bitcast i8** [[BP2]] to %class.S** + // CK35-DAG: [[PC2:%.+]] = bitcast i8** [[P2]] to double*** + + // CK35-DAG: store %class.S* [[S_ADDR]], %class.S** [[BPC2]], + // CK35-DAG: store double** [[B_END:%.+]], double*** [[PC2]], + // CK35-DAG: store i64 [[REM_SIZE:%.+]], i64* [[S2]], + + // CK35-DAG: [[B_END]] = getelementptr double*, double** [[B_ADDR]], i{{.+}} 1 + + // CK35-DAG: [[REM_SIZE]] = sdiv exact i64 [[SZ:%.+]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) + // CK35-DAG: [[SZ]] = sub i64 [[S_END_INTPTR:%.+]], [[B_END_INTPTR:%.+]] + // CK35-DAG: [[B_END_INTPTR]] = ptrtoint i8* [[B_END_VOID:%.+]] to i64 + // CK35-DAG: [[S_END_INTPTR]] = ptrtoint i8* [[S_END_VOID:%.+]] to i64 + // CK35-DAG: [[B_END_VOID]] = bitcast double** [[B_END]] to i8* + // CK35-DAG: [[S_END_VOID]] = getelementptr i8, i8* [[S_LAST:%.+]], i{{.+}} 1 + // CK35-64-DAG: [[S_LAST]] = getelementptr i8, i8* [[S_VOIDPTR:%.+]], i64 15 + // CK35-32-DAG: [[S_LAST]] = getelementptr i8, i8* [[S_VOIDPTR:%.+]], i32 7 + // CK35-DAG: [[S_VOIDPTR]] = bitcast %class.S* [[S_ADDR]] to i8* + + // pass MEMBER_OF_1 | PTR_AND_OBJ | TO {&s, &s.b, 8|4} to copy the data of s.b. + + // CK35-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3 + // CK35-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3 + // CK35-DAG: [[S3:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 3 + + // CK35-DAG: [[BPC3:%.+]] = bitcast i8** [[BP3]] to %class.S** + // CK35-DAG: [[PC3:%.+]] = bitcast i8** [[P3]] to double** + + // CK35-DAG: store %class.S* [[S_ADDR]], %class.S** [[BPC3]], + // CK35-DAG: store double* [[B_ADDR:%.+]], double** [[PC3]], + // CK35-DAG: store i64 8, i64* [[S3]], + + // CK35-DAG: [[B_ADDR]] = load double*, double** [[B_REF:%.+]], + // CK35-DAG: [[B_REF]] = getelementptr inbounds %class.S, %class.S* [[S_ADDR]], i32 0, i32 1 + + #pragma omp target map(to: s, s.b) + s.foo(); + + // CK35 : call void + + // CK35-DAG: call i32 @__tgt_target_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{.+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE_FROM]]{{.+}}, i8** null, i8** null) + // CK35-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK35-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK35-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // pass TARGET_PARAM {&s, &s.b, ((void*)(&s.b+1)-(void*)&s.b)} + + // CK35-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK35-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK35-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK35-DAG: [[BPC0:%.+]] = bitcast i8** [[BP0]] to %class.S** + // CK35-DAG: [[PC0:%.+]] = bitcast i8** [[P0]] to double*** + + // CK35-DAG: store %class.S* [[S_ADDR]], %class.S** [[BPC0]], + // CK35-DAG: store double** [[SB_ADDR:%.+]], double*** [[PC0]], + // CK35-DAG: store i64 [[B_SIZE:%.+]], i64* [[S0]], + + // CK35-DAG: [[B_SIZE]] = sdiv exact i64 [[SZ:%.+]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) + // CK35-DAG: [[SZ]] = sub i64 [[SB_1_INTPTR:%.+]], [[SB_INTPTR:%.+]] + // CK35-DAG: [[SB_1_INTPTR]] = ptrtoint i8* [[SB_1_VOID:%.+]] to i64 + // CK35-DAG: [[SB_INTPTR]] = ptrtoint i8* [[SB_VOID:%.+]] to i64 + // CK35-DAG: [[SB_1_VOID]] = bitcast double** [[SB_1:%.+]] to i8* + // CK35-DAG: [[SB_VOID]] = bitcast double** [[SB_ADDR:%.+]] to i8* + // CK35-DAG: [[SB_ADDR]] = getelementptr inbounds %class.S, %class.S* [[S_ADDR]], i32 0, i32 1 + // CK35-DAG: [[SB_1]] = getelementptr double*, double** [[SB_ADDR]], i{{.+}} 1 + + // pass MEMBER_OF_1 | PTR_AND_OBJ | FROM {&s, &s.b, 8|4} to copy the data of s.c. + + // CK35-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK35-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK35-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + + // CK35-DAG: [[BPC1:%.+]] = bitcast i8** [[BP1]] to %class.S** + // CK35-DAG: [[PC1:%.+]] = bitcast i8** [[P1]] to double** + + // CK35-DAG: store %class.S* [[S_ADDR]], %class.S** [[BPC1]], + // CK35-DAG: store double* [[B_ADDR:%.+]], double** [[PC1]], + // CK35-DAG: store i64 8, i64* [[S1]], + + // CK35-DAG: [[B_ADDR]] = load double*, double** [[SB_ADDR]], + + #pragma omp target map(from: s.b) + s.foo(); +} + +#endif // CK35 +#endif diff --git a/clang/test/OpenMP/target_parallel_depend_codegen.cpp b/clang/test/OpenMP/target_parallel_depend_codegen.cpp index 66b8d41a774c..14e6a65a3d58 100644 --- a/clang/test/OpenMP/target_parallel_depend_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_depend_codegen.cpp @@ -199,7 +199,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -221,7 +222,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -241,7 +243,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_parallel_for_codegen.cpp b/clang/test/OpenMP/target_parallel_for_codegen.cpp index f941bd0e32e3..3e577df3d4bb 100644 --- a/clang/test/OpenMP/target_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_codegen.cpp @@ -455,7 +455,8 @@ int foo(int n) { // CHECK-DAG: [[FPBPR]] = load [3 x i8*]*, [3 x i8*]** [[FPBPRADDR:%[^,]+]], align // CHECK-DAG: [[FPPR]] = load [3 x i8*]*, [3 x i8*]** [[FPPRADDR:%[^,]+]], align // CHECK-DAG: [[FPSIZE]] = load [3 x i64]*, [3 x i64]** [[FPSIZEADDR:%[^,]+]], align -// CHECK-DAG: call void (i8*, ...) %{{[0-9]+}}(i8* %{{[^,]+}}, i16** %{{[^,]+}}, [3 x i8*]** [[FPBPRADDR]], [3 x i8*]** [[FPPRADDR]], [3 x i64]** [[FPSIZEADDR]]) +// CHECK-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK-DAG: call void [[FN]](i8* %{{[^,]+}}, i16** %{{[^,]+}}, [3 x i8*]** [[FPBPRADDR]], [3 x i8*]** [[FPPRADDR]], [3 x i64]** [[FPSIZEADDR]]) // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] // CHECK: [[FAIL]] diff --git a/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp b/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp index c25216a5e3b7..ed16b3737de7 100644 --- a/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp @@ -194,7 +194,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -216,7 +217,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -236,7 +238,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp b/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp index 68fe197f21cf..8d08bb4af3a2 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp @@ -194,7 +194,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -216,7 +217,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -236,7 +238,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_simd_depend_codegen.cpp b/clang/test/OpenMP/target_simd_depend_codegen.cpp index 7071b5bc5416..f17948a758a6 100644 --- a/clang/test/OpenMP/target_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_simd_depend_codegen.cpp @@ -198,7 +198,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -220,7 +221,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -240,7 +242,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_teams_codegen.cpp b/clang/test/OpenMP/target_teams_codegen.cpp index a5a4a8001462..8decb4721976 100644 --- a/clang/test/OpenMP/target_teams_codegen.cpp +++ b/clang/test/OpenMP/target_teams_codegen.cpp @@ -393,7 +393,8 @@ int foo(int n) { // CHECK-DAG: [[BPADDR]] = load [3 x i8*]*, [3 x i8*]** [[FPBPADDR:%[^,]+]], align // CHECK-DAG: [[PADDR]] = load [3 x i8*]*, [3 x i8*]** [[FPPADDR:%[^,]+]], align // CHECK-DAG: [[SIZEADDR]] = load [3 x i64]*, [3 x i64]** [[FPSIZEADDR:%[^,]+]], align -// CHECK-DAG: call void (i8*, ...) %{{.+}}(i8* %{{.+}}, i16** %{{.+}}, [3 x i8*]** [[FPBPADDR]], [3 x i8*]** [[FPPADDR]], [3 x i64]** [[FPSIZEADDR]]) +// CHECK-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK-DAG: call void [[FN]](i8* %{{.+}}, i16** %{{.+}}, [3 x i8*]** [[FPBPADDR]], [3 x i8*]** [[FPPADDR]], [3 x i64]** [[FPSIZEADDR]]) // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] // CHECK: [[FAIL]] diff --git a/clang/test/OpenMP/target_teams_depend_codegen.cpp b/clang/test/OpenMP/target_teams_depend_codegen.cpp index 36f18fb22679..ed82d158fcfa 100644 --- a/clang/test/OpenMP/target_teams_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_depend_codegen.cpp @@ -198,7 +198,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -220,7 +221,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -240,7 +242,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_teams_distribute_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_codegen.cpp index d29cc68740a6..3de7aa2d012a 100644 --- a/clang/test/OpenMP/target_teams_distribute_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_codegen.cpp @@ -393,7 +393,8 @@ int foo(int n) { // CHECK-DAG: [[BPADDR]] = load [3 x i8*]*, [3 x i8*]** [[FPBPADDR:%[^,]+]], align // CHECK-DAG: [[PADDR]] = load [3 x i8*]*, [3 x i8*]** [[FPPADDR:%[^,]+]], align // CHECK-DAG: [[SIZEADDR]] = load [3 x i64]*, [3 x i64]** [[FPSIZEADDR:%[^,]+]], align -// CHECK-DAG: call void (i8*, ...) %{{.+}}(i8* %{{.+}}, i16** %{{.+}}, [3 x i8*]** [[FPBPADDR]], [3 x i8*]** [[FPPADDR]], [3 x i64]** [[FPSIZEADDR]]) +// CHECK-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK-DAG: call void [[FN]](i8* %{{.+}}, i16** %{{.+}}, [3 x i8*]** [[FPBPADDR]], [3 x i8*]** [[FPPADDR]], [3 x i64]** [[FPSIZEADDR]]) // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] // CHECK: [[FAIL]] diff --git a/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp index 9b8b0d4ecfdd..ca063005f036 100644 --- a/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp @@ -194,7 +194,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -216,7 +217,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -236,7 +238,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp index 0229ace911f8..c0f53239aa13 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp @@ -39,7 +39,7 @@ #ifdef CK1 -// HCK_NO_TGT-NOT: @__kmpc_push_target_tripcount +// HCK_NO_TGT-NOT: @__kmpc_push_target_tripcount_mapper // HCK1: define{{.*}} i32 @{{.+}}target_teams_fun{{.*}}( int target_teams_fun(int *g){ @@ -60,7 +60,7 @@ int target_teams_fun(int *g){ // HCK1: [[N_PAR:%.+]] = load{{.+}}, {{.+}} [[N_CAST]], // HCK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]], // HCK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]], - // HCK1: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) + // HCK1: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) // HCK1: call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, // HCK1: call void @[[OFFL1:.+]](i{{32|64}} [[N_PAR]], {{.+}}, i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]]) diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp index 914798ed1f15..d327a808da5f 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp @@ -194,7 +194,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -216,7 +217,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -236,7 +238,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp index 6650e0557511..efe7df819fb6 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp @@ -49,10 +49,10 @@ int Arg; // CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test void gtid_test() { -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_0:@.+]]( -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_1:@.+]]( #pragma omp target teams distribute parallel for @@ -107,12 +107,12 @@ int tmain(T Arg) { // CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main() int main() { -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_0:@.+]]( -// CHECK-NOT: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK-NOT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call void [[OFFLOADING_FUN_1:@.+]]( -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_2:@.+]]( // CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp index b2ab37f22ec3..b99ba9d38a43 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp @@ -14,7 +14,7 @@ // CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test void gtid_test() { -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: %0 = call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{.+}}, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 0, i32 0) // CHECK: call void [[TARGET_OUTLINE:@.+]]() // CHECK: ret void diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp index e6049145702b..39ccb87462c0 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp @@ -60,7 +60,7 @@ int target_teams_fun(int *g){ // HCK1: [[N_PAR:%.+]] = load{{.+}}, {{.+}} [[N_CAST]], // HCK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]], // HCK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]], -// HCK1: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) +// HCK1: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) // HCK1: call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, // HCK1: call void @[[OFFL1:.+]](i{{32|64}} [[I_PAR]], i{{32|64}} [[N_PAR]], {{.+}}, i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]]) diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp index a26082fbba88..bc190016ffd4 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp @@ -194,7 +194,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], @@ -216,7 +217,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -236,7 +238,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp index 8b0eaba07f1c..19dc15b94f64 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp @@ -43,10 +43,10 @@ int Arg; // CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test void gtid_test() { -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_0:@.+]]( -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_1:@.+]]( #ifdef OMP5 @@ -110,12 +110,12 @@ int tmain(T Arg) { // CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main() int main() { -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_0:@.+]]( -// CHECK-NOT: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK-NOT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call void [[OFFLOADING_FUN_1:@.+]]( -// CHECK: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 100) +// CHECK: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 100) // CHECK: call i{{[0-9]+}} @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, // CHECK: call void [[OFFLOADING_FUN_2:@.+]]( // CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain diff --git a/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp index 61c48e6632d0..527b71cafc48 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp @@ -380,7 +380,8 @@ int foo(int n) { // CHECK-DAG: [[BPADDR]] = load [3 x i8*]*, [3 x i8*]** [[FPBPADDR:%[^,]+]], align // CHECK-DAG: [[PADDR]] = load [3 x i8*]*, [3 x i8*]** [[FPPADDR:%[^,]+]], align // CHECK-DAG: [[SIZEADDR]] = load [3 x i64]*, [3 x i64]** [[FPSIZEADDR:%[^,]+]], align -// CHECK-DAG: call void (i8*, ...) %{{.+}}(i8* %{{.+}}, i16** %{{.+}}, [3 x i8*]** [[FPBPADDR]], [3 x i8*]** [[FPPADDR]], [3 x i64]** [[FPSIZEADDR]]) +// CHECK-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK-DAG: call void [[FN]](i8* %{{.+}}, i16** %{{.+}}, [3 x i8*]** [[FPBPADDR]], [3 x i8*]** [[FPPADDR]], [3 x i64]** [[FPSIZEADDR]]) // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] // CHECK: [[FAIL]] diff --git a/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp index 0161ec9d55e6..d4a82bfb48fd 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp @@ -233,7 +233,8 @@ int foo(int n) { // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* %{{.+}}, i[[SZ]] %{{.+}}) // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // OMP45: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // OMP50: [[SZT:%.+]] = getelementptr inbounds [3 x i64], [3 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 // OMP45: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 @@ -262,7 +263,8 @@ int foo(int n) { // CHECK: ret i32 0 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ @@ -285,7 +287,8 @@ int foo(int n) { // CHECK-32: load i32, i32* [[AA_ADDR]], align // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias %1) -// CHECK: call void (i8*, ...) % +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CHECK: call void [[FN]]( // CHECK: [[BP1_I32:%.+]] = load i32, i32* % // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], diff --git a/clang/test/OpenMP/target_update_codegen.cpp b/clang/test/OpenMP/target_update_codegen.cpp index 911d2ae031eb..9f76da7c67a2 100644 --- a/clang/test/OpenMP/target_update_codegen.cpp +++ b/clang/test/OpenMP/target_update_codegen.cpp @@ -170,7 +170,8 @@ void foo(int arg) { // CK1-DAG: [[BPADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPBPADDR:%[^,]+]], align // CK1-DAG: [[PADDR]] = load [1 x i8*]*, [1 x i8*]** [[FPPADDR:%[^,]+]], align // CK1-DAG: [[SZADDR]] = load [1 x i64]*, [1 x i64]** [[FPSZADDR:%[^,]+]], align -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[FPBPADDR]], [1 x i8*]** [[FPPADDR]], [1 x i64]** [[FPSZADDR]]) // CK1: ret i32 0 // CK1: } #endif diff --git a/clang/test/OpenMP/target_update_depend_codegen.cpp b/clang/test/OpenMP/target_update_depend_codegen.cpp index 621def50e16d..f80536f4f28d 100644 --- a/clang/test/OpenMP/target_update_depend_codegen.cpp +++ b/clang/test/OpenMP/target_update_depend_codegen.cpp @@ -382,7 +382,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1: ret i32 0 // CK1: } @@ -394,7 +395,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1: ret i32 0 // CK1: } @@ -406,7 +408,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [1 x i8*]*, [1 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [1 x i8*]*, [1 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [1 x i64]*, [1 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [1 x i8*]** [[BP_PRIV]], [1 x i8*]** [[P_PRIV]], [1 x i64]** [[S_PRIV]]) // CK1-NOT: __tgt_target_data_end // CK1: ret i32 0 // CK1: } @@ -419,7 +422,8 @@ void foo(int arg) { // CK1-DAG: [[BP]] = load [2 x i8*]*, [2 x i8*]** [[BP_PRIV:%[^,]+]], // CK1-DAG: [[P]] = load [2 x i8*]*, [2 x i8*]** [[P_PRIV:%[^,]+]], // CK1-DAG: [[S]] = load [2 x i64]*, [2 x i64]** [[S_PRIV:%[^,]+]], -// CK1-DAG: call void (i8*, ...) %{{.+}}(i8* %{{[^,]+}}, [2 x i8*]** [[BP_PRIV]], [2 x i8*]** [[P_PRIV]], [2 x i64]** [[S_PRIV]]) +// CK1-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, +// CK1-DAG: call void [[FN]](i8* %{{[^,]+}}, [2 x i8*]** [[BP_PRIV]], [2 x i8*]** [[P_PRIV]], [2 x i64]** [[S_PRIV]]) // CK1-NOT: __tgt_target_data_end // CK1: ret i32 0 // CK1: } diff --git a/clang/test/OpenMP/task_codegen.cpp b/clang/test/OpenMP/task_codegen.cpp index a2f319892402..503cff1ad360 100644 --- a/clang/test/OpenMP/task_codegen.cpp +++ b/clang/test/OpenMP/task_codegen.cpp @@ -315,7 +315,8 @@ int main() { // CHECK: define internal i32 [[TASK_ENTRY6]](i32 %0, [[KMP_TASK_T]]{{.*}}* noalias %{{.+}}) // UNTIEDRT: [[S1_ADDR_PTR:%.+]] = alloca %struct.S*, // UNTIEDRT: [[S2_ADDR_PTR_REF:%.+]] = alloca %struct.S**, -// UNTIEDRT: call void (i8*, ...) %{{.+}}(i8* %{{.+}}, %struct.S** [[S1_ADDR_PTR]], %struct.S*** [[S2_ADDR_PTR_REF]]) +// UNTIEDRT: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.*}} to void (i8*, +// UNTIEDRT: call void [[FN]](i8* %{{.+}}, %struct.S** [[S1_ADDR_PTR]], %struct.S*** [[S2_ADDR_PTR_REF]]) // UNTIEDRT-DAG: [[S1_ADDR:%.+]] = load %struct.S*, %struct.S** [[S1_ADDR_PTR]], // UNTIEDRT-DAG: [[S2_ADDR_PTR:%.+]] = load %struct.S**, %struct.S*** [[S2_ADDR_PTR_REF]], // UNTIEDRT-DAG: [[S2_ADDR:%.+]] = load %struct.S*, %struct.S** [[S2_ADDR_PTR]], diff --git a/clang/test/OpenMP/task_firstprivate_codegen.cpp b/clang/test/OpenMP/task_firstprivate_codegen.cpp index cc4f102b11f3..31fc7838af4e 100644 --- a/clang/test/OpenMP/task_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/task_firstprivate_codegen.cpp @@ -275,7 +275,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**, [[S_DOUBLE_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]], [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]], [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -395,7 +396,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/task_in_reduction_codegen.cpp b/clang/test/OpenMP/task_in_reduction_codegen.cpp index 64477211ca1f..ffc4fa7d5894 100644 --- a/clang/test/OpenMP/task_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/task_in_reduction_codegen.cpp @@ -76,7 +76,8 @@ int main(int argc, char **argv) { // CHECK-NEXT: } // CHECK: define internal {{.*}} [[OMP_TASK]]( -// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.*}} to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) // CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]], // CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]], // CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds % diff --git a/clang/test/OpenMP/task_private_codegen.cpp b/clang/test/OpenMP/task_private_codegen.cpp index c995c353c87c..54f4907a9fef 100644 --- a/clang/test/OpenMP/task_private_codegen.cpp +++ b/clang/test/OpenMP/task_private_codegen.cpp @@ -230,7 +230,8 @@ int main() { // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -341,7 +342,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/taskgroup_messages.cpp b/clang/test/OpenMP/taskgroup_messages.cpp index 6bac1614b6a9..fb774e03b530 100644 --- a/clang/test/OpenMP/taskgroup_messages.cpp +++ b/clang/test/OpenMP/taskgroup_messages.cpp @@ -71,7 +71,7 @@ int foo() { foo(); } -#pragma omp taskgroup init // expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}} +#pragma omp taskgroup initi // expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}} ; return 0; } diff --git a/clang/test/OpenMP/taskloop_firstprivate_codegen.cpp b/clang/test/OpenMP/taskloop_firstprivate_codegen.cpp index 40477158b916..7c9d28bda0e7 100644 --- a/clang/test/OpenMP/taskloop_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/taskloop_firstprivate_codegen.cpp @@ -277,7 +277,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -426,7 +427,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp index 3a150eeedd1f..8eeaa4fc5bf4 100644 --- a/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp @@ -64,7 +64,8 @@ int main(int argc, char **argv) { // CHECK-NEXT: } // CHECK: define internal {{.*}} [[OMP_TASK]]( -// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.*}} to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) // CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]], // CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]], // CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds % diff --git a/clang/test/OpenMP/taskloop_lastprivate_codegen.cpp b/clang/test/OpenMP/taskloop_lastprivate_codegen.cpp index 183dd9eb197f..fbc6cca841d3 100644 --- a/clang/test/OpenMP/taskloop_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/taskloop_lastprivate_codegen.cpp @@ -269,7 +269,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -436,7 +437,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/taskloop_private_codegen.cpp b/clang/test/OpenMP/taskloop_private_codegen.cpp index dd5feaeb5b22..5f2df419a646 100644 --- a/clang/test/OpenMP/taskloop_private_codegen.cpp +++ b/clang/test/OpenMP/taskloop_private_codegen.cpp @@ -230,7 +230,8 @@ int main() { // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -358,7 +359,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp index ef75e72aa028..db3d787bc38a 100644 --- a/clang/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp @@ -277,7 +277,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -426,7 +427,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp index e0fd21d8e937..0c2bab835cdd 100644 --- a/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp @@ -64,7 +64,8 @@ int main(int argc, char **argv) { // CHECK-NEXT: } // CHECK: define internal {{.*}} [[OMP_TASK]]( -// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.*}} to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]]) // CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]], // CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]], // CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds % diff --git a/clang/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp index 895da41aac8c..b47f7bff2fa4 100644 --- a/clang/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp @@ -267,7 +267,8 @@ int main() { // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], @@ -434,7 +435,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/taskloop_simd_private_codegen.cpp b/clang/test/OpenMP/taskloop_simd_private_codegen.cpp index 73f35a17f2c0..388ac00a9deb 100644 --- a/clang/test/OpenMP/taskloop_simd_private_codegen.cpp +++ b/clang/test/OpenMP/taskloop_simd_private_codegen.cpp @@ -230,7 +230,8 @@ int main() { // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], @@ -358,7 +359,8 @@ int main() { // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, +// CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], diff --git a/clang/test/OpenMP/taskloop_with_atomic_codegen.cpp b/clang/test/OpenMP/taskloop_with_atomic_codegen.cpp index 7cabcc3377f9..077908f5bc77 100644 --- a/clang/test/OpenMP/taskloop_with_atomic_codegen.cpp +++ b/clang/test/OpenMP/taskloop_with_atomic_codegen.cpp @@ -27,6 +27,7 @@ int main() { // Check that occupanices var is firstprivatized. // CHECK-DAG: atomicrmw add i32* [[FP_OCCUP:%.+]], i32 1 monotonic, align 4 // CHECK-DAG: [[FP_OCCUP]] = load i32*, i32** [[FP_OCCUP_ADDR:%[^,]+]], -// CHECK-DAG: call void (i8*, ...) %{{.+}}(i8* %{{.+}}, i32** [[FP_OCCUP_ADDR]]) +// CHECK-DAG: [[FN:%.+]] = bitcast void (i8*, ...)* %{{.*}} to void (i8*, +// CHECK-DAG: call void [[FN]](i8* %{{.+}}, i32** [[FP_OCCUP_ADDR]]) #endif diff --git a/clang/test/OpenMP/teams_distribute_codegen.cpp b/clang/test/OpenMP/teams_distribute_codegen.cpp index 5bbb100e669e..aab5cced4c70 100644 --- a/clang/test/OpenMP/teams_distribute_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_codegen.cpp @@ -33,7 +33,7 @@ int teams_argument_global(int n) { // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]], // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]], - // CK1: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) + // CK1: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) // CK1: call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i8** null, i8** null, i32 {{.+}}, i32 {{.+}}) // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]], diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp index b63e5aeddb7a..8fa73e76009b 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp @@ -32,7 +32,7 @@ int teams_argument_global(int n){ // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}}, // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]], // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]], - // CK1: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) + // CK1: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) // CK1: call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i8** null, i8** null, i32 {{.+}}, i32 {{.+}}) // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]], diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp index 3d479c4cd29d..9b3855c61759 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp @@ -33,7 +33,7 @@ int teams_argument_global(int n){ // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]], // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]], - // CK1: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) + // CK1: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) // CK1: call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i8** null // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]], diff --git a/clang/test/OpenMP/teams_distribute_simd_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_codegen.cpp index fd1214d22ce9..6e5d06b0c568 100644 --- a/clang/test/OpenMP/teams_distribute_simd_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_codegen.cpp @@ -35,7 +35,7 @@ int teams_argument_global(int n) { // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]], // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]], - // CK1: call void @__kmpc_push_target_tripcount(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) + // CK1: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @{{.+}}, i64 -1, i64 %{{.+}}) // CK1: call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i8** null, i8** null, i32 {{.+}}, i32 1) // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]], diff --git a/clang/test/PCH/cxx-explicit-specifier.cpp b/clang/test/PCH/cxx-explicit-specifier.cpp index ede0730f7c13..331c2e84c781 100644 --- a/clang/test/PCH/cxx-explicit-specifier.cpp +++ b/clang/test/PCH/cxx-explicit-specifier.cpp @@ -1,8 +1,10 @@ +// RUN: %clang_cc1 -std=c++2a -include %s %s -ast-print -verify | FileCheck %s +// // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t-cxx2a -// RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s +// RUN: %clang_cc1 -std=c++2a -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s // RUN: %clang_cc1 -std=c++2a -emit-pch -fpch-instantiate-templates %s -o %t-cxx2a -// RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s +// RUN: %clang_cc1 -std=c++2a -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s #ifndef USE_PCH namespace inheriting_constructor { @@ -125,3 +127,5 @@ A a1 = { 0 }; #endif } + +#define USE_PCH diff --git a/clang/test/Parser/cxx-concepts-requires-clause.cpp b/clang/test/Parser/cxx-concepts-requires-clause.cpp index 9cef4c64ee96..68f1af8b12cc 100644 --- a/clang/test/Parser/cxx-concepts-requires-clause.cpp +++ b/clang/test/Parser/cxx-concepts-requires-clause.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify +// RUN: %clang_cc1 -std=c++2b -x c++ %s -verify // Test parsing of the optional requires-clause in a template-declaration. @@ -153,5 +154,9 @@ auto lambda1 = [] (auto x) requires (sizeof(decltype(x)) == 1) { }; auto lambda2 = [] (auto x) constexpr -> int requires (sizeof(decltype(x)) == 1) { return 0; }; -auto lambda3 = [] requires (sizeof(char) == 1) { }; -// expected-error@-1{{lambda requires '()' before 'requires' clause}} \ No newline at end of file +auto lambda3 = [] requires(sizeof(char) == 1){}; + +auto lambda4 = [] requires(sizeof(char) == 1){}; // expected-error {{expected body of lambda expression}} +#if __cplusplus <= 202002L +// expected-warning@-2{{lambda without a parameter clause is a C++2b extension}} +#endif diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index 101e03845b8f..c9b27c1a7b89 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -179,6 +179,7 @@ struct [[]] N::S s; // expected-error {{an attribute list cannot appear here}} struct [[]] Template t; // expected-error {{an attribute list cannot appear here}} struct [[]] ::template Template u; // expected-error {{an attribute list cannot appear here}} template struct [[]] Template; // expected-error {{an attribute list cannot appear here}} +template struct __attribute__((pure)) Template; // We still allow GNU-style attributes here template <> struct [[]] Template; enum [[]] E1 {}; diff --git a/clang/test/Parser/cxx0x-lambda-expressions.cpp b/clang/test/Parser/cxx0x-lambda-expressions.cpp index 3148c73a4069..00a9b70ccd01 100644 --- a/clang/test/Parser/cxx0x-lambda-expressions.cpp +++ b/clang/test/Parser/cxx0x-lambda-expressions.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 -Wno-c99-designator %s // RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++2a -Wno-c99-designator %s +// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++2b -Wno-c99-designator %s enum E { e }; @@ -17,7 +18,7 @@ class C { [&this] {}; // expected-error {{'this' cannot be captured by reference}} [&,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}} [=,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}} - [] {}; + [] {}; [=] (int i) {}; [&] (int) mutable -> void {}; [foo,bar] () { return 3; }; @@ -27,8 +28,12 @@ class C { [] () -> class C { return C(); }; [] () -> enum E { return e; }; - [] -> int { return 0; }; // expected-error{{lambda requires '()' before return type}} - [] mutable -> int { return 0; }; // expected-error{{lambda requires '()' before 'mutable'}} + [] -> int { return 0; }; + [] mutable -> int { return 0; }; +#if __cplusplus <= 202002L + // expected-warning@-3 {{lambda without a parameter clause is a C++2b extension}} + // expected-warning@-3 {{is a C++2b extension}} +#endif [](int) -> {}; // PR13652 expected-error {{expected a type}} return 1; } @@ -101,7 +106,10 @@ class C { } void attributes() { - [] __attribute__((noreturn)) {}; // expected-error {{lambda requires '()' before attribute specifier}} + [] __attribute__((noreturn)){}; +#if __cplusplus <= 202002L + // expected-warning@-2 {{is a C++2b extension}} +#endif []() [[]] mutable {}; // expected-error {{expected body of lambda expression}} @@ -118,11 +126,29 @@ class C { // Testing support for P2173 on adding attributes to the declaration // rather than the type. - [] [[]] () {}; // expected-warning {{an attribute specifier sequence in this position is a C++2b extension}} + [][[]](){}; +#if __cplusplus <= 202002L + // expected-warning@-2 {{an attribute specifier sequence in this position is a C++2b extension}} +#endif #if __cplusplus > 201703L - [] [[]] () {}; // expected-warning {{an attribute specifier sequence in this position is a C++2b extension}} + [][[]](){}; +#if __cplusplus <= 202002L + // expected-warning@-2 {{an attribute specifier sequence in this position is a C++2b extension}} +#endif +#endif + [][[]]{}; +#if __cplusplus <= 202002L + // expected-warning@-2 {{an attribute specifier sequence in this position is a C++2b extension}} +#endif + } + + void missing_parens() { + [] mutable {}; + [] noexcept {}; +#if __cplusplus <= 202002L + // expected-warning@-3 {{is a C++2b extension}} + // expected-warning@-3 {{is a C++2b extension}} #endif - [] [[]] {}; // expected-warning {{an attribute specifier sequence in this position is a C++2b extension}} } }; diff --git a/clang/test/Parser/cxx1z-constexpr-lambdas.cpp b/clang/test/Parser/cxx1z-constexpr-lambdas.cpp index 4cf3d1221167..0c2f81d318a1 100644 --- a/clang/test/Parser/cxx1z-constexpr-lambdas.cpp +++ b/clang/test/Parser/cxx1z-constexpr-lambdas.cpp @@ -1,12 +1,19 @@ -// RUN: %clang_cc1 -std=c++17 %s -verify -// RUN: %clang_cc1 -std=c++14 %s -verify -// RUN: %clang_cc1 -std=c++11 %s -verify +// RUN: %clang_cc1 -std=c++2b %s -verify +// RUN: %clang_cc1 -std=c++20 %s -verify +// RUN: %clang_cc1 -std=c++17 %s -verify +// RUN: %clang_cc1 -std=c++14 %s -verify +// RUN: %clang_cc1 -std=c++11 %s -verify - -auto XL0 = [] constexpr { }; //expected-error{{requires '()'}} expected-error{{expected body}} -auto XL1 = [] () mutable - mutable //expected-error{{cannot appear multiple times}} - mutable { }; //expected-error{{cannot appear multiple times}} +auto XL0 = [] constexpr { return true; }; +#if __cplusplus <= 201402L +// expected-warning@-2 {{is a C++17 extension}} +#endif +#if __cplusplus <= 202002L +// expected-warning@-5 {{lambda without a parameter clause is a C++2b extension}} +#endif +auto XL1 = []() mutable // + mutable // expected-error{{cannot appear multiple times}} + mutable {}; // expected-error{{cannot appear multiple times}} #if __cplusplus > 201402L auto XL2 = [] () constexpr mutable constexpr { }; //expected-error{{cannot appear multiple times}} diff --git a/clang/test/Parser/cxx2a-init-statement.cpp b/clang/test/Parser/cxx2a-init-statement.cpp index 3b1862f1d3c5..727ee63d1b92 100644 --- a/clang/test/Parser/cxx2a-init-statement.cpp +++ b/clang/test/Parser/cxx2a-init-statement.cpp @@ -31,4 +31,12 @@ void f() { for (int n = 0; static int m = 0; ++n) {} // expected-error {{type name does not allow storage class}} for (int n = 0; static int m : arr1) {} // expected-error {{loop variable 'm' may not be declared 'static'}} + + // The init-statement and range are not break / continue scopes. (But the body is.) + for (int n = ({ break; 0; }); int m : arr1) {} // expected-error {{not in loop}} + for (int n = ({ continue; 0; }); int m : arr1) {} // expected-error {{not in loop}} + for (int arr[3]; int n : *({ break; &arr; })) {} // expected-error {{not in loop}} + for (int arr[3]; int n : *({ continue; &arr; })) {} // expected-error {{not in loop}} + for (int n = 0; int m : arr1) { break; } + for (int n = 0; int m : arr1) { continue; } } diff --git a/clang/test/Parser/cxx2a-template-lambdas.cpp b/clang/test/Parser/cxx2a-template-lambdas.cpp index 034a3b157d80..f85280f7ece5 100644 --- a/clang/test/Parser/cxx2a-template-lambdas.cpp +++ b/clang/test/Parser/cxx2a-template-lambdas.cpp @@ -1,3 +1,4 @@ +// RUN: %clang_cc1 -std=c++2b %s -verify // RUN: %clang_cc1 -std=c++2a %s -verify auto L0 = []<> { }; //expected-error {{cannot be empty}} @@ -6,3 +7,28 @@ auto L1 = [] { }; auto L2 = [](T1 arg1, T2 arg2) -> T1 { }; auto L3 = [](auto arg) { T t; }; auto L4 = []() { }; + +// http://llvm.org/PR49736 +auto L5 = [](){}; +auto L6 = []{}; +auto L7 = []() noexcept {}; +auto L8 = [] noexcept {}; +#if __cplusplus <= 202002L +// expected-warning@-2 {{lambda without a parameter clause is a C++2b extension}} +#endif +auto L9 = [] requires true {}; +auto L10 = [] requires true(){}; +auto L11 = [] requires true() noexcept {}; +auto L12 = [] requires true noexcept {}; +#if __cplusplus <= 202002L +// expected-warning@-2 {{is a C++2b extension}} +#endif +auto L13 = []() noexcept requires true {}; +auto L14 = [] requires true() noexcept requires true {}; + +auto XL0 = [] noexcept requires true {}; // expected-error {{expected body of lambda expression}} +auto XL1 = [] requires true noexcept requires true {}; // expected-error {{expected body}} +#if __cplusplus <= 202002L +// expected-warning@-3 {{is a C++2b extension}} +// expected-warning@-3 {{is a C++2b extension}} +#endif diff --git a/clang/test/Parser/cxx2b-lambdas.cpp b/clang/test/Parser/cxx2b-lambdas.cpp new file mode 100644 index 000000000000..57e81eed7b9e --- /dev/null +++ b/clang/test/Parser/cxx2b-lambdas.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++2b %s -verify + +auto LL0 = [] {}; +auto LL1 = []() {}; +auto LL2 = []() mutable {}; +auto LL3 = []() constexpr {}; + +auto L0 = [] constexpr {}; +auto L1 = [] mutable {}; +auto L2 = [] noexcept {}; +auto L3 = [] constexpr mutable {}; +auto L4 = [] mutable constexpr {}; +auto L5 = [] constexpr mutable noexcept {}; +auto L6 = [s = 1] mutable {}; +auto L7 = [s = 1] constexpr mutable noexcept {}; +auto L8 = [] -> bool { return true; }; +auto L9 = [] { return true; }; +auto L10 = [] noexcept { return true; }; +auto L11 = [] -> bool { return true; }; +auto L12 = [] consteval {}; +auto L13 = []() requires true {}; +auto L14 = [] requires true() requires true {}; +auto L15 = [] requires true noexcept {}; +auto L16 = [] [[maybe_unused]]{}; + +auto XL0 = [] mutable constexpr mutable {}; // expected-error{{cannot appear multiple times}} +auto XL1 = [] constexpr mutable constexpr {}; // expected-error{{cannot appear multiple times}} +auto XL2 = []) constexpr mutable constexpr {}; // expected-error{{expected body of lambda expression}} +auto XL3 = []( constexpr mutable constexpr {}; // expected-error{{invalid storage class specifier}} \ + // expected-error{{function parameter cannot be constexpr}} \ + // expected-error{{C++ requires}} \ + // expected-error{{expected ')'}} \ + // expected-note{{to match this '('}} \ + // expected-error{{expected body}} \ + // expected-warning{{duplicate 'constexpr'}} + +// http://llvm.org/PR49736 +auto XL4 = [] requires true {}; // expected-error{{expected body}} +auto XL5 = [] requires true requires true {}; // expected-error{{expected body}} +auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}} diff --git a/clang/test/Parser/opencl-atomics-cl20.cl b/clang/test/Parser/opencl-atomics-cl20.cl index 844902e847f7..2f5f913d2873 100644 --- a/clang/test/Parser/opencl-atomics-cl20.cl +++ b/clang/test/Parser/opencl-atomics-cl20.cl @@ -42,21 +42,21 @@ void atomic_types_test() { // expected-error@-16 {{use of undeclared identifier 'atomic_size_t'}} // expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}} #elif !EXT -// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics support}} +// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics support}} +// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics support}} +// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics support}} +// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics support}} +// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics support}} #if __LP64__ -// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} +// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} +// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} +// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} #endif #endif diff --git a/clang/test/Parser/static_assert.c b/clang/test/Parser/static_assert.c index eaae2adbe380..452c404a79ce 100644 --- a/clang/test/Parser/static_assert.c +++ b/clang/test/Parser/static_assert.c @@ -7,7 +7,7 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++17 -pedantic -verify=cxx17-pedantic -x c++ %s // RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify=cxx98 -x c++ %s // RUN: %clang_cc1 -fsyntax-only -std=c++98 -pedantic -verify=cxx98-pedantic -x c++ %s -// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-c++11-c++14-compat -verify=cxx17-compat -x c++ %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wpre-c++17-compat -verify=cxx17-compat -x c++ %s // cxx17-no-diagnostics diff --git a/clang/test/Parser/stmt-attributes.c b/clang/test/Parser/stmt-attributes.c index d142ce1b5b95..86adc56f40ca 100644 --- a/clang/test/Parser/stmt-attributes.c +++ b/clang/test/Parser/stmt-attributes.c @@ -40,7 +40,7 @@ void foo(int i) { __attribute__((unused)) switch (i) { // expected-error {{'unused' attribute cannot be applied to a statement}} __attribute__((uuid)) case 0: // expected-warning {{unknown attribute 'uuid' ignored}} - __attribute__((visibility)) default: // expected-error {{'visibility' attribute cannot be applied to a statement}} + __attribute__((visibility(""))) default: // expected-error {{'visibility' attribute cannot be applied to a statement}} __attribute__((carries_dependency)) break; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}} } diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 3c7b56d75553..537c6b90d18b 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -441,6 +441,12 @@ // CHECK-BTI-OFF-NOT: __ARM_FEATURE_BTI_DEFAULT // CHECK-BTI: #define __ARM_FEATURE_BTI_DEFAULT 1 +// ================== Check Armv8.5-A random number generation extension. +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.5-a+rng -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-RNG %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.5-a -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-NO-RNG %s +// CHECK-RNG: __ARM_FEATURE_RNG 1 +// CHECK-NO-RNG-NOT: __ARM_FEATURE_RNG 1 + // ================== Check BFloat16 Extensions. // RUN: %clang -target aarch64-arm-none-eabi -march=armv8.6-a+bf16 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-BFLOAT %s // CHECK-BFLOAT: __ARM_BF16_FORMAT_ALTERNATIVE 1 diff --git a/clang/test/Preprocessor/init-ppc64.c b/clang/test/Preprocessor/init-ppc64.c index 163e86b919bc..6aed0e7daa96 100644 --- a/clang/test/Preprocessor/init-ppc64.c +++ b/clang/test/Preprocessor/init-ppc64.c @@ -566,7 +566,8 @@ // PPCPWR8-NOT:#define _ARCH_PWR6X 1 // PPCPWR8:#define _ARCH_PWR7 1 // PPCPWR8:#define _ARCH_PWR8 1 -// PPCPWR8-NOT:#define __ROP_PROTECTION__ 1 +// PPCPWR8-NOT:#define __ROP_PROTECT__ 1 +// PPCPWR8-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER8 %s // @@ -584,7 +585,8 @@ // PPCPOWER8-NOT:#define _ARCH_PWR6X 1 // PPCPOWER8:#define _ARCH_PWR7 1 // PPCPOWER8:#define _ARCH_PWR8 1 -// PPCPOWER8-NOT:#define __ROP_PROTECTION__ 1 +// PPCPOWER8-NOT:#define __ROP_PROTECT__ 1 +// PPCPOWER8-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr9 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPWR9 %s // @@ -599,7 +601,8 @@ // PPCPWR9-NOT:#define _ARCH_PWR6X 1 // PPCPWR9:#define _ARCH_PWR7 1 // PPCPWR9:#define _ARCH_PWR9 1 -// PPCPWR9-NOT:#define __ROP_PROTECTION__ 1 +// PPCPWR9-NOT:#define __ROP_PROTECT__ 1 +// PPCPWR9-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER9 %s // @@ -614,7 +617,8 @@ // PPCPOWER9-NOT:#define _ARCH_PWR6X 1 // PPCPOWER9:#define _ARCH_PWR7 1 // PPCPOWER9:#define _ARCH_PWR9 1 -// PPCPOWER9-NOT:#define __ROP_PROTECTION__ 1 +// PPCPOWER9-NOT:#define __ROP_PROTECT__ 1 +// PPCPOWER9-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr10 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER10 %s // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER10 %s @@ -633,7 +637,9 @@ // PPCPOWER10:#define _ARCH_PWR8 1 // PPCPOWER10:#define _ARCH_PWR9 1 // PPCPOWER10:#define __MMA__ 1 -// PPCPOWER10-NOT:#define __ROP_PROTECTION__ 1 +// PPCPOWER10:#define __PCREL__ 1 +// PPCPOWER10-NOT:#define __ROP_PROTECT__ 1 +// PPCPOWER10-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu future -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCFUTURE %s // @@ -652,15 +658,22 @@ // PPCFUTURE:#define _ARCH_PWR9 1 // PPCFUTURE:#define _ARCH_PWR_FUTURE 1 // PPCFUTURE:#define __MMA__ 1 -// PPCFUTURE-NOT:#define __ROP_PROTECTION__ 1 +// PPCFUTURE:#define __PCREL__ 1 +// PPCFUTURE-NOT:#define __ROP_PROTECT__ 1 +// PPCFUTURE-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +mma -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-MMA %s // PPC-MMA:#define __MMA__ 1 // -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protection -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protection -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protection -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s -// PPC-ROP:#define __ROP_PROTECTION__ 1 +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protect -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protect -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protect -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s +// PPC-ROP:#define __ROP_PROTECT__ 1 +// +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +privileged -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-PRIV %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +privileged -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-PRIV %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +privileged -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-PRIV %s +// PPC-PRIV:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s // PPC-FLOAT128:#define __FLOAT128__ 1 diff --git a/clang/test/Preprocessor/iwithprefix.c b/clang/test/Preprocessor/iwithprefix.c index a65a8043aa71..70d2abcd374c 100644 --- a/clang/test/Preprocessor/iwithprefix.c +++ b/clang/test/Preprocessor/iwithprefix.c @@ -9,8 +9,6 @@ // CHECK: #include <...> search starts here: // CHECK: {{.*}}.tmps/first -// CHECK: {{/|\\}}lib{{(32|64)?}}{{/|\\}}clang{{/|\\}}{{[.0-9]+}}{{/|\\}}include +// CHECK: {{/|\\}}clang{{/|\\}}{{[.0-9]+}}{{/|\\}}include // CHECK: {{.*}}.tmps/second // CHECK-NOT: {{.*}}.tmps - - diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 88826bbd60b8..da9b15b88a4c 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -4,14 +4,20 @@ // RUN: -o - | FileCheck %s // CHECK-NOT: __riscv_div +// CHECK-NOT: __riscv_m // CHECK-NOT: __riscv_mul // CHECK-NOT: __riscv_muldiv -// CHECK-NOT: __riscv_compressed -// CHECK-NOT: __riscv_bitmanip +// CHECK-NOT: __riscv_a 2000000 +// CHECK-NOT: __riscv_atomic +// CHECK-NOT: __riscv_f 2000000 +// CHECK-NOT: __riscv_d // CHECK-NOT: __riscv_flen // CHECK-NOT: __riscv_fdiv // CHECK-NOT: __riscv_fsqrt -// CHECK-NOT: __riscv_atomic +// CHECK-NOT: __riscv_c 2000000 +// CHECK-NOT: __riscv_compressed +// CHECK-NOT: __riscv_b +// CHECK-NOT: __riscv_bitmanip // CHECK-NOT: __riscv_zba // CHECK-NOT: __riscv_zbb // CHECK-NOT: __riscv_zbc @@ -24,6 +30,8 @@ // CHECK-NOT: __riscv_zbs // CHECK-NOT: __riscv_zbt // CHECK-NOT: __riscv_zfh +// CHECK-NOT: __riscv_v +// CHECK-NOT: __riscv_vector // CHECK-NOT: __riscv_zvamo // CHECK-NOT: __riscv_zvlsseg @@ -61,30 +69,6 @@ // CHECK-D-EXT: __riscv_flen 64 // CHECK-D-EXT: __riscv_fsqrt 1 -// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ic -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ic -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s -// CHECK-C-EXT: __riscv_c 2000000 -// CHECK-C-EXT: __riscv_compressed 1 - -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32ib0p93 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-B-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64ib0p93 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-B-EXT %s -// CHECK-B-EXT: __riscv_b 93000 -// CHECK-B-EXT: __riscv_bitmanip 1 -// CHECK-B-EXT: __riscv_zba 93000 -// CHECK-B-EXT: __riscv_zbb 93000 -// CHECK-B-EXT: __riscv_zbc 93000 -// CHECK-B-EXT: __riscv_zbe 93000 -// CHECK-B-EXT: __riscv_zbf 93000 -// CHECK-B-EXT: __riscv_zbm 93000 -// CHECK-B-EXT: __riscv_zbp 93000 -// CHECK-B-EXT: __riscv_zbr 93000 -// CHECK-B-EXT: __riscv_zbs 93000 -// CHECK-B-EXT: __riscv_zbt 93000 - // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ifd -mabi=ilp32 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-SOFT %s // RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ifd -mabi=lp64 -x c -E -dM %s \ @@ -109,104 +93,158 @@ // CHECK-DOUBLE-NOT: __riscv_float_abi_soft // CHECK-DOUBLE-NOT: __riscv_float_abi_single +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ic -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ic -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s +// CHECK-C-EXT: __riscv_c 2000000 +// CHECK-C-EXT: __riscv_compressed 1 + // RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ -// RUN: -march=rv32iv0p10 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s +// RUN: -march=rv32ib0p93 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-B-EXT %s // RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ -// RUN: -march=rv64iv0p10 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izvamo0p10 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv32izvamo0p10 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izvlsseg0p10 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv32izvlsseg0p10 -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s -// CHECK-V-EXT: __riscv_v 10000 -// CHECK-V-EXT: __riscv_vector 1 -// CHECK-V-EXT: __riscv_zvamo 10000 -// CHECK-V-EXT: __riscv_zvlsseg 10000 +// RUN: -march=rv64ib0p93 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-B-EXT %s +// CHECK-B-EXT: __riscv_b 93000 +// CHECK-B-EXT: __riscv_bitmanip 1 +// CHECK-B-EXT: __riscv_zba 93000 +// CHECK-B-EXT: __riscv_zbb 93000 +// CHECK-B-EXT: __riscv_zbc 93000 +// CHECK-B-EXT: __riscv_zbe 93000 +// CHECK-B-EXT: __riscv_zbf 93000 +// CHECK-B-EXT: __riscv_zbm 93000 +// CHECK-B-EXT: __riscv_zbp 93000 +// CHECK-B-EXT: __riscv_zbr 93000 +// CHECK-B-EXT: __riscv_zbs 93000 +// CHECK-B-EXT: __riscv_zbt 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izba0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izba0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBA-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izba0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izba0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBA-EXT %s // CHECK-ZBA-NOT: __riscv_b // CHECK-ZBA-EXT: __riscv_zba 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbb0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbb0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBB-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbb0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbb0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBB-EXT %s // CHECK-ZBB-NOT: __riscv_b // CHECK-ZBB-EXT: __riscv_zbb 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbc0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbc0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBC-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbc0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbc0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBC-EXT %s // CHECK-ZBC-NOT: __riscv_b // CHECK-ZBC-EXT: __riscv_zbc 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbe0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbe0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBE-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbe0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbe0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBE-EXT %s // CHECK-ZBE-NOT: __riscv_b // CHECK-ZBE-EXT: __riscv_zbe 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbf0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbf0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBF-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbf0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbf0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBF-EXT %s // CHECK-ZBF-NOT: __riscv_b // CHECK-ZBF-EXT: __riscv_zbf 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbm0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbm0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBM-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbm0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbm0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBM-EXT %s // CHECK-ZBM-NOT: __riscv_b // CHECK-ZBM-EXT: __riscv_zbm 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbp0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbp0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBP-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbp0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbp0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBP-EXT %s // CHECK-ZBP-NOT: __riscv_b // CHECK-ZBP-EXT: __riscv_zbp 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbproposedc0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbproposedc0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBPROPOSEDC-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbproposedc0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbproposedc0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBPROPOSEDC-EXT %s // CHECK-ZBPROPOSEDC-NOT: __riscv_b // CHECK-ZBPROPOSEDC-EXT: __riscv_zbproposedc 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbr0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbr0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBR-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbr0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbr0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBR-EXT %s // CHECK-ZBR-NOT: __riscv_b // CHECK-ZBR-EXT: __riscv_zbr 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbs0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbs0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBS-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbs0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbs0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBS-EXT %s // CHECK-ZBS-NOT: __riscv_b // CHECK-ZBS-EXT: __riscv_zbs 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izbt0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izbt0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBT-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izbt0p93 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izbt0p93 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZBT-EXT %s // CHECK-ZBT-NOT: __riscv_b // CHECK-ZBT-EXT: __riscv_zbt 93000 -// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions -march=rv32izfh0p1 -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32iv0p10 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64iv0p10 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izvamo0p10 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izvamo0p10 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izvlsseg0p10 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izvlsseg0p10 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V-EXT %s +// CHECK-V-EXT: __riscv_v 10000 +// CHECK-V-EXT: __riscv_vector 1 +// CHECK-V-EXT: __riscv_zvamo 10000 +// CHECK-V-EXT: __riscv_zvlsseg 10000 + +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32izfh0p1 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZFH-EXT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions -march=rv64izfh0p1 -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64izfh0p1 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZFH-EXT %s // CHECK-ZFH-EXT: __riscv_zfh 1000 diff --git a/clang/test/Preprocessor/sycl-macro.cpp b/clang/test/Preprocessor/sycl-macro.cpp index 408dc200ad88..d1d830210529 100644 --- a/clang/test/Preprocessor/sycl-macro.cpp +++ b/clang/test/Preprocessor/sycl-macro.cpp @@ -1,7 +1,8 @@ // RUN: %clang_cc1 %s -E -dM | FileCheck %s -// RUN: %clang_cc1 %s -fsycl -sycl-std=2017 -E -dM | FileCheck --check-prefix=CHECK-SYCL-STD %s -// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -sycl-std=1.2.1 -E -dM | FileCheck --check-prefix=CHECK-SYCL-STD %s -// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -E -dM | FileCheck --check-prefixes=CHECK-SYCL %s +// RUN: %clang_cc1 %s -fsycl-is-device -sycl-std=2017 -E -dM | FileCheck --check-prefix=CHECK-SYCL-STD %s +// RUN: %clang_cc1 %s -fsycl-is-host -sycl-std=2017 -E -dM | FileCheck --check-prefix=CHECK-SYCL-STD %s +// RUN: %clang_cc1 %s -fsycl-is-device -sycl-std=1.2.1 -E -dM | FileCheck --check-prefix=CHECK-SYCL-STD %s +// RUN: %clang_cc1 %s -fsycl-is-device -E -dM | FileCheck --check-prefixes=CHECK-SYCL %s // CHECK-NOT:#define __SYCL_DEVICE_ONLY__ 1 // CHECK-NOT:#define CL_SYCL_LANGUAGE_VERSION 121 diff --git a/clang/test/Preprocessor/unwind-tables.c b/clang/test/Preprocessor/unwind-tables.c new file mode 100644 index 000000000000..4eab8e516cda --- /dev/null +++ b/clang/test/Preprocessor/unwind-tables.c @@ -0,0 +1,10 @@ +// RUN: %clang %s -dM -E -target x86_64-windows | FileCheck %s --check-prefix=NO +// RUN: %clang %s -dM -E -target x86_64 -fno-asynchronous-unwind-tables | FileCheck %s --check-prefix=NO + +// RUN: %clang %s -dM -E -target x86_64 | FileCheck %s +// RUN: %clang %s -dM -E -target aarch64-apple-darwin | FileCheck %s +// RUN: %clang %s -dM -E -target x86_64 -fno-asynchronous-unwind-tables -g | FileCheck %s +// RUN: %clang %s -dM -E -target x86_64 -fno-asynchronous-unwind-tables -fexceptions | FileCheck %s + +// NO-NOT: #define __GCC_HAVE_DWARF2_CFI_ASM +// CHECK: #define __GCC_HAVE_DWARF2_CFI_ASM 1 diff --git a/clang/test/Preprocessor/wasm-target-features.c b/clang/test/Preprocessor/wasm-target-features.c index 05b4bb49d73b..29cc3071a235 100644 --- a/clang/test/Preprocessor/wasm-target-features.c +++ b/clang/test/Preprocessor/wasm-target-features.c @@ -7,15 +7,6 @@ // // SIMD128:#define __wasm_simd128__ 1{{$}} -// RUN: %clang -E -dM %s -o - 2>&1 \ -// RUN: -target wasm32-unknown-unknown -munimplemented-simd128 \ -// RUN: | FileCheck %s -check-prefix=SIMD128-UNIMPLEMENTED -// RUN: %clang -E -dM %s -o - 2>&1 \ -// RUN: -target wasm64-unknown-unknown -munimplemented-simd128 \ -// RUN: | FileCheck %s -check-prefix=SIMD128-UNIMPLEMENTED -// -// SIMD128-UNIMPLEMENTED:#define __wasm_unimplemented_simd128__ 1{{$}} - // RUN: %clang -E -dM %s -o - 2>&1 \ // RUN: -target wasm32-unknown-unknown -mnontrapping-fptoint \ // RUN: | FileCheck %s -check-prefix=NONTRAPPING-FPTOINT @@ -114,7 +105,6 @@ // RUN: | FileCheck %s -check-prefix=MVP // // MVP-NOT:#define __wasm_simd128__ -// MVP-NOT:#define __wasm_unimplemented_simd128__ // MVP-NOT:#define __wasm_nontrapping_fptoint__ // MVP-NOT:#define __wasm_sign_ext__ // MVP-NOT:#define __wasm_exception_handling__ diff --git a/clang/test/Sema/128bitfloat.cpp b/clang/test/Sema/128bitfloat.cpp index 4a826b479d01..6a9ae743c6f0 100644 --- a/clang/test/Sema/128bitfloat.cpp +++ b/clang/test/Sema/128bitfloat.cpp @@ -6,6 +6,13 @@ // RUN: %clang_cc1 -triple x86_64-windows-msvc -verify -std=c++11 %s #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) + +#if defined(__ppc__) +template struct __is_float128 { static constexpr bool value = false; }; +template <> struct __is_float128<__float128> { static constexpr bool value = true; }; +static_assert(__is_float128<__ieee128>::value, "__ieee128 aliases to __float128"); +#endif + __float128 f; template struct __is_floating_point_helper {}; template<> struct __is_floating_point_helper<__float128> {}; diff --git a/clang/test/Sema/attr-standalonedebug.cpp b/clang/test/Sema/attr-standalonedebug.cpp new file mode 100644 index 000000000000..540dd5f79af5 --- /dev/null +++ b/clang/test/Sema/attr-standalonedebug.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -x c + +#ifdef __cplusplus +int a __attribute__((standalone_debug)); // expected-warning {{'standalone_debug' attribute only applies to classes}} + +void __attribute__((standalone_debug)) b(); // expected-warning {{'standalone_debug' attribute only applies to classes}} + +struct __attribute__((standalone_debug(1))) c {}; // expected-error {{'standalone_debug' attribute takes no arguments}} + +#else +// Check that attribute only works in C++. +struct __attribute__((standalone_debug)) a {}; // expected-warning {{'standalone_debug' attribute ignored}} +#endif diff --git a/clang/test/Sema/c2x-fallthrough.c b/clang/test/Sema/c2x-fallthrough.c index 2fd69c4da0f2..e5508e0a10f1 100644 --- a/clang/test/Sema/c2x-fallthrough.c +++ b/clang/test/Sema/c2x-fallthrough.c @@ -57,7 +57,7 @@ struct [[fallthrough]] S { // expected-error {{'fallthrough' attribute cannot be [[fallthrough]] // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} void g(void) { [[fallthrough]] int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} - [[fallthrough]] ++n; // expected-error-re {{{{^}}fallthrough attribute is only allowed on empty statements}} + [[fallthrough]] ++n; // expected-error {{'fallthrough' attribute only applies to empty statements}} switch (n) { // FIXME: This should be an error. diff --git a/clang/test/Sema/integer-overflow.c b/clang/test/Sema/integer-overflow.c index 39395d9bc1fd..79e9294067de 100644 --- a/clang/test/Sema/integer-overflow.c +++ b/clang/test/Sema/integer-overflow.c @@ -203,3 +203,12 @@ struct s2 { } } }; + +void PR49619() { + int n; + n = ({ + while (1) + ; + 0; + }); +} diff --git a/clang/test/Sema/matrix-type-operators.c b/clang/test/Sema/matrix-type-operators.c index fc857854af35..c1345274f065 100644 --- a/clang/test/Sema/matrix-type-operators.c +++ b/clang/test/Sema/matrix-type-operators.c @@ -94,6 +94,40 @@ void mat_scalar_multiply(sx10x10_t a, sx5x10_t b, float sf, char *p) { // expected-error@-1 {{assigning to 'float' from incompatible type 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))')}} } +void mat_scalar_divide(sx10x10_t a, sx5x10_t b, float sf, char *p) { + // Shape of multiplication result does not match the type of b. + b = a / sf; + // expected-error@-1 {{assigning to 'sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))') from incompatible type 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))')}} + b = sf / a; + // expected-error@-1 {{invalid operands to binary expression ('float' and 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))'))}} + + a = a / p; + // expected-error@-1 {{invalid operands to binary expression ('sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))') and 'char *')}} + a = p / a; + // expected-error@-1 {{invalid operands to binary expression ('char *' and 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))'))}} + + sf = a / sf; + // expected-error@-1 {{assigning to 'float' from incompatible type 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))')}} +} + +void matrix_matrix_divide(sx10x10_t a, sx5x10_t b, ix10x5_t c, ix10x10_t d, float sf, char *p) { + // Matrix by matrix division is not supported. + a = a / a; + // expected-error@-1 {{invalid operands to binary expression ('sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))') and 'sx10x10_t')}} + + b = a / a; + // expected-error@-1 {{invalid operands to binary expression ('sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))') and 'sx10x10_t')}} + + // Check element type mismatches. + a = b / c; + // expected-error@-1 {{invalid operands to binary expression ('sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))') and 'ix10x5_t' (aka 'int __attribute__((matrix_type(10, 5)))'))}} + d = a / a; + // expected-error@-1 {{invalid operands to binary expression ('sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))') and 'sx10x10_t')}} + + p = a / a; + // expected-error@-1 {{invalid operands to binary expression ('sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))') and 'sx10x10_t')}} +} + sx5x10_t get_matrix(); void insert(sx5x10_t a, float f) { diff --git a/clang/test/Sema/patchable-function-entry-attr.cpp b/clang/test/Sema/patchable-function-entry-attr.cpp index 63de5a2abf70..3dd050498730 100644 --- a/clang/test/Sema/patchable-function-entry-attr.cpp +++ b/clang/test/Sema/patchable-function-entry-attr.cpp @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -triple aarch64_be -fsyntax-only -verify=silence %s // RUN: %clang_cc1 -triple i386 -fsyntax-only -verify=silence %s // RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify=silence %s +// RUN: %clang_cc1 -triple riscv32 -fsyntax-only -verify=silence %s +// RUN: %clang_cc1 -triple riscv64 -fsyntax-only -verify=silence %s // RUN: %clang_cc1 -triple ppc64le -fsyntax-only -verify %s // silence-no-diagnostics diff --git a/clang/test/Sema/pre-c2x-compat.c b/clang/test/Sema/pre-c2x-compat.c new file mode 100644 index 000000000000..cf40efb62cfa --- /dev/null +++ b/clang/test/Sema/pre-c2x-compat.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -std=c2x -Wpre-c2x-compat -pedantic -fsyntax-only -verify + +int digit_seps = 123'456; // expected-warning {{digit separators are incompatible with C standards before C2x}} diff --git a/clang/test/Sema/warn-cast-function-type.c b/clang/test/Sema/warn-cast-function-type.c new file mode 100644 index 000000000000..5d823df27ee5 --- /dev/null +++ b/clang/test/Sema/warn-cast-function-type.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -x c %s -fsyntax-only -Wcast-function-type -triple x86_64-- -verify + +int x(long); + +typedef int (f1)(long); +typedef int (f2)(void*); +typedef int (f3)(); +typedef void (f4)(); +typedef void (f5)(void); +typedef int (f6)(long, int); +typedef int (f7)(long,...); + +f1 *a; +f2 *b; +f3 *c; +f4 *d; +f5 *e; +f6 *f; +f7 *g; + +void foo(void) { + a = (f1 *)x; + b = (f2 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f2 *' (aka 'int (*)(void *)') converts to incompatible function type}} */ + c = (f3 *)x; + d = (f4 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f4 *' (aka 'void (*)()') converts to incompatible function type}} */ + e = (f5 *)x; + f = (f6 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f6 *' (aka 'int (*)(long, int)') converts to incompatible function type}} */ + g = (f7 *)x; +} diff --git a/clang/test/SemaCUDA/builtin-mangled-name.cu b/clang/test/SemaCUDA/builtin-mangled-name.cu new file mode 100644 index 000000000000..6ca85083d717 --- /dev/null +++ b/clang/test/SemaCUDA/builtin-mangled-name.cu @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-gnu-linux -aux-triple amdgcn-amd-amdhsa \ +// RUN: -verify -fsyntax-only -x hip %s + +#include "Inputs/cuda.h" + +__global__ void kern1(); +int y; + +void fun1() { + int x; + const char *p; + p = __builtin_get_device_side_mangled_name(); + // expected-error@-1 {{invalid argument: symbol must be a device-side function or global variable}} + p = __builtin_get_device_side_mangled_name(kern1, kern1); + // expected-error@-1 {{invalid argument: symbol must be a device-side function or global variable}} + p = __builtin_get_device_side_mangled_name(1); + // expected-error@-1 {{invalid argument: symbol must be a device-side function or global variable}} + p = __builtin_get_device_side_mangled_name(x); + // expected-error@-1 {{invalid argument: symbol must be a device-side function or global variable}} + p = __builtin_get_device_side_mangled_name(fun1); + // expected-error@-1 {{invalid argument: symbol must be a device-side function or global variable}} + p = __builtin_get_device_side_mangled_name(y); + // expected-error@-1 {{invalid argument: symbol must be a device-side function or global variable}} +} diff --git a/clang/test/SemaCXX/PR49534.cpp b/clang/test/SemaCXX/PR49534.cpp new file mode 100644 index 000000000000..8a17402689e6 --- /dev/null +++ b/clang/test/SemaCXX/PR49534.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify + +static union { // expected-warning {{declaration does not declare anything}} + virtual int a(); // expected-error {{unions cannot have virtual functions}} \ + // expected-error {{functions cannot be declared in an anonymous union}} +}; diff --git a/clang/test/SemaCXX/constructor-initializer.cpp b/clang/test/SemaCXX/constructor-initializer.cpp index df8991416712..874682944bb8 100644 --- a/clang/test/SemaCXX/constructor-initializer.cpp +++ b/clang/test/SemaCXX/constructor-initializer.cpp @@ -91,13 +91,14 @@ struct Derived : Base, Base1, virtual V { struct Current : Derived { int Derived; - Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \ - // expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}} - ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}} - Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}} - Derived::V(), - ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} - INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \ + Current() : Derived(1), ::Derived(), // expected-warning {{initializer order does not match the declaration order}} \ + // expected-note {{field 'Derived' will be initialized after base '::Derived'}} \ + // expected-note {{base class '::Derived' will be initialized after base 'Derived::V'}} + ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}} + Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}} + Derived::V(), + ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} + INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \ // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} }; diff --git a/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp index 7a7b92b7d04f..94fee530aea6 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp @@ -133,3 +133,10 @@ namespace array_addressof { namespace PR24816 { struct { int i; } ne = {{0, 1}}; // expected-error{{excess elements in scalar initializer}} } + +namespace no_crash { +class Foo; // expected-note {{forward declaration}} +void test(int size) { + Foo array[size] = {0}; // expected-error {{variable has incomplete type}} +} +} diff --git a/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp b/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp index 2f00ad2d237b..28af62368a89 100644 --- a/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp +++ b/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %s -// RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks -emit-llvm-only %s +// RUN: %clang_cc1 -std=c++2a -verify -verify=expected-cxx2a -fsyntax-only -fblocks -emit-llvm-only %s // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only -triple i386-windows-pc %s -// RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks -emit-llvm-only -triple i386-windows-pc %s +// RUN: %clang_cc1 -std=c++2a -verify -verify=expected-cxx2a -fsyntax-only -fblocks -emit-llvm-only -triple i386-windows-pc %s // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING @@ -77,13 +77,14 @@ void doit() { { int a; //expected-note{{declared here}} auto B = []() { return ^{ return a; }; }; //expected-error{{cannot be implicitly capture}}\ - //expected-note{{begins here}} + //expected-note{{begins here}}\ + //expected-note 2 {{capture 'a' by}}\ + //expected-note 2 {{default capture by}} //[](){ return ({int b = 5; return 'c'; 'x';}); }; //auto X = ^{ return a; }; //auto Y = []() -> auto { return 3; return 'c'; }; - } } } @@ -102,7 +103,7 @@ void doit() { } { // should not capture 'x' - even though certain instantiations require - auto L = [](auto a) { //expected-note{{begins here}} + auto L = [](auto a) { //expected-note{{begins here}} expected-note 2 {{capture 'x' by}} expected-note 2 {{default capture by}} DEFINE_SELECTOR(a); F_CALL(x, a); //expected-error{{'x' cannot be implicitly captured}} }; @@ -137,7 +138,7 @@ void doit() { } { int j = 0; //expected-note{{declared}} - auto L = [](auto a) { //expected-note{{begins here}} + auto L = [](auto a) { //expected-note{{begins here}} expected-note 2 {{capture 'j' by}} expected-note 2 {{default capture by}} return j + 1; //expected-error{{cannot be implicitly captured}} }; } @@ -366,10 +367,10 @@ template struct Y { T t2{t}; return [](auto b) { const int y = 0; //expected-note{{declared here}} - return [](auto c) { //expected-note 2{{lambda expression begins here}} + return [](auto c) { //expected-note 2{{lambda expression begins here}} expected-note 2 {{capture 'x' by}} expected-note 2 {{capture 'y' by}} expected-note 4 {{default capture by}} f(x, c); //expected-error{{variable 'x'}} f(y, c); //expected-error{{variable 'y'}} - return 0; + return 0; }; }; }; @@ -530,7 +531,7 @@ struct X { L(3.13); } { - auto L = [](auto a) { + auto L = [](auto a) { // expected-note {{explicitly capture 'this'}} f(a); //expected-error{{this}} }; L(3.13); @@ -561,8 +562,8 @@ struct X { static void f(double) { } int g() { - auto L = [=](auto a) { - return [](int i) { + auto L = [=](auto a) { + return [](int i) { // expected-note {{explicitly capture 'this'}} return [=](auto b) { f(decltype(a){}); //expected-error{{this}} int x = i; @@ -585,8 +586,8 @@ struct X { static void f(double) { } int g() { - auto L = [=](auto a) { - return [](auto b) { + auto L = [=](auto a) { + return [](auto b) { // expected-note {{explicitly capture 'this'}} return [=](int i) { f(b); f(decltype(a){}); //expected-error{{this}} @@ -609,8 +610,8 @@ struct X { static void f(double) { } int g() { - auto L = [=](auto a) { - return [](auto b) { + auto L = [=](auto a) { + return [](auto b) { // expected-note {{explicitly capture 'this'}} return [=](int i) { f(b); //expected-error{{this}} f(decltype(a){}); @@ -632,9 +633,9 @@ struct X { static void f(double) { } int g() { - auto L = [=](auto a) { + auto L = [=](auto a) { return [](int i) { - return [=](auto b) { + return [=](auto b) { // expected-cxx2a-note {{explicitly capture 'this'}} f(b); //expected-error{{'this' cannot}} int x = i; }; @@ -655,8 +656,8 @@ int foo() { // This variable is used and must be caught early, do not need instantiation const int x = 0; //expected-note{{declared}} - auto L = [](auto a) { //expected-note{{begins}} - const int &r = x; //expected-error{{variable}} + auto L = [](auto a) { //expected-note{{begins}} expected-note 2 {{capture 'x' by}} expected-note 2 {{default capture by}} + const int &r = x; //expected-error{{variable}} }; } { // This variable is not used @@ -670,7 +671,7 @@ int foo() const int x = 0; //expected-note{{declared}} auto L = [=](auto a) { // <-- #A const int y = 0; - return [](auto b) { //expected-note{{begins}} + return [](auto b) { //expected-note{{begins}} expected-note 2 {{capture 'x' by}} expected-note 2 {{default capture by}} int c[sizeof(b)]; f(x, c); f(y, c); @@ -716,7 +717,7 @@ int foo() { int x; auto L = [](auto a) { //expected-note {{declared here}} int y = 10; //expected-note {{declared here}} - return [](int b) { //expected-note 2{{expression begins here}} + return [](int b) { //expected-note 2{{expression begins here}} expected-note 2 {{capture 'a' by}} expected-note 2 {{capture 'y' by}} expected-note 4 {{default capture by}} return [=] (auto c) { return a + y; //expected-error 2{{cannot be implicitly captured}} }; @@ -908,7 +909,7 @@ struct X { return 0; } int g2() { - auto lam = [](auto a) { f(a); }; // expected-error{{'this'}} + auto lam = [](auto a) { f(a); }; // expected-error{{'this'}} expected-note {{explicitly capture 'this'}} lam(0); // expected-note{{in instantiation of}} lam(0.0); // ok. return 0; @@ -941,9 +942,10 @@ template struct YUnresolvable { template struct YUnresolvable2 { void f(int) { } static void f(double) { } - + T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}} \ - //expected-note{{in instantiation of}} + //expected-note{{in instantiation of}}\ + //expected-note {{explicitly capture 'this'}} T t2 = [=](auto b) { f(b); return b; }; }; @@ -961,8 +963,8 @@ template struct YOnlyStatic { YOnlyStatic yos; template struct YOnlyNonStatic { void f(int) { } - - T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}} + + T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}} expected-note {{explicitly capture 'this'}} }; @@ -980,8 +982,8 @@ struct FunctorInt { template struct YThisCapture { const int x = 10; - static double d; - T t = [](auto a) { return x; }; //expected-error{{'this'}} + static double d; + T t = [](auto a) { return x; }; //expected-error{{'this'}} expected-note {{explicitly capture 'this'}} T t2 = [](auto b) { return d; }; T t3 = [this](auto a) { return [=](auto b) { @@ -993,10 +995,10 @@ template struct YThisCapture { return x; }; }; - T t5 = [](auto a) { - return [=](auto b) { - return x; //expected-error{{'this'}} - }; + T t5 = [](auto a) { // expected-note {{explicitly capture 'this'}} + return [=](auto b) { + return x; //expected-error{{'this'}} + }; }; }; @@ -1020,8 +1022,8 @@ template void foo(int); //expected-note{{in instantiation of}} #else template void foo(T t) { //expected-note{{declared here}} - auto L = []() //expected-note{{begins here}} - { return t; }; //expected-error{{cannot be implicitly captured}} + auto L = []() //expected-note{{begins here}} expected-note 2 {{capture 't' by}} expected-note 2 {{default capture by}} + { return t; }; //expected-error{{cannot be implicitly captured}} } #endif @@ -1049,9 +1051,9 @@ struct X { void f(double) { } int g() { - auto L = [=](auto a) { f(a); }; - L(0); - auto L2 = [](auto a) { f(a); }; //expected-error {{cannot be implicitly captured}} + auto L = [=](auto a) { f(a); }; + L(0); + auto L2 = [](auto a) { f(a); }; //expected-error {{cannot be implicitly captured}} expected-note {{explicitly capture 'this'}} return 0; } }; @@ -1080,7 +1082,7 @@ struct X { static void f(double) { } template int g(T t) { - auto L = [](auto a) { f(a); }; //expected-error{{'this'}} + auto L = [](auto a) { f(a); }; //expected-error{{'this'}} expected-note {{explicitly capture 'this'}} L(t); // expected-note{{in instantiation of}} return 0; } @@ -1099,7 +1101,7 @@ struct X { void f(int) { } template int g(T t) { - auto L = [](auto a) { f(a); }; //expected-error{{'this'}} + auto L = [](auto a) { f(a); }; //expected-error{{'this'}} expected-note {{explicitly capture 'this'}} L(t); return 0; } @@ -1209,9 +1211,9 @@ struct X { static void f(double) { } int g() { - auto L = [=](auto a) { + auto L = [=](auto a) { return [](int i) { - return [=](auto b) { + return [=](auto b) { // expected-cxx2a-note {{explicitly capture 'this'}} f(b); //expected-error {{'this' cannot}} int x = i; }; @@ -1235,9 +1237,9 @@ struct X { static void f(double) { } int g() { - auto L = [](auto a) { + auto L = [](auto a) { return [=](auto i) { - return [=](auto b) { + return [=](auto b) { // expected-cxx2a-note {{explicitly capture 'this'}} f(b); //expected-error {{'this' cannot}} int x = i; }; diff --git a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp index 00a7dc10a785..4b6cbf9584f2 100644 --- a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp +++ b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp @@ -258,7 +258,7 @@ int test() { { int i = 10; //expected-note 3{{declared here}} auto L = [](auto a) { - return [](auto b) { //expected-note 3{{begins here}} + return [](auto b) { //expected-note 3{{begins here}} expected-note 6 {{capture 'i' by}} expected-note 6 {{default capture by}} i = b; //expected-error 3{{cannot be implicitly captured}} return b; }; diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp index 79d56e11c441..1c1c93c757a0 100644 --- a/clang/test/SemaCXX/cxx1y-init-captures.cpp +++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp @@ -21,10 +21,10 @@ namespace variadic_expansion { return a; }() ...); }; - auto N2 = [x = y, //expected-note3{{begins here}} + auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}} &z = y, n = f(t...), - o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { - fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}} + o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}} + fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}} return a; }() ...); }; @@ -57,8 +57,8 @@ int test() { } { const int x = 10; - auto L = [k = x](char a) { //expected-note {{declared}} - return [](int b) { //expected-note {{begins}} + auto L = [k = x](char a) { //expected-note {{declared}} + return [](int b) { //expected-note {{begins}} expected-note 2 {{capture 'k' by}} expected-note 2 {{default capture by}} return [j = k](int c) { //expected-error {{cannot be implicitly captured}} return c; }; @@ -117,13 +117,12 @@ int test(T t = T{}) { } { // will need to capture x in outer lambda const T x = 10; //expected-note {{declared}} - auto L = [z = x](char a) { //expected-note {{begins}} + auto L = [z = x](char a) { //expected-note {{begins}} expected-note 2 {{capture 'x' by}} expected-note 2 {{default capture by}} auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}} return y; }; return M; }; - } { // will need to capture x in outer lambda const T x = 10; @@ -146,7 +145,7 @@ int test(T t = T{}) { } { // will need to capture x in outer lambda const int x = 10; //expected-note {{declared}} - auto L = [z = x](char a) { //expected-note {{begins}} + auto L = [z = x](char a) { //expected-note {{begins}} expected-note 2 {{capture 'x' by}} expected-note 2 {{default capture by}} auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}} return y; }; diff --git a/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp b/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp index fa4ff03fad7f..d79924c8e2ed 100644 --- a/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp +++ b/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp @@ -34,7 +34,7 @@ duration a = 1ns, b = 1us, c = 1ms, d = 1s, e = 1min, f = 1h; string s = "foo"s; char error = 'x's; // expected-error {{invalid suffix}} expected-error {{expected ';'}} -int _1z = 1z; // expected-error {{invalid suffix}} +int _1y = 1y; // expected-error {{invalid suffix}} int _1b = 1b; // expected-error {{invalid digit}} complex cf1 = 1if, cf2 = 2.if, cf3 = 0x3if; diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp index 305cc3e976b0..62b1c166e954 100644 --- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -416,6 +416,17 @@ B b(0, {}); } +namespace no_crash_on_default_arg { +class A { + template class B { + B(int c = 1); + }; + // This used to crash due to unparsed default arg above. The diagnostic could + // be improved, but the point of this test is to simply check we do not crash. + B(); // expected-error {{deduction guide declaration without trailing return type}} +}; +} // namespace no_crash_on_default_arg + #pragma clang diagnostic push #pragma clang diagnostic warning "-Wctad-maybe-unsupported" namespace test_implicit_ctad_warning { @@ -532,6 +543,18 @@ namespace PR47175 { int m = n; } +// Ensure we don't crash when CTAD fails. +template +struct Foo { // expected-note{{candidate function template not viable}} + Foo(T1, T2); // expected-note{{candidate function template not viable}} +}; + +template +void insert(Args &&...args); + +void foo() { + insert(Foo(2, 2, 2)); // expected-error{{no viable constructor or deduction guide}} +} #else // expected-no-diagnostics diff --git a/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp index d7ebfdc3133a..6a1f48bf7958 100644 --- a/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp +++ b/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp @@ -93,7 +93,7 @@ void f() { } void f(char c) { //expected-note{{declared here}} - auto L = [] { return c; }; //expected-error{{cannot be implicitly captured}} expected-note{{lambda expression begins here}} + auto L = [] { return c; }; //expected-error{{cannot be implicitly captured}} expected-note{{lambda expression begins here}} expected-note 2 {{capture 'c' by}} expected-note 2 {{default capture by}} int I = L(); } diff --git a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp index 097ca00640e9..f37ebc9f6365 100644 --- a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp +++ b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp @@ -17,7 +17,7 @@ namespace std { return (T*)NEW(sizeof(T) * N); // expected-note 3{{heap allocation}} expected-note {{not deallocated}} } constexpr void deallocate(void *p) { - DELETE(p); // expected-note 2{{'std::allocator<...>::deallocate' used to delete pointer to object allocated with 'new'}} + DELETE(p); // #dealloc expected-note 2{{'std::allocator<...>::deallocate' used to delete pointer to object allocated with 'new'}} } }; } @@ -83,6 +83,11 @@ static_assert(mismatched(2, 2)); constexpr int *escape = std::allocator().allocate(3); // expected-error {{constant expression}} expected-note {{pointer to subobject of heap-allocated}} constexpr int leak = (std::allocator().allocate(3), 0); // expected-error {{constant expression}} constexpr int no_lifetime_start = (*std::allocator().allocate(1) = 1); // expected-error {{constant expression}} expected-note {{assignment to object outside its lifetime}} +constexpr int no_deallocate_nullptr = (std::allocator().deallocate(nullptr), 1); // expected-error {{constant expression}} expected-note {{in call}} +// expected-note@#dealloc {{'std::allocator<...>::deallocate' used to delete a null pointer}} +constexpr int no_deallocate_nonalloc = (std::allocator().deallocate((int*)&no_deallocate_nonalloc), 1); // expected-error {{constant expression}} expected-note {{in call}} +// expected-note@#dealloc {{delete of pointer '&no_deallocate_nonalloc' that does not point to a heap-allocated object}} +// expected-note@-2 {{declared here}} void *operator new(std::size_t, void *p) { return p; } constexpr bool no_placement_new_in_user_code() { // expected-error {{never produces a constant expression}} diff --git a/clang/test/SemaCXX/cxx98-compat-pedantic.cpp b/clang/test/SemaCXX/cxx98-compat-pedantic.cpp index c72c44ad5feb..74aa890b8c62 100644 --- a/clang/test/SemaCXX/cxx98-compat-pedantic.cpp +++ b/clang/test/SemaCXX/cxx98-compat-pedantic.cpp @@ -4,7 +4,7 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Werror %s // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s -DCXX98 -// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-compat-pedantic -verify %s -Wno-c++98-c++11-compat-pedantic -DCXX1Y2 +// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-compat-pedantic -verify %s -Wno-pre-c++14-compat-pedantic -DCXX1Y2 // -Wc++98-compat-pedantic warns on C++11 features which we accept without a // warning in C++98 mode. diff --git a/clang/test/SemaCXX/inline.cpp b/clang/test/SemaCXX/inline.cpp index ba29521ce504..1a13609eb578 100644 --- a/clang/test/SemaCXX/inline.cpp +++ b/clang/test/SemaCXX/inline.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s -Wc++98-c++11-c++14-compat +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s -Wpre-c++17-compat // Check that we don't allow illegal uses of inline // (checking C++-only constructs here) diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 22e0939379f5..71a876f6f9b3 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -12,17 +12,17 @@ namespace ExplicitCapture { virtual C& Overload(float); void ImplicitThisCapture() { - [](){(void)Member;}; // expected-error {{'this' cannot be implicitly captured in this context}} - const int var = [](){(void)Member; return 0;}(); // expected-error {{'this' cannot be implicitly captured in this context}} + []() { (void)Member; }; // expected-error {{'this' cannot be implicitly captured in this context}} expected-note {{explicitly capture 'this'}} + const int var = []() {(void)Member; return 0; }(); // expected-error {{'this' cannot be implicitly captured in this context}} expected-note {{explicitly capture 'this'}} [&](){(void)Member;}; [this](){(void)Member;}; [this]{[this]{};}; []{[this]{};};// expected-error {{'this' cannot be implicitly captured in this context}} []{Overload(3);}; - []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}} + [] { Overload(); }; // expected-error {{'this' cannot be implicitly captured in this context}} expected-note {{explicitly capture 'this'}} []{(void)typeid(Overload());}; - []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}} + [] { (void)typeid(Overload(.5f)); }; // expected-error {{'this' cannot be implicitly captured in this context}} expected-note {{explicitly capture 'this'}} } }; @@ -47,14 +47,14 @@ namespace ReturnDeduction { namespace ImplicitCapture { void test() { int a = 0; // expected-note 5 {{declared}} - []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}} + []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}} expected-note 2 {{capture 'a' by}} expected-note 2 {{default capture by}} [&]() { return a; }; [=]() { return a; }; [=]() { int* b = &a; }; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}} [=]() { return [&]() { return a; }; }; - []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} - []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} - []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}} + []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-note 2 {{capture 'a' by}} expected-note 2 {{default capture by}} + []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-note 2 {{capture 'a' by}} expected-note 2 {{default capture by}} + []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}} expected-note 4 {{capture 'a' by}} expected-note 4 {{default capture by}} [=]() { return [&a] { return a; }; }; // const int b = 2; @@ -74,7 +74,7 @@ namespace ImplicitCapture { int f[10]; // expected-note {{declared}} [&]() { return f[2]; }; (void) ^{ return []() { return f[2]; }; }; // expected-error {{variable 'f' cannot be implicitly captured in a lambda with no capture-default specified}} \ - // expected-note{{lambda expression begins here}} + // expected-note{{lambda expression begins here}} expected-note 2 {{capture 'f' by}} expected-note 2 {{default capture by}} struct G { G(); G(G&); int a; }; // expected-note 6 {{not viable}} G g; @@ -83,13 +83,13 @@ namespace ImplicitCapture { (void)^{ return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error 2 {{no matching constructor for initialization of 'const G'}} const int h = a; // expected-note {{declared}} - []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} + []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-note 2 {{capture 'h' by}} expected-note 2 {{default capture by}} // References can appear in constant expressions if they are initialized by // reference constant expressions. int i; int &ref_i = i; // expected-note {{declared}} - [] { return ref_i; }; // expected-error {{variable 'ref_i' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} + [] { return ref_i; }; // expected-error {{variable 'ref_i' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-note 2 {{capture 'ref_i' by}} expected-note 2 {{default capture by}} static int j; int &ref_j = j; @@ -259,7 +259,8 @@ namespace VariadicPackExpansion { // instantiation backtrace. f([&ts] { return (int)f(ts...); } ()...); // \ // expected-error 2{{'ts' cannot be implicitly captured}} \ - // expected-note 2{{lambda expression begins here}} + // expected-note 2{{lambda expression begins here}} \ + // expected-note 4 {{capture 'ts' by}} } template void nested2(int); // ok template void nested2(int, int); // expected-note {{in instantiation of}} @@ -375,7 +376,7 @@ namespace PR18128 { int a = [=]{ return n; }(); // ok int b = [=]{ return [=]{ return n; }(); }(); // ok int c = []{ int k = 0; return [=]{ return k; }(); }(); // ok - int d = []{ return [=]{ return n; }(); }(); // expected-error {{'this' cannot be implicitly captured in this context}} + int d = [] { return [=] { return n; }(); }(); // expected-error {{'this' cannot be implicitly captured in this context}} expected-note {{explicitly capture 'this'}} }; } @@ -661,6 +662,6 @@ void Test() { }; [] { return i; }; // expected-error {{variable '' cannot be implicitly captured in a lambda with no capture-default specified}} // expected-note@-1 {{lambda expression begins here}} - + // expected-note@-2 2 {{default capture by}} } }; diff --git a/clang/test/SemaCXX/lambda-invalid-capture.cpp b/clang/test/SemaCXX/lambda-invalid-capture.cpp index a4d96b34df85..c9bd0d786cab 100644 --- a/clang/test/SemaCXX/lambda-invalid-capture.cpp +++ b/clang/test/SemaCXX/lambda-invalid-capture.cpp @@ -18,7 +18,7 @@ void captures_invalid_array_type() { } int pr43080(int i) { // expected-note {{declared here}} - return [] { // expected-note {{begins here}} + return [] { // expected-note {{begins here}} expected-note 2 {{capture 'i' by}} expected-note 2 {{default capture by}} return sizeof i < i; // expected-error {{variable 'i' cannot be implicitly captured in a lambda with no capture-default specified}} }(); diff --git a/clang/test/SemaCXX/scope-check.cpp b/clang/test/SemaCXX/scope-check.cpp index 518a1e9f2606..7eec58ca057a 100644 --- a/clang/test/SemaCXX/scope-check.cpp +++ b/clang/test/SemaCXX/scope-check.cpp @@ -629,3 +629,19 @@ void indirect_jumps(void **ip) { } } // namespace seh + +void continue_scope_check() { + // These are OK. + for (; ({break; true;});) {} + for (; ({continue; true;});) {} + for (; int n = ({break; 0;});) {} + for (; int n = 0; ({break;})) {} + for (; int n = 0; ({continue;})) {} + + // This would jump past the initialization of 'n' to the increment (where 'n' + // is in scope). + for (; int n = ({continue; 0;});) {} // expected-error {{cannot jump from this continue statement to the loop increment; jump bypasses initialization of loop condition variable}} + + // An intervening loop makes it OK again. + for (; int n = ({while (true) continue; 0;});) {} +} diff --git a/clang/test/SemaCXX/size_t-literal.cpp b/clang/test/SemaCXX/size_t-literal.cpp new file mode 100644 index 000000000000..180f95979b39 --- /dev/null +++ b/clang/test/SemaCXX/size_t-literal.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -std=c++2b -triple x86_64-linux -Wpre-c++2b-compat -fsyntax-only -verify=cxx2b %s +// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux -fsyntax-only -verify=cxx20 %s +// RUN: %clang_cc1 -std=c++2b -triple i686-linux -fsyntax-only -verify=cxx2b-32 %s +// RUN: %clang_cc1 -x c -std=c11 -fsyntax-only -verify=c11 %s + +#ifdef __cplusplus + +typedef __SIZE_TYPE__ size_t; +// Assume ptrdiff_t is the signed integer type corresponding to size_t. +typedef __PTRDIFF_TYPE__ ssize_t; + +template +struct is_same { static constexpr bool value = false; }; + +template +struct is_same { static constexpr bool value = true; }; + +void SSizeT() { + auto a1 = 1z; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a2 = 1Z; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); +} + +void SizeT() { + auto a1 = 1uz; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a2 = 1uZ; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a3 = 1Uz; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a4 = 1UZ; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a5 = 1zu; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a6 = 1Zu; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a7 = 1zU; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); + + auto a8 = 1ZU; + // cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}} + // cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}} + static_assert(is_same::value); +} + +void oor() { +#if __i386__ + (void)3'000'000'000z; // cxx2b-32-error {{signed 'size_t' literal is out of range of possible signed 'size_t' values}} + (void)3'000'000'000uz; + (void)5'000'000'000uz; // cxx2b-32-error {{'size_t' literal is out of range of possible 'size_t' values}} + + (void)0x80000000z; + (void)0x80000000uz; + (void)0x180000000uz; //cxx2b-32-error {{'size_t' literal is out of range of possible 'size_t' values}} +#endif +} + +#else + +void f() { + (void)1z; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1Z; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1uz; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1uZ; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1Uz; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1UZ; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1zu; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1Zu; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1zU; // c11-error {{'size_t' suffix for literals is a C++2b feature}} + (void)1ZU; // c11-error {{'size_t' suffix for literals is a C++2b feature}} +} + +#endif diff --git a/clang/test/SemaCXX/switch-implicit-fallthrough.cpp b/clang/test/SemaCXX/switch-implicit-fallthrough.cpp index a67f6bef1f49..e6ae0d55b588 100644 --- a/clang/test/SemaCXX/switch-implicit-fallthrough.cpp +++ b/clang/test/SemaCXX/switch-implicit-fallthrough.cpp @@ -299,16 +299,16 @@ int fallthrough_placement_error(int n) { int fallthrough_targets(int n) { [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}} - [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} + [[clang::fallthrough]] // expected-error{{'fallthrough' attribute only applies to empty statements}} switch (n) { case 121: n += 400; [[clang::fallthrough]]; // no warning here, correct target case 123: - [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} + [[clang::fallthrough]] // expected-error{{'fallthrough' attribute only applies to empty statements}} n += 800; break; - [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}} + [[clang::fallthrough]] // expected-error{{'fallthrough' attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}} case 125: n += 1600; } diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index 5adb1f99c27f..d576e4388d6f 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -13,6 +13,7 @@ typedef NonPOD NonPODArMB[10][2]; // PODs enum Enum { EV }; enum SignedEnum : signed int { }; +enum UnsignedEnum : unsigned int { }; struct POD { Enum e; int i; float f; NonPOD* p; }; struct Empty {}; struct IncompleteStruct; @@ -1440,6 +1441,7 @@ void is_signed() int t25[F(__is_signed(IntArNB))]; int t26[F(__is_signed(Union))]; int t27[F(__is_signed(UnionAr))]; + int t28[F(__is_signed(UnsignedEnum))]; } void is_unsigned() @@ -1450,7 +1452,6 @@ void is_unsigned() int t04[T(__is_unsigned(unsigned int))]; int t05[T(__is_unsigned(unsigned long))]; int t06[T(__is_unsigned(unsigned long long))]; - int t07[T(__is_unsigned(Enum))]; int t10[F(__is_unsigned(void))]; int t11[F(__is_unsigned(cvoid))]; @@ -1468,6 +1469,9 @@ void is_unsigned() int t24[F(__is_unsigned(Derives))]; int t25[F(__is_unsigned(ClassType))]; int t26[F(__is_unsigned(IntArNB))]; + int t27[F(__is_unsigned(Enum))]; + int t28[F(__is_unsigned(UnsignedEnum))]; + int t29[F(__is_unsigned(SignedEnum))]; } typedef Int& IntRef; diff --git a/clang/test/SemaCXX/warn-cast-function-type.cpp b/clang/test/SemaCXX/warn-cast-function-type.cpp new file mode 100644 index 000000000000..cfacce022410 --- /dev/null +++ b/clang/test/SemaCXX/warn-cast-function-type.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -x c++ %s -fblocks -fsyntax-only -Wcast-function-type -triple x86_64-- -verify + +int x(long); + +typedef int (f1)(long); +typedef int (f2)(void*); +typedef int (f3)(...); +typedef void (f4)(...); +typedef void (f5)(void); +typedef int (f6)(long, int); +typedef int (f7)(long,...); +typedef int (&f8)(long, int); + +f1 *a; +f2 *b; +f3 *c; +f4 *d; +f5 *e; +f6 *f; +f7 *g; + +struct S +{ + void foo (int*); + void bar (int); +}; + +typedef void (S::*mf)(int); + +void foo() { + a = (f1 *)x; + b = (f2 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f2 *' (aka 'int (*)(void *)') converts to incompatible function type}} */ + b = reinterpret_cast(x); /* expected-warning {{cast from 'int (*)(long)' to 'f2 *' (aka 'int (*)(void *)') converts to incompatible function type}} */ + c = (f3 *)x; + d = (f4 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f4 *' (aka 'void (*)(...)') converts to incompatible function type}} */ + e = (f5 *)x; + f = (f6 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f6 *' (aka 'int (*)(long, int)') converts to incompatible function type}} */ + g = (f7 *)x; + + mf p1 = (mf)&S::foo; /* expected-warning {{cast from 'void (S::*)(int *)' to 'mf' (aka 'void (S::*)(int)') converts to incompatible function type}} */ + + f8 f2 = (f8)x; /* expected-warning {{cast from 'int (long)' to 'f8' (aka 'int (&)(long, int)') converts to incompatible function type}} */ + (void)f2; + + int (^y)(long); + f = (f6 *)y; /* expected-warning {{cast from 'int (^)(long)' to 'f6 *' (aka 'int (*)(long, int)') converts to incompatible function type}} */ +} diff --git a/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp index 6d38ec95fbfb..47588660d204 100644 --- a/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp +++ b/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp @@ -4,15 +4,14 @@ struct BB {}; struct BB1 {}; -class complex : public BB, BB1 { -public: +class complex : public BB, BB1 { +public: complex() - : s2(1), // expected-warning {{field 's2' will be initialized after field 's1'}} - s1(1), - s3(3), // expected-warning {{field 's3' will be initialized after base 'BB1'}} - BB1(), // expected-warning {{base class 'BB1' will be initialized after base 'BB'}} - BB() - {} + : s2(1), // expected-warning {{initializer order does not match the declaration order}} expected-note {{field 's2' will be initialized after field 's1'}} + s1(1), + s3(3), // expected-note {{field 's3' will be initialized after base 'BB1'}} + BB1(), // expected-note {{base class 'BB1' will be initialized after base 'BB'}} + BB() {} int s1; int s2; int s3; diff --git a/clang/test/SemaCXX/warn-thread-safety-parsing.cpp b/clang/test/SemaCXX/warn-thread-safety-parsing.cpp index 6ad0f877a11d..b6e9c052a241 100644 --- a/clang/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -1295,6 +1295,11 @@ struct SLDerived2 : public SLTemplateClass { // expected-warning{{'unlock_function' attribute without capability arguments refers to 'this', but 'SLDerived2' isn't annotated with 'capability' or 'scoped_lockable' attribute}} }; +struct SLDerived3 : public SLTemplateDerived { + ~SLDerived3() UNLOCK_FUNCTION(); // \ + // expected-warning{{'unlock_function' attribute without capability arguments refers to 'this', but 'SLDerived3' isn't annotated with 'capability' or 'scoped_lockable' attribute}} +}; + //----------------------------------------------------- // Parsing of member variables and function parameters //------------------------------------------------------ diff --git a/clang/test/SemaObjC/format-arg-attribute.m b/clang/test/SemaObjC/format-arg-attribute.m index 67c9c2e3d4c9..ac81bdc21dc1 100644 --- a/clang/test/SemaObjC/format-arg-attribute.m +++ b/clang/test/SemaObjC/format-arg-attribute.m @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -verify -fsyntax-only %s @class NSString; +@class NSAttributedString; extern NSString *fa2 (const NSString *) __attribute__((format_arg(1))); extern NSString *fa3 (NSString *) __attribute__((format_arg(1))); @@ -25,3 +26,5 @@ extern int fi3 (const NSString *) __attribute__((format_arg(1))); // expected-error {{function does not return NSString}} extern NSString *fi4 (const NSString *) __attribute__((format_arg(1))); extern NSString *fi5 (const NSString *) __attribute__((format_arg(1))); + +extern NSAttributedString *fattrs (const NSString *) __attribute__((format_arg(1))); diff --git a/clang/test/SemaObjC/warn-called-once.m b/clang/test/SemaObjC/warn-called-once.m index 1014e1730163..ff2778d4bd0a 100644 --- a/clang/test/SemaObjC/warn-called-once.m +++ b/clang/test/SemaObjC/warn-called-once.m @@ -31,6 +31,16 @@ @interface NSMutableArray : NSArray @class NSString, Protocol; extern void NSLog(NSString *format, ...); +typedef int group_t; +typedef struct dispatch_queue_s *dispatch_queue_t; +typedef void (^dispatch_block_t)(void); +extern dispatch_queue_t queue; + +void dispatch_group_async(dispatch_queue_t queue, + group_t group, + dispatch_block_t block); +void dispatch_async(dispatch_queue_t queue, dispatch_block_t block); + void escape(void (^callback)(void)); void escape_void(void *); void indirect_call(void (^callback)(void) CALLED_ONCE); @@ -225,11 +235,11 @@ void indirect_call_within_direct_call(void (^callback)(void) CALLED_ONCE, } void block_call_1(void (^callback)(void) CALLED_ONCE) { - indirect_call(^{ - callback(); - }); - callback(); - // no-warning + indirect_call( // expected-note{{previous call is here}} + ^{ + callback(); + }); + callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}} } void block_call_2(void (^callback)(void) CALLED_ONCE) { @@ -255,7 +265,7 @@ void block_call_4(int cond, void (^callback)(void) CALLED_ONCE) { // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}} escape(callback); } - }(); + }(); // no-warning } void block_call_5(void (^outer)(void) CALLED_ONCE) { @@ -273,6 +283,32 @@ void block_with_called_once(void (^outer)(void) CALLED_ONCE) { outer(); // expected-warning{{'outer' parameter marked 'called_once' is called twice}} } +void block_dispatch_call(int cond, void (^callback)(void) CALLED_ONCE) { + dispatch_async(queue, ^{ + if (cond) // expected-warning{{'callback' parameter marked 'called_once' is never called when taking false branch}} + callback(); + }); +} + +void block_escape_call_1(int cond, void (^callback)(void) CALLED_ONCE) { + escape_void((__bridge void *)^{ + if (cond) { + // no-warning + callback(); + } + }); +} + +void block_escape_call_2(int cond, void (^callback)(void) CALLED_ONCE) { + escape_void((__bridge void *)^{ + if (cond) { + callback(); // expected-note{{previous call is here}} + } + // Double call can still be reported. + callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}} + }); +} + void never_called_one_exit(int cond, void (^callback)(void) CALLED_ONCE) { if (!cond) // expected-warning{{'callback' parameter marked 'called_once' is never called when taking true branch}} return; @@ -822,11 +858,10 @@ - (void)escaped_one_path:(int)cond callback:(void (^)(void))CALLED_ONCE callback - (void)block_call_1:(void (^)(void))CALLED_ONCE callback { // We consider captures by blocks as escapes - [self indirect_call:(^{ + [self indirect_call:(^{ // expected-note{{previous call is here}} callback(); })]; - callback(); - // no-warning + callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}} } - (void)block_call_2:(int)cond callback:(void (^)(void))CALLED_ONCE callback { @@ -1036,6 +1071,20 @@ - (void)testWithCompletion:(void (^)(void))callback { } } +- (void)test:(int)cond fooWithReplyTo:(void (^)(void))handler { + if (cond) { + // expected-warning@-1{{completion handler is never called when taking false branch}} + handler(); + } +} + +- (void)test:(int)cond with:(void (^)(void))fooWithCompletionBlock { + if (cond) { + // expected-warning@-1{{completion handler is never called when taking false branch}} + fooWithCompletionBlock(); + } +} + - (void)completion_handler_wrong_type:(int (^)(void))completionHandler { // We don't want to consider completion handlers with non-void return types. if ([self condition]) { @@ -1116,4 +1165,74 @@ - (void)test_nil_suppression_3:(int)cond1 } } +- (void)test_escape_before_branch:(int)cond + withCompletion:(void (^)(void))handler { + if (cond) { + filler(); + } + + void (^copiedHandler)(void) = ^{ + handler(); + }; + + if (cond) { + // no-warning + handler(); + } else { + copiedHandler(); + } +} + +- (void)test_escape_after_branch:(int)cond + withCompletion:(void (^)(void))handler { + if (cond) { + // no-warning + handler(); + } + + escape(handler); +} + +// rdar://74441906 +typedef void (^DeferredBlock)(void); +static inline void DefferedCallback(DeferredBlock *inBlock) { (*inBlock)(); } +#define _DEFERCONCAT(a, b) a##b +#define _DEFERNAME(a) _DEFERCONCAT(__DeferredVar_, a) +#define DEFER __extension__ __attribute__((cleanup(DefferedCallback), unused)) \ + DeferredBlock _DEFERNAME(__COUNTER__) = ^ + +- (void)test_cleanup_1:(int)cond + withCompletion:(void (^)(void))handler { + int error = 0; + DEFER { + if (error) + handler(); + }; + + if (cond) { + error = 1; + } else { + // no-warning + handler(); + } +} + +- (void)test_cleanup_2:(int)cond + withCompletion:(void (^)(void))handler { + int error = 0; + DEFER { + if (error) + handler(); + }; + + if (cond) { + error = 1; + } else { + handler(); // expected-note{{previous call is here}} + } + + // We still can warn about double call even in this case. + handler(); // expected-warning{{completion handler is called twice}} +} + @end diff --git a/clang/test/SemaObjCXX/capturing-flexible-array-in-block.mm b/clang/test/SemaObjCXX/capturing-flexible-array-in-block.mm index cf88d4684c58..086abc988916 100644 --- a/clang/test/SemaObjCXX/capturing-flexible-array-in-block.mm +++ b/clang/test/SemaObjCXX/capturing-flexible-array-in-block.mm @@ -5,5 +5,5 @@ void f() { struct { int x; int y[]; } a; // expected-note 3 {{'a' declared here}} ^{return a.x;}(); // expected-error {{cannot refer to declaration of structure variable with flexible array member inside block}} [=] {return a.x;}(); // expected-error {{variable 'a' with flexible array member cannot be captured in a lambda expression}} - [] {return a.x;}(); // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default}} expected-note {{here}} + [] {return a.x;}(); // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default}} expected-note {{here}} expected-note 2 {{capture 'a' by}} expected-note 2 {{default capture by}} } diff --git a/clang/test/SemaOpenCL/access-qualifier.cl b/clang/test/SemaOpenCL/access-qualifier.cl index a5e1b65daf70..4912d9401737 100644 --- a/clang/test/SemaOpenCL/access-qualifier.cl +++ b/clang/test/SemaOpenCL/access-qualifier.cl @@ -76,7 +76,7 @@ kernel void k14(read_only pipe int p) { #endif #if __OPENCL_C_VERSION__ < 200 -kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes extension to be enabled}} +kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes support}} #endif #if __OPENCL_C_VERSION__ >= 200 diff --git a/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl b/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl index f63e2913c749..d25a03504c03 100644 --- a/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl +++ b/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl @@ -235,11 +235,11 @@ kernel void bar(global unsigned int *buf) kernel void foo1(global unsigned int *buf) { ndrange_t n; - buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups extension to be enabled}} + buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups support}} } kernel void bar1(global unsigned int *buf) { ndrange_t n; - buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups extension to be enabled}} + buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups support}} } diff --git a/clang/test/SemaOpenCL/extension-begin.cl b/clang/test/SemaOpenCL/extension-begin.cl index fdb481f8e092..f1f0de084cef 100644 --- a/clang/test/SemaOpenCL/extension-begin.cl +++ b/clang/test/SemaOpenCL/extension-begin.cl @@ -41,11 +41,11 @@ void test_f1(void) { #pragma OPENCL EXTENSION my_ext : disable void test_f2(void) { - struct A test_A2; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}} - const struct A test_A_local; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}} - TypedefOfA test_typedef_A; // expected-error {{use of type 'TypedefOfA' (aka 'struct A') requires my_ext extension to be enabled}} - PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const __private struct A *') requires my_ext extension to be enabled}} - f(); // expected-error {{use of declaration 'f' requires my_ext extension to be enabled}} + struct A test_A2; // expected-error {{use of type 'struct A' requires my_ext support}} + const struct A test_A_local; // expected-error {{use of type 'struct A' requires my_ext support}} + TypedefOfA test_typedef_A; // expected-error {{use of type 'TypedefOfA' (aka 'struct A') requires my_ext support}} + PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const __private struct A *') requires my_ext support}} + f(); // expected-error {{use of declaration 'f' requires my_ext support}} g(0); // expected-error {{no matching function for call to 'g'}} // expected-note@extension-begin.h:18 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be enabled}} // expected-note@extension-begin.h:23 {{candidate function not viable: requires 0 arguments, but 1 was provided}} diff --git a/clang/test/SemaOpenCL/extension-version.cl b/clang/test/SemaOpenCL/extension-version.cl index 64c8590d9b20..d135970b8b02 100644 --- a/clang/test/SemaOpenCL/extension-version.cl +++ b/clang/test/SemaOpenCL/extension-version.cl @@ -93,12 +93,12 @@ // expected-warning@-2{{OpenCL extension 'cl_khr_fp64' is core feature or supported optional core feature - ignoring}} #endif -//Core feature in CL 2.0 +//Core feature in CL 2.0, optional core feature in CL 3.0 #ifndef cl_khr_3d_image_writes #error "Missing cl_khr_3d_image_writes define" #endif #pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable -#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) && defined TEST_CORE_FEATURES +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200 || __OPENCL_C_VERSION__ == 300) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_3d_image_writes' is core feature or supported optional core feature - ignoring}} #endif diff --git a/clang/test/SemaOpenCL/extensions.cl b/clang/test/SemaOpenCL/extensions.cl index 55dbd1d5eede..b0be017511a8 100644 --- a/clang/test/SemaOpenCL/extensions.cl +++ b/clang/test/SemaOpenCL/extensions.cl @@ -43,8 +43,8 @@ #endif #if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) -void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}} - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} +void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 support}} + double d; // expected-error {{type 'double' requires cl_khr_fp64 support}} (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}} } #endif @@ -72,14 +72,14 @@ int isfinite(float x) { void f2(void) { double d; #ifdef NOFP64 -// expected-error@-2{{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +// expected-error@-2{{use of type 'double' requires cl_khr_fp64 support}} #endif typedef double double4 __attribute__((ext_vector_type(4))); double4 d4 = {0.0f, 2.0f, 3.0f, 1.0f}; #ifdef NOFP64 -// expected-error@-3 {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} -// expected-error@-3 {{use of type 'double4' (vector of 4 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-error@-3 {{use of type 'double' requires cl_khr_fp64 support}} +// expected-error@-3 {{use of type 'double4' (vector of 4 'double' values) requires cl_khr_fp64 support}} #endif (void) 1.0; @@ -96,6 +96,6 @@ void f2(void) { #if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) void f3(void) { - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} + double d; // expected-error {{type 'double' requires cl_khr_fp64 support}} } #endif diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl index 825dd3a935d0..103d1d8b262b 100644 --- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl @@ -39,6 +39,9 @@ typedef unsigned int uint; typedef unsigned long ulong; typedef unsigned short ushort; typedef __SIZE_TYPE__ size_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; +typedef __INTPTR_TYPE__ intptr_t; +typedef __UINTPTR_TYPE__ uintptr_t; typedef char char2 __attribute__((ext_vector_type(2))); typedef char char4 __attribute__((ext_vector_type(4))); typedef uchar uchar4 __attribute__((ext_vector_type(4))); @@ -98,6 +101,24 @@ void test_typedef_args(clk_event_t evt, volatile atomic_flag *flg, global unsign size_t ws[2] = {2, 8}; ndrange_t r = ndrange_2D(ws); } + +// Check that atomic_fetch_ functions can be called with (u)intptr_t arguments, +// despite OpenCLBuiltins.td not providing explicit overloads for those types. +void test_atomic_fetch(volatile __generic atomic_int *a_int, + volatile __generic atomic_intptr_t *a_intptr, + volatile __generic atomic_uintptr_t *a_uintptr) { + int i; + intptr_t ip; + uintptr_t uip; + ptrdiff_t ptrdiff; + + i = atomic_fetch_add(a_int, i); + ip = atomic_fetch_add(a_intptr, ptrdiff); + uip = atomic_fetch_add(a_uintptr, ptrdiff); + + ip = atomic_fetch_or(a_intptr, ip); + uip = atomic_fetch_or(a_uintptr, uip); +} #endif kernel void basic_conversion() { diff --git a/clang/test/SemaOpenCL/fp-options.cl b/clang/test/SemaOpenCL/fp-options.cl index 413afd61819d..3b7cb89cf41b 100644 --- a/clang/test/SemaOpenCL/fp-options.cl +++ b/clang/test/SemaOpenCL/fp-options.cl @@ -1,4 +1,3 @@ -// RUN: %clang_cc1 %s -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch -// RUN: %clang_cc1 %s -finclude-default-header -cl-no-signed-zeros -triple spir-unknown-unknown -include-pch %t.pch -fsyntax-only -verify +// RUN: %clang_cc1 %s -finclude-default-header -fdeclare-opencl-builtins -triple spir-unknown-unknown -emit-pch -o %t.pch +// RUN: %clang_cc1 %s -finclude-default-header -fdeclare-opencl-builtins -cl-no-signed-zeros -triple spir-unknown-unknown -include-pch %t.pch -fsyntax-only -verify // expected-no-diagnostics - diff --git a/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl b/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl index e76d54763016..48ed4c0594d6 100644 --- a/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl +++ b/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl @@ -1,6 +1,9 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=+cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=+cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify -DEXT %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=-cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify %s +#ifdef cl_intel_device_side_avc_motion_estimation #pragma OPENCL EXTENSION cl_intel_device_side_avc_motion_estimation : enable +#endif // All intel_sub_group_avc_* types can only be used as argument or return value // of built-in functions defined in the extension. @@ -16,55 +19,77 @@ struct st{}; // negative test cases for initializers void foo(char c, float f, void* v, struct st ss) { intel_sub_group_avc_mce_payload_t payload_mce = 0; // No zero initializer for mce types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_mce_payload_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ime_payload_t payload_ime = 1; // No literal initializer for *payload_t types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_payload_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ref_payload_t payload_ref = f; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private float'}} intel_sub_group_avc_sic_payload_t payload_sic = ss; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_sic_payload_t' with an expression of incompatible type '__private struct st'}} - intel_sub_group_avc_mce_result_t result_mce = 0; // No zero initializer for mce types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_mce_result_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ime_result_t result_ime = 1; // No literal initializer for *result_t types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_result_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ref_result_t result_ref = f; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_result_t' with an expression of incompatible type '__private float'}} intel_sub_group_avc_sic_result_t result_sic = ss; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_sic_result_t' with an expression of incompatible type '__private struct st'}} - intel_sub_group_avc_ime_result_single_reference_streamout_t sstreamout = v; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_result_single_reference_streamout_t' with an expression of incompatible type '__private void *__private'}} - intel_sub_group_avc_ime_result_dual_reference_streamout_t dstreamin_list = {0x0, 0x1}; - // expected-warning@-1 {{excess elements in struct initializer}} intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list2 = {}; - // expected-error@-1 {{scalar initializer cannot be empty}} intel_sub_group_avc_ime_single_reference_streamin_t dstreamin_list3 = {c}; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_single_reference_streamin_t' with an expression of incompatible type '__private char'}} intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list4 = {1}; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_dual_reference_streamin_t' with an expression of incompatible type 'int'}} +#ifdef EXT +// expected-error@-14 {{initializing '__private intel_sub_group_avc_mce_payload_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_payload_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private float'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_sic_payload_t' with an expression of incompatible type '__private struct st'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_mce_result_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_result_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ref_result_t' with an expression of incompatible type '__private float'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_sic_result_t' with an expression of incompatible type '__private struct st'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_result_single_reference_streamout_t' with an expression of incompatible type '__private void *__private'}} +// expected-warning@-14 {{excess elements in struct initializer}} +// expected-error@-14 {{scalar initializer cannot be empty}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_single_reference_streamin_t' with an expression of incompatible type '__private char'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_dual_reference_streamin_t' with an expression of incompatible type 'int'}} +#else +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_single_reference_streamout_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_dual_reference_streamout_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_single_reference_streamin_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} +#endif } // negative tests for initializers and assignment void far() { intel_sub_group_avc_mce_payload_t payload_mce; intel_sub_group_avc_mce_payload_t payload_mce2 = payload_mce; - intel_sub_group_avc_ime_payload_t payload_ime; intel_sub_group_avc_ref_payload_t payload_ref = payload_ime; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private intel_sub_group_avc_ime_payload_t'}} - intel_sub_group_avc_sic_result_t result_sic; intel_sub_group_avc_ime_result_t result_ime; result_sic = result_ime; - // expected-error@-1 {{assigning to '__private intel_sub_group_avc_sic_result_t' from incompatible type '__private intel_sub_group_avc_ime_result_t'}} +#ifdef EXT +// expected-error@-5 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private intel_sub_group_avc_ime_payload_t'}} +// expected-error@-3 {{assigning to '__private intel_sub_group_avc_sic_result_t' from incompatible type '__private intel_sub_group_avc_ime_result_t'}} +#else +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} +// expected-error@-11 {{use of undeclared identifier 'result_sic'}} expected-error@-11 {{use of undeclared identifier 'result_ime'}} +#endif } // Using 0x0 directly allows us not to include opencl-c.h header and not to // redefine all of these CLK_AVC_*_INTITIALIZE_INTEL macro. '0x0' value must // be in sync with ones defined in opencl-c.h +#ifdef EXT // positive test cases void bar() { const sampler_t vme_sampler = 0x0; @@ -102,4 +127,4 @@ void bar() { intel_sub_group_avc_ime_single_reference_streamin_t sstreamin_list = {0}; intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list = {0}; } - +#endif //EXT diff --git a/clang/test/SemaOpenCL/printf-format-string-warnings.cl b/clang/test/SemaOpenCL/printf-format-string-warnings.cl index d08c95b6d8ab..af4905108557 100644 --- a/clang/test/SemaOpenCL/printf-format-string-warnings.cl +++ b/clang/test/SemaOpenCL/printf-format-string-warnings.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header -fdeclare-opencl-builtins // Make sure warnings are produced based on printf format strings. diff --git a/clang/test/SemaOpenCLCXX/address-space-castoperators.cl b/clang/test/SemaOpenCLCXX/address-space-castoperators.clcpp similarity index 93% rename from clang/test/SemaOpenCLCXX/address-space-castoperators.cl rename to clang/test/SemaOpenCLCXX/address-space-castoperators.clcpp index 7fd7f728fda3..f0ec86cb0afc 100644 --- a/clang/test/SemaOpenCLCXX/address-space-castoperators.cl +++ b/clang/test/SemaOpenCLCXX/address-space-castoperators.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s +//RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s void nester_ptr() { local int * * locgen; diff --git a/clang/test/SemaOpenCLCXX/address-space-cond.cl b/clang/test/SemaOpenCLCXX/address-space-cond.clcpp similarity index 91% rename from clang/test/SemaOpenCLCXX/address-space-cond.cl rename to clang/test/SemaOpenCLCXX/address-space-cond.clcpp index 809059892000..1b45515b1a15 100644 --- a/clang/test/SemaOpenCLCXX/address-space-cond.cl +++ b/clang/test/SemaOpenCLCXX/address-space-cond.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -verify +// RUN: %clang_cc1 %s -pedantic -verify namespace PointerRvalues { diff --git a/clang/test/SemaOpenCLCXX/address-space-deduction.cl b/clang/test/SemaOpenCLCXX/address-space-deduction.clcpp similarity index 97% rename from clang/test/SemaOpenCLCXX/address-space-deduction.cl rename to clang/test/SemaOpenCLCXX/address-space-deduction.clcpp index ddfdb6da4347..1b757ca43687 100644 --- a/clang/test/SemaOpenCLCXX/address-space-deduction.cl +++ b/clang/test/SemaOpenCLCXX/address-space-deduction.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s +//RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s //expected-no-diagnostics diff --git a/clang/test/SemaOpenCLCXX/address-space-lambda.cl b/clang/test/SemaOpenCLCXX/address-space-lambda.clcpp similarity index 88% rename from clang/test/SemaOpenCLCXX/address-space-lambda.cl rename to clang/test/SemaOpenCLCXX/address-space-lambda.clcpp index 571ea9035877..66dc4da13d2c 100644 --- a/clang/test/SemaOpenCLCXX/address-space-lambda.cl +++ b/clang/test/SemaOpenCLCXX/address-space-lambda.clcpp @@ -1,5 +1,5 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify -triple i386-windows | FileCheck %s +//RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s +//RUN: %clang_cc1 %s -pedantic -ast-dump -verify -triple i386-windows | FileCheck %s //CHECK: CXXMethodDecl {{.*}} constexpr operator() 'int (__private int){{.*}} const __generic' auto glambda = [](auto a) { return a; }; @@ -61,7 +61,10 @@ __kernel void test_qual() { [&] () __global {} (); //expected-error{{no matching function for call to object of type '(lambda at}} expected-note{{candidate function not viable: 'this' object is in default address space, but method expects object in address space '__global'}} [&] () __private {} (); //expected-error{{no matching function for call to object of type '(lambda at}} expected-note{{candidate function not viable: 'this' object is in default address space, but method expects object in address space '__private'}} - [&] __private {} (); //expected-error{{lambda requires '()' before attribute specifier}} expected-error{{expected body of lambda expression}} + [&] __private {} (); // expected-error{{no matching function for call to object of type '(lambda at}} expected-note{{candidate function not viable: 'this' object is in default address space, but method expects object in address space '__private'}} +#if __cplusplus <= 202002L +// expected-warning@-2{{lambda without a parameter clause is a C++2b extension}} +#endif [&] () mutable __private {} (); [&] () __private mutable {} (); //expected-error{{expected body of lambda expression}} diff --git a/clang/test/SemaOpenCLCXX/address-space-of-this-class-scope.cl b/clang/test/SemaOpenCLCXX/address-space-of-this-class-scope.clcpp similarity index 90% rename from clang/test/SemaOpenCLCXX/address-space-of-this-class-scope.cl rename to clang/test/SemaOpenCLCXX/address-space-of-this-class-scope.clcpp index 86d839d9701b..55cfef3ceee4 100644 --- a/clang/test/SemaOpenCLCXX/address-space-of-this-class-scope.cl +++ b/clang/test/SemaOpenCLCXX/address-space-of-this-class-scope.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify +//RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify struct C { auto fGlob() __global -> decltype(this); diff --git a/clang/test/SemaOpenCLCXX/address-space-of-this.cl b/clang/test/SemaOpenCLCXX/address-space-of-this.clcpp similarity index 56% rename from clang/test/SemaOpenCLCXX/address-space-of-this.cl rename to clang/test/SemaOpenCLCXX/address-space-of-this.clcpp index ac79b3411928..d77469b197c2 100644 --- a/clang/test/SemaOpenCLCXX/address-space-of-this.cl +++ b/clang/test/SemaOpenCLCXX/address-space-of-this.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify -fsyntax-only +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify -fsyntax-only // expected-no-diagnostics // Extract from PR38614 diff --git a/clang/test/SemaOpenCLCXX/address-space-references.cl b/clang/test/SemaOpenCLCXX/address-space-references.clcpp similarity index 95% rename from clang/test/SemaOpenCLCXX/address-space-references.cl rename to clang/test/SemaOpenCLCXX/address-space-references.clcpp index 05e789a7d4fd..76426ea65c28 100644 --- a/clang/test/SemaOpenCLCXX/address-space-references.cl +++ b/clang/test/SemaOpenCLCXX/address-space-references.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify -fsyntax-only +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify -fsyntax-only __global const int& f(__global float &ref) { return ref; // expected-error{{reference of type 'const __global int &' cannot bind to a temporary object because of address space mismatch}} diff --git a/clang/test/SemaOpenCLCXX/address-space-templates.cl b/clang/test/SemaOpenCLCXX/address-space-templates.clcpp similarity index 93% rename from clang/test/SemaOpenCLCXX/address-space-templates.cl rename to clang/test/SemaOpenCLCXX/address-space-templates.clcpp index b7db0e6de3d2..0ea1a2a1e4df 100644 --- a/clang/test/SemaOpenCLCXX/address-space-templates.cl +++ b/clang/test/SemaOpenCLCXX/address-space-templates.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -verify -ast-dump | FileCheck %s +//RUN: %clang_cc1 %s -pedantic -verify -ast-dump | FileCheck %s template struct S { @@ -31,7 +31,7 @@ template struct as_pointer { // Check address space deduction in template parameter deduction. struct rep { // When there is no address space on a reference use __generic. - // CHECK: |-CXXConstructorDecl {{.*}} rep 'void (const __generic rep &__private) __generic' + // CHECK: |-CXXConstructorDecl {{.*}} rep 'void (const __generic rep &__private){{.*}} __generic' template::type> rep(U&& v) {} }; @@ -57,6 +57,6 @@ void bar() { rep_outer r; int i; // Preserve the address space of the type in forwarding reference. - // CHECK: CXXMethodDecl {{.*}} operator() 'void (__private int &__private) const __generic' + // CHECK: CXXMethodDecl {{.*}} operator() 'void (__private int &__private){{.*}} const __generic' foo4(i, [](auto&& x){;}); } diff --git a/clang/test/SemaOpenCLCXX/address_space_overloading.cl b/clang/test/SemaOpenCLCXX/address_space_overloading.clcpp similarity index 83% rename from clang/test/SemaOpenCLCXX/address_space_overloading.cl rename to clang/test/SemaOpenCLCXX/address_space_overloading.clcpp index 33337ef461df..01f5010b58bf 100644 --- a/clang/test/SemaOpenCLCXX/address_space_overloading.cl +++ b/clang/test/SemaOpenCLCXX/address_space_overloading.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=clc++ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only // expected-no-diagnostics struct RetGlob { diff --git a/clang/test/SemaOpenCLCXX/addrspace-auto.cl b/clang/test/SemaOpenCLCXX/addrspace-auto.clcpp similarity index 94% rename from clang/test/SemaOpenCLCXX/addrspace-auto.cl rename to clang/test/SemaOpenCLCXX/addrspace-auto.clcpp index 2860237ddef7..7862564d1b4e 100644 --- a/clang/test/SemaOpenCLCXX/addrspace-auto.cl +++ b/clang/test/SemaOpenCLCXX/addrspace-auto.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s +//RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s __constant int i = 1; //CHECK: |-VarDecl {{.*}} ai '__global int':'__global int' diff --git a/clang/test/SemaOpenCLCXX/addrspace_cast.cl b/clang/test/SemaOpenCLCXX/addrspace_cast.clcpp similarity index 95% rename from clang/test/SemaOpenCLCXX/addrspace_cast.cl rename to clang/test/SemaOpenCLCXX/addrspace_cast.clcpp index 3bf01757accd..37cf1bc1d296 100644 --- a/clang/test/SemaOpenCLCXX/addrspace_cast.cl +++ b/clang/test/SemaOpenCLCXX/addrspace_cast.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify -fsyntax-only +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify -fsyntax-only void foo(global int *gl, const global int *gl_const, global int &gl_ref) { //FIXME: Diagnostics can be improved to be more specific in some cases. diff --git a/clang/test/SemaOpenCLCXX/addrspace_cast_ast_dump.cl b/clang/test/SemaOpenCLCXX/addrspace_cast_ast_dump.clcpp similarity index 83% rename from clang/test/SemaOpenCLCXX/addrspace_cast_ast_dump.cl rename to clang/test/SemaOpenCLCXX/addrspace_cast_ast_dump.clcpp index cdc3e2785774..87a7f669ea9e 100644 --- a/clang/test/SemaOpenCLCXX/addrspace_cast_ast_dump.cl +++ b/clang/test/SemaOpenCLCXX/addrspace_cast_ast_dump.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify -ast-dump | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify -ast-dump | FileCheck %s // expected-no-diagnostics diff --git a/clang/test/SemaOpenCLCXX/invalid-kernel.cl b/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp similarity index 89% rename from clang/test/SemaOpenCLCXX/invalid-kernel.cl rename to clang/test/SemaOpenCLCXX/invalid-kernel.clcpp index 2efdb756446d..2cbfffd5a00e 100644 --- a/clang/test/SemaOpenCLCXX/invalid-kernel.cl +++ b/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -verify -fsyntax-only +// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only struct C { kernel void m(); //expected-error{{kernel functions cannot be class members}} diff --git a/clang/test/SemaOpenCLCXX/members.cl b/clang/test/SemaOpenCLCXX/members.clcpp similarity index 76% rename from clang/test/SemaOpenCLCXX/members.cl rename to clang/test/SemaOpenCLCXX/members.clcpp index 855948f0615e..c0a885cc4bd1 100644 --- a/clang/test/SemaOpenCLCXX/members.cl +++ b/clang/test/SemaOpenCLCXX/members.clcpp @@ -1,5 +1,5 @@ -//RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -verify -fsyntax-only -//RUN: %clang_cc1 %s -triple spir -cl-std=clc++ -verify -fsyntax-only -DFUNCPTREXT +//RUN: %clang_cc1 %s -triple spir -verify -fsyntax-only +//RUN: %clang_cc1 %s -triple spir -verify -fsyntax-only -DFUNCPTREXT #ifdef FUNCPTREXT #pragma OPENCL EXTENSION __cl_clang_function_pointers : enable diff --git a/clang/test/SemaOpenCLCXX/method-overload-address-space.cl b/clang/test/SemaOpenCLCXX/method-overload-address-space.clcpp similarity index 86% rename from clang/test/SemaOpenCLCXX/method-overload-address-space.cl rename to clang/test/SemaOpenCLCXX/method-overload-address-space.clcpp index 7c428a570c2c..3164901d38cf 100644 --- a/clang/test/SemaOpenCLCXX/method-overload-address-space.cl +++ b/clang/test/SemaOpenCLCXX/method-overload-address-space.clcpp @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify +//RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify struct C { void m1() __local __local; //expected-warning{{multiple identical address spaces specified for type}} diff --git a/clang/test/SemaOpenCLCXX/newdelete.cl b/clang/test/SemaOpenCLCXX/newdelete.clcpp similarity index 94% rename from clang/test/SemaOpenCLCXX/newdelete.cl rename to clang/test/SemaOpenCLCXX/newdelete.clcpp index 2ef27843d5ce..127efbedded8 100644 --- a/clang/test/SemaOpenCLCXX/newdelete.cl +++ b/clang/test/SemaOpenCLCXX/newdelete.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify -fsyntax-only +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify -fsyntax-only class A { public: diff --git a/clang/test/SemaOpenCLCXX/references.cl b/clang/test/SemaOpenCLCXX/references.clcpp similarity index 89% rename from clang/test/SemaOpenCLCXX/references.cl rename to clang/test/SemaOpenCLCXX/references.clcpp index 42acb1272927..cffcc2cfbc29 100644 --- a/clang/test/SemaOpenCLCXX/references.cl +++ b/clang/test/SemaOpenCLCXX/references.clcpp @@ -1,5 +1,5 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -verify -fsyntax-only -triple spir -//RUN: %clang_cc1 %s -cl-std=clc++ -verify -fsyntax-only -DFPTREXT -triple spir +//RUN: %clang_cc1 %s -verify -fsyntax-only -triple spir +//RUN: %clang_cc1 %s -verify -fsyntax-only -DFPTREXT -triple spir #ifdef FPTREXT #pragma OPENCL EXTENSION __cl_clang_function_pointers : enable diff --git a/clang/test/SemaOpenCLCXX/restricted.cl b/clang/test/SemaOpenCLCXX/restricted.clcpp similarity index 94% rename from clang/test/SemaOpenCLCXX/restricted.cl rename to clang/test/SemaOpenCLCXX/restricted.clcpp index c00c634073fe..2a84b4138b46 100644 --- a/clang/test/SemaOpenCLCXX/restricted.cl +++ b/clang/test/SemaOpenCLCXX/restricted.clcpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -pedantic -verify -fsyntax-only +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -pedantic -verify -fsyntax-only // This test checks that various C/C++/OpenCL C constructs are not available in // C++ for OpenCL. diff --git a/clang/test/SemaOpenCLCXX/template-astype.cl b/clang/test/SemaOpenCLCXX/template-astype.cl new file mode 100644 index 000000000000..efb93412cb20 --- /dev/null +++ b/clang/test/SemaOpenCLCXX/template-astype.cl @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fdeclare-opencl-builtins -finclude-default-header %s -cl-std=clc++ -verify + +// Test as_type, which is defined in terms of __builtin_astype. +template +auto templated_astype(T x) { + return as_int2(x); + // expected-error@-1{{invalid reinterpretation: sizes of 'int2' (vector of 2 'int' values) and '__private int' must match}} +} + +auto test_long(long x) { return templated_astype(x); } + +auto neg_test_int(int x) { return templated_astype(x); } +// expected-note@-1{{in instantiation of function template specialization 'templated_astype' requested here}} + +auto test_short4(short4 x) { return templated_astype(x); } + +// Test __builtin_astype. +template +auto templated_builtin_astype(T x) { + return __builtin_astype(x, int2); +} + +auto test_builtin(char8 x) { return templated_builtin_astype(x); } diff --git a/clang/test/SemaSYCL/float128.cpp b/clang/test/SemaSYCL/float128.cpp index d2d520b5b12d..b91535eda489 100644 --- a/clang/test/SemaSYCL/float128.cpp +++ b/clang/test/SemaSYCL/float128.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple spir64 -fsycl -fsycl-is-device -verify -fsyntax-only %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsycl -fsycl-is-device -fsyntax-only %s +// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsycl-is-device -fsyntax-only %s typedef __float128 BIGTY; diff --git a/clang/test/SemaSYCL/int128.cpp b/clang/test/SemaSYCL/int128.cpp index 38271bc020d3..f6f92c237a9c 100644 --- a/clang/test/SemaSYCL/int128.cpp +++ b/clang/test/SemaSYCL/int128.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple spir64 -aux-triple x86_64-unknown-linux-gnu \ -// RUN: -fsycl -fsycl-is-device -verify -fsyntax-only %s +// RUN: -fsycl-is-device -verify -fsyntax-only %s typedef __uint128_t BIGTY; diff --git a/clang/test/SemaSYCL/kernel-attribute.cpp b/clang/test/SemaSYCL/kernel-attribute.cpp index ae9589e7b099..84ba69fd46f9 100644 --- a/clang/test/SemaSYCL/kernel-attribute.cpp +++ b/clang/test/SemaSYCL/kernel-attribute.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fsycl -fsycl-is-device -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fsycl-is-device -verify %s // Only function templates [[clang::sycl_kernel]] int gv2 = 0; // expected-warning {{'sycl_kernel' attribute only applies to function templates}} diff --git a/clang/test/SemaSYCL/prohibit-thread-local.cpp b/clang/test/SemaSYCL/prohibit-thread-local.cpp index 4fd113626ea7..e507489695f8 100644 --- a/clang/test/SemaSYCL/prohibit-thread-local.cpp +++ b/clang/test/SemaSYCL/prohibit-thread-local.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64 -verify -fsyntax-only %s +// RUN: %clang_cc1 -fsycl-is-device -triple spir64 -verify -fsyntax-only %s thread_local const int prohobit_ns_scope = 0; thread_local int prohobit_ns_scope2 = 0; diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp index b9a1f0dccb24..0f48a4dc1095 100644 --- a/clang/test/SemaTemplate/deduction.cpp +++ b/clang/test/SemaTemplate/deduction.cpp @@ -604,3 +604,14 @@ namespace merge_size_only_deductions { int b = f(X(), Y<1, 2>(), X, id>()); #endif } + +namespace PR49724 { + struct A; + template class X {}; + template void f(X

); + void g(X x) { f(x); } + + template class Y {}; + template void f(Y

); + void g(Y y) { f(y); } +} diff --git a/clang/test/TableGen/emit-diag-docs.td b/clang/test/TableGen/emit-diag-docs.td index b2ecba727f4f..2dd1a6b57af0 100644 --- a/clang/test/TableGen/emit-diag-docs.td +++ b/clang/test/TableGen/emit-diag-docs.td @@ -13,8 +13,14 @@ def MySubNested : TextSubstitution<"%sub{MyGoodBad}1 %sub{MyKinds}2 are %sub{MyG let Group = MyGroup in { -// CHECK: |:warning:`warning:` |nbsp| :diagtext:`this is my diff text`| -// CHECK-NEXT: +-----------------------------------------------------------+ +// CHECK: |:warning:`warning:` |nbsp| |+--------------------------------------------------------------------+| +// CHECK-NEXT: | ||+------------------------------------------------------------------+|| +// CHECK-NEXT: | |||:placeholder:`A` |nbsp| :diagtext:`is not` |nbsp| :placeholder:`B`||| +// CHECK-NEXT: | ||+------------------------------------------------------------------+|| +// CHECK-NEXT: | |+--------------------------------------------------------------------+| +// CHECK-NEXT: | ||:diagtext:`this is my diff text` || +// CHECK-NEXT: | |+--------------------------------------------------------------------+| +// CHECK-NEXT: +---------------------------+----------------------------------------------------------------------+ def CheckDiff : Warning<"%diff{$ is not $|this is my diff text}0,1">; diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index 863ab444fb02..21b674539a30 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -26,7 +26,7 @@ # suffixes: A list of file extensions to treat as test files. config.suffixes = ['.c', '.cpp', '.i', '.cppm', '.m', '.mm', '.cu', - '.ll', '.cl', '.s', '.S', '.modulemap', '.test', '.rs', '.ifs'] + '.ll', '.cl', '.clcpp', '.s', '.S', '.modulemap', '.test', '.rs', '.ifs'] # excludes: A list of directories to exclude from the testsuite. The 'Inputs' # subdirectories contain auxiliary inputs for various tests in their parent @@ -92,6 +92,9 @@ ('%hmaptool', "'%s' %s" % (config.python_executable, os.path.join(config.clang_tools_dir, 'hmaptool')))) +config.substitutions.append(('%host_cc', config.host_cc)) +config.substitutions.append(('%host_cxx', config.host_cxx)) + # Plugins (loadable modules) if config.has_plugins and config.llvm_plugin_ext: diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index eb01720249af..85526b9d30d6 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -9,11 +9,13 @@ config.llvm_libs_dir = path(r"@LLVM_LIBS_DIR@") config.llvm_shlib_dir = path(r"@SHLIBDIR@") config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@" config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@") +config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@" config.clang_obj_root = path(r"@CLANG_BINARY_DIR@") config.clang_src_dir = path(r"@CLANG_SOURCE_DIR@") config.clang_tools_dir = path(r"@CLANG_TOOLS_DIR@") config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" +config.host_cc = "@CMAKE_C_COMPILER@" config.host_cxx = "@CMAKE_CXX_COMPILER@" config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" config.have_zlib = @LLVM_ENABLE_ZLIB@ diff --git a/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected b/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected index 4f8f6003bfb4..b9a8d5f55dc9 100644 --- a/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected +++ b/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected @@ -44,7 +44,7 @@ Foo::Foo(int x) : x(x) {} // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca %class.Foo*, align 8 // CHECK-NEXT: store %class.Foo* [[THIS:%.*]], %class.Foo** [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load %class.Foo*, %class.Foo** [[THIS_ADDR]], align 8 -// CHECK-NEXT: call void @_ZN3FooD2Ev(%class.Foo* nonnull dereferenceable(4) [[THIS1]]) [[ATTR3:#.*]] +// CHECK-NEXT: call void @_ZN3FooD2Ev(%class.Foo* nonnull dereferenceable(4) [[THIS1]]) #[[ATTR3:[0-9]+]] // CHECK-NEXT: ret void // Foo::~Foo() {} @@ -70,7 +70,7 @@ int Foo::function_defined_out_of_line(int arg) const { return x - arg; } // CHECK-NEXT: call void @_ZN3FooC1Ei(%class.Foo* nonnull dereferenceable(4) [[F]], i32 1) // CHECK-NEXT: [[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* nonnull dereferenceable(4) [[F]], i32 2) // CHECK-NEXT: [[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* nonnull dereferenceable(4) [[F]], i32 3) -// CHECK-NEXT: call void @_ZN3FooD1Ev(%class.Foo* nonnull dereferenceable(4) [[F]]) [[ATTR3]] +// CHECK-NEXT: call void @_ZN3FooD1Ev(%class.Foo* nonnull dereferenceable(4) [[F]]) #[[ATTR3]] // CHECK-NEXT: ret i32 0 // int main() { diff --git a/clang/test/utils/update_cc_test_checks/Inputs/exec-all-runlines.c b/clang/test/utils/update_cc_test_checks/Inputs/exec-all-runlines.c new file mode 100644 index 000000000000..e0dfc42c4bd6 --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/exec-all-runlines.c @@ -0,0 +1,11 @@ +// Check that the non-clang/non-filechecked runlines execute +// RUN: cp %s %S/Output/execute-all-runlines.copy.c +// RUN: cp %S/Output/execute-all-runlines.copy.c %s.copy.c +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s.copy.c -emit-llvm-bc -o %t-host.bc +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -fopenmp-host-ir-file-path %t-host.bc %s.copy.c -emit-llvm -o - | FileCheck %s + +void use(int); + +void test(int a) +{ +} diff --git a/clang/test/utils/update_cc_test_checks/Inputs/exec-all-runlines.c.expected b/clang/test/utils/update_cc_test_checks/Inputs/exec-all-runlines.c.expected new file mode 100644 index 000000000000..ae9745fa9b1e --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/exec-all-runlines.c.expected @@ -0,0 +1,18 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// Check that the non-clang/non-filechecked runlines execute +// RUN: cp %s %S/Output/execute-all-runlines.copy.c +// RUN: cp %S/Output/execute-all-runlines.copy.c %s.copy.c +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s.copy.c -emit-llvm-bc -o %t-host.bc +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -fopenmp-host-ir-file-path %t-host.bc %s.copy.c -emit-llvm -o - | FileCheck %s + +void use(int); + +// CHECK-LABEL: @test( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4 +// CHECK-NEXT: ret void +// +void test(int a) +{ +} diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c new file mode 100644 index 000000000000..3d51d48568ef --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck %s + +void __test_offloading_42_abcdef_bar_l123(); +void use(int); + +void foo(int a) +{ + #pragma omp target + use(a); + + __test_offloading_42_abcdef_bar_l123(); +} diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c.expected new file mode 100644 index 000000000000..838db8d8e606 --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c.expected @@ -0,0 +1,36 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-function-regex "__([a-z]+)_offloading_[a-z0-9]+_[a-z0-9]+_(.*)_l[0-9]+" +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck %s + +void __test_offloading_42_abcdef_bar_l123(); +void use(int); + +void foo(int a) +{ + #pragma omp target + use(a); + + __test_offloading_42_abcdef_bar_l123(); +} +// CHECK-LABEL: @foo( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32* +// CHECK-NEXT: store i32 [[TMP0]], i32* [[CONV]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_CASTED]], align 8 +// CHECK-NEXT: call void @{{__omp_offloading_[a-z0-9]+_[a-z0-9]+_foo_l[0-9]+}}(i64 [[TMP1]]) #[[ATTR3:[0-9]+]] +// CHECK-NEXT: call void (...) @{{__test_offloading_[a-z0-9]+_[a-z0-9]+_bar_l[0-9]+}}() +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: @{{__omp_offloading_[a-z0-9]+_[a-z0-9]+_foo_l[0-9]+}}( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8 +// CHECK-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32* +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[CONV]], align 8 +// CHECK-NEXT: call void @use(i32 [[TMP0]]) +// CHECK-NEXT: ret void +// diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected index cbdfff47675c..96868dd7bab1 100644 --- a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected +++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected @@ -34,7 +34,7 @@ void foo(void) { // OMP-NEXT: entry: // OMP-NEXT: [[I:%.*]] = alloca i32, align 4 // OMP-NEXT: store i32 0, i32* [[I]], align 4 -// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2:@.*]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) +// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) // OMP-NEXT: ret void // // @@ -57,7 +57,7 @@ void foo(void) { // OMP-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 // OMP-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // OMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -// OMP-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* [[GLOB1:@.*]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// OMP-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // OMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 // OMP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431 // OMP-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -97,7 +97,7 @@ void foo(void) { // OMP: omp.inner.for.end: // OMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // OMP: omp.loop.exit: -// OMP-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* [[GLOB1]], i32 [[TMP1]]) +// OMP-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // OMP-NEXT: ret void // // @@ -107,7 +107,7 @@ void foo(void) { // OMP-NEXT: [[I:%.*]] = alloca i32, align 4 // OMP-NEXT: store i32 0, i32* [[RETVAL]], align 4 // OMP-NEXT: store i32 0, i32* [[I]], align 4 -// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) +// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) // OMP-NEXT: call void @foo() // OMP-NEXT: ret i32 0 // @@ -131,7 +131,7 @@ void foo(void) { // OMP-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 // OMP-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // OMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -// OMP-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* [[GLOB1]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// OMP-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // OMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 // OMP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431 // OMP-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -171,7 +171,7 @@ void foo(void) { // OMP: omp.inner.for.end: // OMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // OMP: omp.loop.exit: -// OMP-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* [[GLOB1]], i32 [[TMP1]]) +// OMP-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // OMP-NEXT: ret void // // @@ -197,7 +197,7 @@ void foo(void) { // NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4 // NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1 // NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4 -// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]] +// NOOMP-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] // NOOMP: for.end: // NOOMP-NEXT: call void @foo() // NOOMP-NEXT: ret i32 0 @@ -223,7 +223,7 @@ void foo(void) { // NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4 // NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1 // NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4 -// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]] +// NOOMP-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]] // NOOMP: for.end: // NOOMP-NEXT: ret void // diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected index 7bb40144b0b1..6685e56c7422 100644 --- a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected +++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected @@ -15,7 +15,7 @@ void foo(void); // OMP-NEXT: [[I:%.*]] = alloca i32, align 4 // OMP-NEXT: store i32 0, i32* [[RETVAL]], align 4 // OMP-NEXT: store i32 0, i32* [[I]], align 4 -// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2:@.*]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) +// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) // OMP-NEXT: call void @foo() // OMP-NEXT: ret i32 0 // @@ -41,7 +41,7 @@ void foo(void); // NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4 // NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1 // NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4 -// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]] +// NOOMP-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] // NOOMP: for.end: // NOOMP-NEXT: call void @foo() // NOOMP-NEXT: ret i32 0 @@ -63,7 +63,7 @@ int main() { // OMP-NEXT: entry: // OMP-NEXT: [[I:%.*]] = alloca i32, align 4 // OMP-NEXT: store i32 0, i32* [[I]], align 4 -// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) +// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) // OMP-NEXT: ret void // // NOOMP-LABEL: @foo( @@ -86,7 +86,7 @@ int main() { // NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4 // NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1 // NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4 -// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]] +// NOOMP-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]] // NOOMP: for.end: // NOOMP-NEXT: ret void // diff --git a/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected index 2069f7e185bb..2c29eb18db6f 100644 --- a/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected +++ b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s // CHECK-LABEL: define {{[^@]+}}@test -// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]] { +// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4 @@ -21,7 +21,7 @@ long test(long a, int b) { // A function with a mangled name // CHECK-LABEL: define {{[^@]+}}@_Z4testlii -// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR0]] { +// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4 diff --git a/clang/test/utils/update_cc_test_checks/Inputs/resolve-tmp-conflict.cpp b/clang/test/utils/update_cc_test_checks/Inputs/resolve-tmp-conflict.cpp new file mode 100644 index 000000000000..d82490ea3c88 --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/resolve-tmp-conflict.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s + +void foo(int a) { + int &tmp0 = a; + int &&tmp1 = 1; + tmp1 = a; + return; +} diff --git a/clang/test/utils/update_cc_test_checks/Inputs/resolve-tmp-conflict.cpp.expected b/clang/test/utils/update_cc_test_checks/Inputs/resolve-tmp-conflict.cpp.expected new file mode 100644 index 000000000000..9a3c4580f4c1 --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/resolve-tmp-conflict.cpp.expected @@ -0,0 +1,25 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --prefix-filecheck-ir-name _ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s + +// CHECK-LABEL: define {{[^@]+}}@_Z3fooi +// CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[_TMP0:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[_TMP1:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 +// CHECK-NEXT: store i32* [[A_ADDR]], i32** [[_TMP0]], align 8 +// CHECK-NEXT: store i32 1, i32* [[REF_TMP]], align 4 +// CHECK-NEXT: store i32* [[REF_TMP]], i32** [[_TMP1]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[_TMP1]], align 8 +// CHECK-NEXT: store i32 [[TMP0]], i32* [[TMP1]], align 4 +// CHECK-NEXT: ret void +// +void foo(int a) { + int &tmp0 = a; + int &&tmp1 = 1; + tmp1 = a; + return; +} diff --git a/clang/test/utils/update_cc_test_checks/exec-all-runlines.test b/clang/test/utils/update_cc_test_checks/exec-all-runlines.test new file mode 100644 index 000000000000..caf39934266c --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/exec-all-runlines.test @@ -0,0 +1,8 @@ +## Test that non-clang/non-filechecked runlines execute + +# RUN: cp %S/Inputs/exec-all-runlines.c %t-generated.c && %update_cc_test_checks %t-generated.c +# RUN: diff -u %S/Inputs/exec-all-runlines.c.expected %t-generated.c + +## Check that re-running update_cc_test_checks doesn't change the output +# RUN: %update_cc_test_checks %t-generated.c +# RUN: diff -u %S/Inputs/exec-all-runlines.c.expected %t-generated.c diff --git a/clang/test/utils/update_cc_test_checks/generated-funcs-regex.test b/clang/test/utils/update_cc_test_checks/generated-funcs-regex.test new file mode 100644 index 000000000000..4051d0a5181f --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/generated-funcs-regex.test @@ -0,0 +1,9 @@ +## Test that CHECK lines are generated for clang-generated functions replaced +## by regex + +## RUN: cp %S/Inputs/generated-funcs-regex.c %t-generated-funcs-regex.c && %update_cc_test_checks --include-generated-funcs --replace-function-regex "__([a-z]+)_offloading_[a-z0-9]+_[a-z0-9]+_(.*)_l[0-9]+" -- %t-generated-funcs-regex.c +# RUN: diff -u %S/Inputs/generated-funcs-regex.c.expected %t-generated-funcs-regex.c + +## Check that re-running update_cc_test_checks doesn't change the output +# RUN: %update_cc_test_checks %t-generated-funcs-regex.c +# RUN: diff -u %S/Inputs/generated-funcs-regex.c.expected %t-generated-funcs-regex.c diff --git a/clang/test/utils/update_cc_test_checks/resolve-tmp-conflict.test b/clang/test/utils/update_cc_test_checks/resolve-tmp-conflict.test new file mode 100644 index 000000000000..a802e1aeecd8 --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/resolve-tmp-conflict.test @@ -0,0 +1,8 @@ +## Test that CHECK lines generated avoid naming conflicts with FileCheck IR variables + +# RUN: cp %S/Inputs/resolve-tmp-conflict.cpp %t.cpp && %update_cc_test_checks --function-signature --prefix-filecheck-ir-name _ %t.cpp +# RUN: diff -u %S/Inputs/resolve-tmp-conflict.cpp.expected %t.cpp + +## Check that re-running update_cc_test_checks doesn't change the output +# RUN: %update_cc_test_checks %t.cpp +# RUN: diff -u %S/Inputs/resolve-tmp-conflict.cpp.expected %t.cpp diff --git a/clang/tools/arcmt-test/arcmt-test.cpp b/clang/tools/arcmt-test/arcmt-test.cpp index 940e622b8a68..26e123c59d59 100644 --- a/clang/tools/arcmt-test/arcmt-test.cpp +++ b/clang/tools/arcmt-test/arcmt-test.cpp @@ -207,11 +207,13 @@ static bool performTransformations(StringRef resourcesPath, static bool filesCompareEqual(StringRef fname1, StringRef fname2) { using namespace llvm; - ErrorOr> file1 = MemoryBuffer::getFile(fname1); + ErrorOr> file1 = + MemoryBuffer::getFile(fname1, /*IsText=*/true); if (!file1) return false; - ErrorOr> file2 = MemoryBuffer::getFile(fname2); + ErrorOr> file2 = + MemoryBuffer::getFile(fname2, /*IsText=*/true); if (!file2) return false; @@ -240,7 +242,7 @@ static bool verifyTransformedFiles(ArrayRef resultFiles) { if (RemappingsFile.empty()) inputBuf = MemoryBuffer::getSTDIN(); else - inputBuf = MemoryBuffer::getFile(RemappingsFile); + inputBuf = MemoryBuffer::getFile(RemappingsFile, /*IsText=*/true); if (!inputBuf) { errs() << "error: could not read remappings input\n"; return true; diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 1bb65ef12d6b..a8ff42ab104c 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -222,16 +222,16 @@ static llvm::json::Array toJSONSorted(const llvm::StringSet<> &Set) { return llvm::json::Array(Strings); } -static llvm::json::Array toJSONSorted(std::vector V) { - llvm::sort(V, [](const ClangModuleDep &A, const ClangModuleDep &B) { +static llvm::json::Array toJSONSorted(std::vector V) { + llvm::sort(V, [](const ModuleID &A, const ModuleID &B) { return std::tie(A.ModuleName, A.ContextHash) < std::tie(B.ModuleName, B.ContextHash); }); llvm::json::Array Ret; - for (const ClangModuleDep &CMD : V) + for (const ModuleID &MID : V) Ret.push_back(llvm::json::Object( - {{"module-name", CMD.ModuleName}, {"context-hash", CMD.ContextHash}})); + {{"module-name", MID.ModuleName}, {"context-hash", MID.ContextHash}})); return Ret; } @@ -244,26 +244,25 @@ class FullDeps { InputDeps ID; ID.FileName = std::string(Input); - ID.ContextHash = std::move(FD.ContextHash); + ID.ContextHash = std::move(FD.ID.ContextHash); ID.FileDeps = std::move(FD.FileDeps); ID.ModuleDeps = std::move(FD.ClangModuleDeps); std::unique_lock ul(Lock); for (const ModuleDeps &MD : FDR.DiscoveredModules) { - auto I = Modules.find({MD.ContextHash, MD.ModuleName, 0}); + auto I = Modules.find({MD.ID, 0}); if (I != Modules.end()) { I->first.InputIndex = std::min(I->first.InputIndex, InputIndex); continue; } - Modules.insert( - I, {{MD.ContextHash, MD.ModuleName, InputIndex}, std::move(MD)}); + Modules.insert(I, {{MD.ID, InputIndex}, std::move(MD)}); } if (FullCommandLine) ID.AdditonalCommandLine = FD.getAdditionalCommandLine( - [&](ClangModuleDep CMD) { return lookupPCMPath(CMD); }, - [&](ClangModuleDep CMD) -> const ModuleDeps & { - return lookupModuleDeps(CMD); + [&](ModuleID MID) { return lookupPCMPath(MID); }, + [&](ModuleID MID) -> const ModuleDeps & { + return lookupModuleDeps(MID); }); Inputs.push_back(std::move(ID)); @@ -271,13 +270,13 @@ class FullDeps { void printFullOutput(raw_ostream &OS) { // Sort the modules by name to get a deterministic order. - std::vector ModuleNames; + std::vector ModuleIDs; for (auto &&M : Modules) - ModuleNames.push_back(M.first); - llvm::sort(ModuleNames, - [](const ContextModulePair &A, const ContextModulePair &B) { - return std::tie(A.ModuleName, A.InputIndex) < - std::tie(B.ModuleName, B.InputIndex); + ModuleIDs.push_back(M.first); + llvm::sort(ModuleIDs, + [](const IndexedModuleID &A, const IndexedModuleID &B) { + return std::tie(A.ID.ModuleName, A.InputIndex) < + std::tie(B.ID.ModuleName, B.InputIndex); }); llvm::sort(Inputs, [](const InputDeps &A, const InputDeps &B) { @@ -287,20 +286,20 @@ class FullDeps { using namespace llvm::json; Array OutModules; - for (auto &&ModName : ModuleNames) { - auto &MD = Modules[ModName]; + for (auto &&ModID : ModuleIDs) { + auto &MD = Modules[ModID]; Object O{ - {"name", MD.ModuleName}, - {"context-hash", MD.ContextHash}, + {"name", MD.ID.ModuleName}, + {"context-hash", MD.ID.ContextHash}, {"file-deps", toJSONSorted(MD.FileDeps)}, {"clang-module-deps", toJSONSorted(MD.ClangModuleDeps)}, {"clang-modulemap-file", MD.ClangModuleMapFile}, {"command-line", FullCommandLine ? MD.getFullCommandLine( - [&](ClangModuleDep CMD) { return lookupPCMPath(CMD); }, - [&](ClangModuleDep CMD) -> const ModuleDeps & { - return lookupModuleDeps(CMD); + [&](ModuleID MID) { return lookupPCMPath(MID); }, + [&](ModuleID MID) -> const ModuleDeps & { + return lookupModuleDeps(MID); }) : MD.NonPathCommandLine}, }; @@ -328,33 +327,31 @@ class FullDeps { } private: - StringRef lookupPCMPath(ClangModuleDep CMD) { - return Modules[ContextModulePair{CMD.ContextHash, CMD.ModuleName, 0}] - .ImplicitModulePCMPath; + StringRef lookupPCMPath(ModuleID MID) { + return Modules[IndexedModuleID{MID, 0}].ImplicitModulePCMPath; } - const ModuleDeps &lookupModuleDeps(ClangModuleDep CMD) { - auto I = - Modules.find(ContextModulePair{CMD.ContextHash, CMD.ModuleName, 0}); + const ModuleDeps &lookupModuleDeps(ModuleID MID) { + auto I = Modules.find(IndexedModuleID{MID, 0}); assert(I != Modules.end()); return I->second; }; - struct ContextModulePair { - std::string ContextHash; - std::string ModuleName; + struct IndexedModuleID { + ModuleID ID; mutable size_t InputIndex; - bool operator==(const ContextModulePair &Other) const { - return ContextHash == Other.ContextHash && ModuleName == Other.ModuleName; + bool operator==(const IndexedModuleID &Other) const { + return ID.ModuleName == Other.ID.ModuleName && + ID.ContextHash == Other.ID.ContextHash; } }; - struct ContextModulePairHasher { - std::size_t operator()(const ContextModulePair &CMP) const { + struct IndexedModuleIDHasher { + std::size_t operator()(const IndexedModuleID &IMID) const { using llvm::hash_combine; - return hash_combine(CMP.ContextHash, CMP.ModuleName); + return hash_combine(IMID.ID.ModuleName, IMID.ID.ContextHash); } }; @@ -362,12 +359,12 @@ class FullDeps { std::string FileName; std::string ContextHash; std::vector FileDeps; - std::vector ModuleDeps; + std::vector ModuleDeps; std::vector AdditonalCommandLine; }; std::mutex Lock; - std::unordered_map + std::unordered_map Modules; std::vector Inputs; }; diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index c3a3aab066ac..ee3ffe3012d1 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -244,25 +244,28 @@ static void getCLEnvVarOptions(std::string &EnvValue, llvm::StringSaver &Saver, } static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) { - // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. - TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS"); - if (TheDriver.CCPrintOptions) - TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE"); - - // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE. - TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS"); - if (TheDriver.CCPrintHeaders) - TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE"); - - // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE. - TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS"); - if (TheDriver.CCLogDiagnostics) - TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE"); - - // Handle CC_PRINT_PROC_STAT and CC_PRINT_PROC_STAT_FILE. - TheDriver.CCPrintProcessStats = !!::getenv("CC_PRINT_PROC_STAT"); - if (TheDriver.CCPrintProcessStats) - TheDriver.CCPrintStatReportFilename = ::getenv("CC_PRINT_PROC_STAT_FILE"); + auto CheckEnvVar = [](const char *EnvOptSet, const char *EnvOptFile, + std::string &OptFile) { + bool OptSet = !!::getenv(EnvOptSet); + if (OptSet) { + if (const char *Var = ::getenv(EnvOptFile)) + OptFile = Var; + } + return OptSet; + }; + + TheDriver.CCPrintOptions = + CheckEnvVar("CC_PRINT_OPTIONS", "CC_PRINT_OPTIONS_FILE", + TheDriver.CCPrintOptionsFilename); + TheDriver.CCPrintHeaders = + CheckEnvVar("CC_PRINT_HEADERS", "CC_PRINT_HEADERS_FILE", + TheDriver.CCPrintHeadersFilename); + TheDriver.CCLogDiagnostics = + CheckEnvVar("CC_LOG_DIAGNOSTICS", "CC_LOG_DIAGNOSTICS_FILE", + TheDriver.CCLogDiagnosticsFilename); + TheDriver.CCPrintProcessStats = + CheckEnvVar("CC_PRINT_PROC_STAT", "CC_PRINT_PROC_STAT_FILE", + TheDriver.CCPrintStatReportFilename); } static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient, diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index e949b8513535..88b31e78feec 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2278,7 +2278,18 @@ void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {} void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {} -void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {} +void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) { + VisitOMPClauseList(C); +} + +void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause *C) { + Visitor->AddStmt(C->getInteropVar()); +} + +void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *C) { + if (C->getInteropVar()) + Visitor->AddStmt(C->getInteropVar()); +} void OMPClauseEnqueue::VisitOMPUnifiedAddressClause( const OMPUnifiedAddressClause *) {} @@ -5655,6 +5666,10 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { "OMPTargetTeamsDistributeParallelForSimdDirective"); case CXCursor_OMPTargetTeamsDistributeSimdDirective: return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective"); + case CXCursor_OMPInteropDirective: + return cxstring::createRef("OMPInteropDirective"); + case CXCursor_OMPDispatchDirective: + return cxstring::createRef("OMPDispatchDirective"); case CXCursor_OverloadCandidate: return cxstring::createRef("OverloadCandidate"); case CXCursor_TypeAliasTemplateDecl: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 0811b0bcdb88..d715d761f691 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -807,6 +807,12 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: K = CXCursor_OMPTargetTeamsDistributeSimdDirective; break; + case Stmt::OMPInteropDirectiveClass: + K = CXCursor_OMPInteropDirective; + break; + case Stmt::OMPDispatchDirectiveClass: + K = CXCursor_OMPDispatchDirective; + break; case Stmt::BuiltinBitCastExprClass: K = CXCursor_BuiltinBitCastExpr; } diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index 4b9620827002..f8c36df35607 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -1030,7 +1030,7 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) { // and we would return InvalidFieldName instead of Incomplete. // But this erroneous results does protects again a hidden assertion failure // in the RecordLayoutBuilder - if (Res.size() != 1) + if (!Res.isSingleResult()) return CXTypeLayoutError_InvalidFieldName; if (const FieldDecl *FD = dyn_cast(Res.front())) return Ctx.getFieldOffset(FD); diff --git a/clang/unittests/AST/ASTImporterObjCTest.cpp b/clang/unittests/AST/ASTImporterObjCTest.cpp new file mode 100644 index 000000000000..2d848dcf754e --- /dev/null +++ b/clang/unittests/AST/ASTImporterObjCTest.cpp @@ -0,0 +1,89 @@ +//===- unittest/AST/ASTImporterObjCTest.cpp -============================--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Tests for the correct import of AST nodes related to Objective-C and +// Objective-C++. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/DeclContextInternals.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "gtest/gtest.h" + +#include "ASTImporterFixtures.h" + +using namespace clang::ast_matchers; +using namespace clang; + +namespace { +struct ImportObjCDecl : ASTImporterOptionSpecificTestBase {}; +} // namespace + +TEST_P(ImportObjCDecl, ImplicitlyDeclareSelf) { + Decl *FromTU = getTuDecl(R"( + __attribute__((objc_root_class)) + @interface Root + @end + @interface C : Root + -(void)method; + @end + @implementation C + -(void)method {} + @end + )", + Lang_OBJCXX, "input.mm"); + auto *FromMethod = LastDeclMatcher().match( + FromTU, namedDecl(hasName("method"))); + ASSERT_TRUE(FromMethod); + auto ToMethod = Import(FromMethod, Lang_OBJCXX); + ASSERT_TRUE(ToMethod); + + // Both methods should have their implicit parameters. + EXPECT_TRUE(FromMethod->getSelfDecl() != nullptr); + EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr); +} + +TEST_P(ImportObjCDecl, ObjPropertyNameConflict) { + // Tests that properties that share the same name are correctly imported. + // This is only possible with one instance and one class property. + Decl *FromTU = getTuDecl(R"( + @interface DupProp{} + @property (class) int prop; + @property int prop; + @end + )", + Lang_OBJCXX, "input.mm"); + auto *FromClass = FirstDeclMatcher().match( + FromTU, namedDecl(hasName("DupProp"))); + auto ToClass = Import(FromClass, Lang_OBJCXX); + ASSERT_TRUE(ToClass); + // We should have one class and one instance property. + ASSERT_EQ( + 1, std::distance(ToClass->classprop_begin(), ToClass->classprop_end())); + ASSERT_EQ(1, + std::distance(ToClass->instprop_begin(), ToClass->instprop_end())); + for (clang::ObjCPropertyDecl *prop : ToClass->properties()) { + // All properties should have a getter and a setter. + ASSERT_TRUE(prop->getGetterMethodDecl()); + ASSERT_TRUE(prop->getSetterMethodDecl()); + // The getters/setters should be able to find the right associated property. + ASSERT_EQ(prop->getGetterMethodDecl()->findPropertyDecl(), prop); + ASSERT_EQ(prop->getSetterMethodDecl()->findPropertyDecl(), prop); + } +} + +static const auto ObjCTestArrayForRunOptions = + std::array, 2>{ + {std::vector{"-fno-objc-arc"}, + std::vector{"-fobjc-arc"}}}; + +const auto ObjCTestValuesForRunOptions = + ::testing::ValuesIn(ObjCTestArrayForRunOptions); + +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportObjCDecl, + ObjCTestValuesForRunOptions, ); diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 193523f2fc51..edbc648abbe1 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -246,6 +246,24 @@ TEST_P(ImportPath, CycleAfterCycle) { EXPECT_FALSE(path.hasCycleAtBack()); } +const internal::VariadicDynCastAllOfMatcher sourceLocExpr; + +AST_MATCHER_P(SourceLocExpr, hasBuiltinStr, StringRef, Str) { + return Node.getBuiltinStr() == Str; +} + +TEST_P(ImportExpr, ImportSourceLocExpr) { + MatchVerifier Verifier; + testImport("void declToImport() { (void)__builtin_FILE(); }", Lang_CXX03, "", + Lang_CXX03, Verifier, + functionDecl(hasDescendant( + sourceLocExpr(hasBuiltinStr("__builtin_FILE"))))); + testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03, + "", Lang_CXX03, Verifier, + functionDecl(hasDescendant( + sourceLocExpr(hasBuiltinStr("__builtin_COLUMN"))))); +} + TEST_P(ImportExpr, ImportStringLiteral) { MatchVerifier Verifier; testImport("void declToImport() { (void)\"foo\"; }", Lang_CXX03, "", @@ -613,6 +631,15 @@ TEST_P(ImportType, ImportDependentTemplateSpecialization) { fieldDecl(hasType(dependentTemplateSpecializationType()))))))); } +TEST_P(ImportType, ImportDeducedTemplateSpecialization) { + MatchVerifier Verifier; + testImport("template " + "class C { public: C(T); };" + "C declToImport(123);", + Lang_CXX17, "", Lang_CXX17, Verifier, + varDecl(hasType(deducedTemplateSpecializationType()))); +} + const internal::VariadicDynCastAllOfMatcher sizeOfPackExpr; @@ -735,6 +762,12 @@ TEST_P(ImportDecl, ImportRecordDeclInFunc) { has(declStmt(hasSingleDecl(varDecl(hasName("d"))))))))); } +TEST_P(ImportDecl, ImportedVarDeclPreservesThreadLocalStorage) { + MatchVerifier Verifier; + testImport("thread_local int declToImport;", Lang_CXX11, "", Lang_CXX11, + Verifier, varDecl(hasThreadStorageDuration())); +} + TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) { Decl *FromTU = getTuDecl("int declToImport() { " " struct data_t {int a;int b;};" @@ -2561,9 +2594,9 @@ TEST_P(ImportFriendFunctions, Lookup) { auto FromName = FromD->getDeclName(); auto *Class = FirstDeclMatcher().match(FromTU, ClassPattern); auto LookupRes = Class->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 0u); + ASSERT_TRUE(LookupRes.empty()); LookupRes = FromTU->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); } auto *ToD = cast(Import(FromD, Lang_CXX03)); @@ -2572,9 +2605,9 @@ TEST_P(ImportFriendFunctions, Lookup) { TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); auto *Class = FirstDeclMatcher().match(ToTU, ClassPattern); auto LookupRes = Class->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 0u); + EXPECT_TRUE(LookupRes.empty()); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, FunctionPattern), 1u); auto *To0 = FirstDeclMatcher().match(ToTU, FunctionPattern); @@ -2608,9 +2641,9 @@ TEST_P(ImportFriendFunctions, LookupWithProtoAfter) { auto *FromClass = FirstDeclMatcher().match(FromTU, ClassPattern); auto LookupRes = FromClass->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 0u); + ASSERT_TRUE(LookupRes.empty()); LookupRes = FromTU->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); auto *ToFriend = cast(Import(FromFriend, Lang_CXX03)); auto ToName = ToFriend->getDeclName(); @@ -2618,10 +2651,10 @@ TEST_P(ImportFriendFunctions, LookupWithProtoAfter) { TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); auto *ToClass = FirstDeclMatcher().match(ToTU, ClassPattern); LookupRes = ToClass->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 0u); + EXPECT_TRUE(LookupRes.empty()); LookupRes = ToTU->noload_lookup(ToName); // Test is disabled because this result is 2. - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); ASSERT_EQ(DeclCounter().match(ToTU, FunctionPattern), 2u); ToFriend = FirstDeclMatcher().match(ToTU, FunctionPattern); @@ -2652,9 +2685,9 @@ TEST_P(ImportFriendFunctions, LookupWithProtoBefore) { auto *FromClass = FirstDeclMatcher().match(FromTU, ClassPattern); auto LookupRes = FromClass->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 0u); + ASSERT_TRUE(LookupRes.empty()); LookupRes = FromTU->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); auto *ToNormal = cast(Import(FromNormal, Lang_CXX03)); auto ToName = ToNormal->getDeclName(); @@ -2662,9 +2695,9 @@ TEST_P(ImportFriendFunctions, LookupWithProtoBefore) { auto *ToClass = FirstDeclMatcher().match(ToTU, ClassPattern); LookupRes = ToClass->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 0u); + EXPECT_TRUE(LookupRes.empty()); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, FunctionPattern), 2u); ToNormal = FirstDeclMatcher().match(ToTU, FunctionPattern); @@ -2694,9 +2727,9 @@ TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) { ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); auto LookupRes = FromNormalTU->noload_lookup(FromNormalName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); LookupRes = FromFriendTU->noload_lookup(FromFriendName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); auto *ToNormalF = cast(Import(FromNormalF, Lang_CXX03)); TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); @@ -2704,12 +2737,12 @@ TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) { EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u); auto *ToFriendF = cast(Import(FromFriendF, Lang_CXX03)); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u); EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); @@ -3031,6 +3064,71 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) { EXPECT_EQ(ToF1, ToF2); } +TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) { + Decl *FromTU = getTuDecl("struct A { unsigned x : 3; };", Lang_CXX03); + auto *FromF = + FirstDeclMatcher().match(FromTU, fieldDecl(hasName("x"))); + + ASSERT_TRUE(FromF->isBitField()); + ASSERT_EQ(3u, FromF->getBitWidthValue(FromTU->getASTContext())); + auto *ToField = Import(FromF, Lang_CXX03); + auto *ToTU = ToField->getTranslationUnitDecl(); + + EXPECT_TRUE(ToField->isBitField()); + EXPECT_EQ(3u, ToField->getBitWidthValue(ToTU->getASTContext())); + + const auto *FromBT = FromF->getBitWidth()->getType()->getAs(); + const auto *ToBT = ToField->getBitWidth()->getType()->getAs(); + ASSERT_TRUE(FromBT); + ASSERT_EQ(BuiltinType::Int, FromBT->getKind()); + EXPECT_TRUE(ToBT); + EXPECT_EQ(BuiltinType::Int, ToBT->getKind()); +} + +struct ImportBlock : ASTImporterOptionSpecificTestBase {}; +TEST_P(ImportBlock, ImportBlocksAreUnsupported) { + const auto *Code = R"( + void test_block__capture_null() { + int *p = 0; + ^(){ + *p = 1; + }(); + })"; + Decl *FromTU = getTuDecl(Code, Lang_CXX03); + auto *FromBlock = FirstDeclMatcher().match(FromTU, blockDecl()); + ASSERT_TRUE(FromBlock); + + auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03); + + const auto ExpectUnsupportedConstructError = [](const ImportError &Error) { + EXPECT_EQ(ImportError::UnsupportedConstruct, Error.Error); + }; + llvm::handleAllErrors(ToBlockOrError.takeError(), + ExpectUnsupportedConstructError); +} + +TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl) { + const auto *Code = R"( + template struct Wrapper { + Wrapper(T Value = {}) {} + }; + template class Wrapper; + )"; + Decl *FromTU = getTuDecl(Code, Lang_CXX11); + auto *FromVar = FirstDeclMatcher().match( + FromTU, parmVarDecl(hasType(asString("int")))); + ASSERT_TRUE(FromVar); + ASSERT_TRUE(FromVar->hasUninstantiatedDefaultArg()); + ASSERT_TRUE(FromVar->getUninstantiatedDefaultArg()); + + const auto *ToVar = Import(FromVar, Lang_CXX11); + EXPECT_TRUE(ToVar); + EXPECT_TRUE(ToVar->hasUninstantiatedDefaultArg()); + EXPECT_TRUE(ToVar->getUninstantiatedDefaultArg()); + EXPECT_NE(FromVar->getUninstantiatedDefaultArg(), + ToVar->getUninstantiatedDefaultArg()); +} + TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) { Decl *ToF1; { @@ -4031,11 +4129,11 @@ TEST_P(DeclContextTest, ASSERT_TRUE(L.getAsDecl()); // Simulate the private function DeclContext::reconcileExternalVisibleStorage. - // The point here is to have a Vec with only one element, which is not the - // one we are going to delete from the DC later. + // We do not have a list with one element. L.setHasExternalDecls(); - ASSERT_TRUE(L.getAsVector()); - ASSERT_EQ(1u, L.getAsVector()->size()); + ASSERT_FALSE(L.getAsList()); + auto Results = L.getLookupResult(); + ASSERT_EQ(1u, std::distance(Results.begin(), Results.end())); // This asserts in the old implementation. DC->removeDecl(A0); @@ -5591,30 +5689,6 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) { 2u); } -TEST_P(ASTImporterOptionSpecificTestBase, ImplicitlyDeclareSelf) { - Decl *FromTU = getTuDecl(R"( - __attribute__((objc_root_class)) - @interface Root - @end - @interface C : Root - -(void)method; - @end - @implementation C - -(void)method {} - @end - )", - Lang_OBJCXX, "input.mm"); - auto *FromMethod = LastDeclMatcher().match( - FromTU, namedDecl(hasName("method"))); - ASSERT_TRUE(FromMethod); - auto ToMethod = Import(FromMethod, Lang_OBJCXX); - ASSERT_TRUE(ToMethod); - - // Both methods should have their implicit parameters. - EXPECT_TRUE(FromMethod->getSelfDecl() != nullptr); - EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr); -} - struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {}; TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) { @@ -6208,6 +6282,47 @@ TEST_P(ASTImporterOptionSpecificTestBase, EXPECT_TRUE(To2); } +TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) { + Decl *FromTU = getTuDecl( + R"( + void declToImport(int N) { + int VLA[N]; + [&VLA] {}; // FieldDecl inside the lambda. + } + )", + Lang_CXX14); + auto *FromFD = FirstDeclMatcher().match(FromTU, fieldDecl()); + ASSERT_TRUE(FromFD); + ASSERT_TRUE(FromFD->hasCapturedVLAType()); + + auto *ToFD = Import(FromFD, Lang_CXX14); + EXPECT_TRUE(ToFD); + EXPECT_TRUE(ToFD->hasCapturedVLAType()); + EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType()); +} + +TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) { + Decl *FromTU = getTuDecl( + R"( + template struct A { + enum tagname { enumerator }; + }; + template struct A; + )", + Lang_CXX03); + auto *FromD = FirstDeclMatcher().match( + FromTU, enumDecl(hasName("tagname"), + hasParent(classTemplateSpecializationDecl()))); + ASSERT_TRUE(FromD); + ASSERT_TRUE(FromD->getMemberSpecializationInfo()); + + auto *ToD = Import(FromD, Lang_CXX03); + EXPECT_TRUE(ToD); + EXPECT_TRUE(ToD->getMemberSpecializationInfo()); + EXPECT_EQ(FromD->getTemplateSpecializationKind(), + ToD->getTemplateSpecializationKind()); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); @@ -6222,6 +6337,11 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFixedPointExpr, std::vector{ "-ffixed-point"}), ); +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportBlock, + ExtendWithOptions(DefaultTestArrayForRunOptions, + std::vector{ + "-fblocks"}), ); + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportType, DefaultTestValuesForRunOptions, ); diff --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt index 2d5d0172afed..105bfd77df90 100644 --- a/clang/unittests/AST/CMakeLists.txt +++ b/clang/unittests/AST/CMakeLists.txt @@ -8,12 +8,12 @@ add_clang_unittest(ASTTests ASTContextParentMapTest.cpp ASTImporterFixtures.cpp ASTImporterTest.cpp + ASTImporterObjCTest.cpp ASTImporterGenericRedeclTest.cpp ASTImporterODRStrategiesTest.cpp ASTImporterVisibilityTest.cpp ASTTraverserTest.cpp ASTTypeTraitsTest.cpp - ASTTraverserTest.cpp ASTVectorTest.cpp CommentLexer.cpp CommentParser.cpp diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 9909cec2065c..bf4b0912c661 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -510,6 +510,83 @@ void foo() varDecl(hasName("lPtrDecay")))))))); } +TEST(Matcher, MatchesCoroutine) { + FileContentMappings M; + M.push_back(std::make_pair("/coro_header", R"cpp( +namespace std { +namespace experimental { + +template +struct void_t_imp { + using type = void; +}; +template +using void_t = typename void_t_imp::type; + +template +struct traits_sfinae_base {}; + +template +struct traits_sfinae_base> { + using promise_type = typename T::promise_type; +}; + +template +struct coroutine_traits : public traits_sfinae_base {}; +}} // namespace std::experimental +struct awaitable { + bool await_ready() noexcept; + template + void await_suspend(F) noexcept; + void await_resume() noexcept; +} a; +struct promise { + void get_return_object(); + awaitable initial_suspend(); + awaitable final_suspend() noexcept; + awaitable yield_value(int); // expected-note 2{{candidate}} + void return_value(int); // expected-note 2{{here}} + void unhandled_exception(); +}; +template +struct std::experimental::coroutine_traits { using promise_type = promise; }; +namespace std { +namespace experimental { +template +struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; +}; +}} // namespace std::experimental +)cpp")); + StringRef CoReturnCode = R"cpp( +#include +void check_match_co_return() { + co_return 1; +} +)cpp"; + EXPECT_TRUE(matchesConditionally(CoReturnCode, + coreturnStmt(isExpansionInMainFile()), + true, {"-std=c++20", "-I/"}, M)); + StringRef CoAwaitCode = R"cpp( +#include +void check_match_co_await() { + co_await a; +} +)cpp"; + EXPECT_TRUE(matchesConditionally(CoAwaitCode, + coawaitExpr(isExpansionInMainFile()), + true, {"-std=c++20", "-I/"}, M)); + StringRef CoYieldCode = R"cpp( +#include +void check_match_co_yield() { + co_yield 1.0; +} +)cpp"; + EXPECT_TRUE(matchesConditionally(CoYieldCode, + coyieldExpr(isExpansionInMainFile()), + true, {"-std=c++20", "-I/"}, M)); +} + TEST(Matcher, isClassMessage) { EXPECT_TRUE(matchesObjC( "@interface NSString +(NSString *) stringWithFormat; @end " diff --git a/clang/unittests/CMakeLists.txt b/clang/unittests/CMakeLists.txt index bb635dfff991..4e0873955700 100644 --- a/clang/unittests/CMakeLists.txt +++ b/clang/unittests/CMakeLists.txt @@ -29,6 +29,7 @@ add_subdirectory(ASTMatchers) add_subdirectory(AST) add_subdirectory(CrossTU) add_subdirectory(Tooling) +add_subdirectory(Introspection) add_subdirectory(Format) add_subdirectory(Frontend) add_subdirectory(Rewrite) diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp index 35060563ab97..87f476c98dc9 100644 --- a/clang/unittests/Driver/ToolChainTest.cpp +++ b/clang/unittests/Driver/ToolChainTest.cpp @@ -31,11 +31,8 @@ TEST(ToolChainTest, VFSGCCInstallation) { IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); struct TestDiagnosticConsumer : public DiagnosticConsumer {}; - DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); IntrusiveRefCntPtr InMemoryFileSystem( new llvm::vfs::InMemoryFileSystem); - Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags, - "clang LLVM compiler", InMemoryFileSystem); const char *EmptyFiles[] = { "foo.cpp", @@ -53,31 +50,78 @@ TEST(ToolChainTest, VFSGCCInstallation) { "/usr/include/arm-linux-gnueabi/.keep", "/usr/include/arm-linux-gnueabihf/.keep", "/lib/arm-linux-gnueabi/.keep", - "/lib/arm-linux-gnueabihf/.keep"}; + "/lib/arm-linux-gnueabihf/.keep", + + "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtbegin.o", + "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtend.o", + "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtbegin.o", + "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtend.o", + "/sysroot/usr/lib/arm-linux-gnueabi/crt1.o", + "/sysroot/usr/lib/arm-linux-gnueabi/crti.o", + "/sysroot/usr/lib/arm-linux-gnueabi/crtn.o", + "/sysroot/usr/lib/arm-linux-gnueabihf/crt1.o", + "/sysroot/usr/lib/arm-linux-gnueabihf/crti.o", + "/sysroot/usr/lib/arm-linux-gnueabihf/crtn.o", + "/sysroot/usr/include/arm-linux-gnueabi/.keep", + "/sysroot/usr/include/arm-linux-gnueabihf/.keep", + "/sysroot/lib/arm-linux-gnueabi/.keep", + "/sysroot/lib/arm-linux-gnueabihf/.keep", + }; for (const char *Path : EmptyFiles) InMemoryFileSystem->addFile(Path, 0, llvm::MemoryBuffer::getMemBuffer("\n")); - std::unique_ptr C(TheDriver.BuildCompilation( - {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=", "foo.cpp"})); - EXPECT_TRUE(C); - - std::string S; { - llvm::raw_string_ostream OS(S); - C->getDefaultToolChain().printVerboseInfo(OS); + DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); + Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags, + "clang LLVM compiler", InMemoryFileSystem); + std::unique_ptr C(TheDriver.BuildCompilation( + {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=", "foo.cpp"})); + ASSERT_TRUE(C); + std::string S; + { + llvm::raw_string_ostream OS(S); + C->getDefaultToolChain().printVerboseInfo(OS); + } +#if _WIN32 + std::replace(S.begin(), S.end(), '\\', '/'); +#endif + EXPECT_EQ( + "Found candidate GCC installation: " + "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n" + "Selected GCC installation: /usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n" + "Candidate multilib: .;@m32\n" + "Selected multilib: .;@m32\n", + S); } + + { + DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); + Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags, + "clang LLVM compiler", InMemoryFileSystem); + std::unique_ptr C(TheDriver.BuildCompilation( + {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=/sysroot", + "foo.cpp"})); + ASSERT_TRUE(C); + std::string S; + { + llvm::raw_string_ostream OS(S); + C->getDefaultToolChain().printVerboseInfo(OS); + } #if _WIN32 - std::replace(S.begin(), S.end(), '\\', '/'); + std::replace(S.begin(), S.end(), '\\', '/'); #endif - EXPECT_EQ( - "Found candidate GCC installation: " - "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n" - "Selected GCC installation: /usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n" - "Candidate multilib: .;@m32\n" - "Selected multilib: .;@m32\n", - S); + // Test that 4.5.3 from --sysroot is not overridden by 4.6.3 (larger + // version) from /usr. + EXPECT_EQ("Found candidate GCC installation: " + "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n" + "Selected GCC installation: " + "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n" + "Candidate multilib: .;@m32\n" + "Selected multilib: .;@m32\n", + S); + } } TEST(ToolChainTest, VFSGCCInstallationRelativeDir) { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 429621e0ca1c..9e5e67d3b97d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -12731,6 +12731,27 @@ TEST_F(FormatTest, ConfigurableSpaceAroundPointerQualifiers) { verifyQualifierSpaces("void * const *x = NULL;", PAS_Right, SAPQ_Both); verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_Both); + verifyQualifierSpaces("Foo::operator void const*();", PAS_Left, SAPQ_Default); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, + SAPQ_Default); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, + SAPQ_Default); + + verifyQualifierSpaces("Foo::operator void const*();", PAS_Left, SAPQ_Before); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, + SAPQ_Before); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, + SAPQ_Before); + + verifyQualifierSpaces("Foo::operator void const *();", PAS_Left, SAPQ_After); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, SAPQ_After); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, + SAPQ_After); + + verifyQualifierSpaces("Foo::operator void const *();", PAS_Left, SAPQ_Both); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, SAPQ_Both); + verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, SAPQ_Both); + #undef verifyQualifierSpaces FormatStyle Spaces = getLLVMStyle(); @@ -14297,6 +14318,102 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { Alignment); } +TEST_F(FormatTest, AlignWithLineBreaks) { + auto Style = getLLVMStyleWithColumns(120); + + EXPECT_EQ(Style.AlignConsecutiveAssignments, FormatStyle::ACS_None); + EXPECT_EQ(Style.AlignConsecutiveDeclarations, FormatStyle::ACS_None); + verifyFormat("void foo() {\n" + " int myVar = 5;\n" + " double x = 3.14;\n" + " auto str = \"Hello \"\n" + " \"World\";\n" + " auto s = \"Hello \"\n" + " \"Again\";\n" + "}", + Style); + + // clang-format off + verifyFormat("void foo() {\n" + " const int capacityBefore = Entries.capacity();\n" + " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + "}", + Style); + // clang-format on + + Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive; + verifyFormat("void foo() {\n" + " int myVar = 5;\n" + " double x = 3.14;\n" + " auto str = \"Hello \"\n" + " \"World\";\n" + " auto s = \"Hello \"\n" + " \"Again\";\n" + "}", + Style); + + // clang-format off + verifyFormat("void foo() {\n" + " const int capacityBefore = Entries.capacity();\n" + " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + "}", + Style); + // clang-format on + + Style.AlignConsecutiveAssignments = FormatStyle::ACS_None; + Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; + verifyFormat("void foo() {\n" + " int myVar = 5;\n" + " double x = 3.14;\n" + " auto str = \"Hello \"\n" + " \"World\";\n" + " auto s = \"Hello \"\n" + " \"Again\";\n" + "}", + Style); + + // clang-format off + verifyFormat("void foo() {\n" + " const int capacityBefore = Entries.capacity();\n" + " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + "}", + Style); + // clang-format on + + Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive; + Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; + + verifyFormat("void foo() {\n" + " int myVar = 5;\n" + " double x = 3.14;\n" + " auto str = \"Hello \"\n" + " \"World\";\n" + " auto s = \"Hello \"\n" + " \"Again\";\n" + "}", + Style); + + // clang-format off + verifyFormat("void foo() {\n" + " const int capacityBefore = Entries.capacity();\n" + " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" + " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" + "}", + Style); + // clang-format on +} + TEST_F(FormatTest, LinuxBraceBreaking) { FormatStyle LinuxBraceStyle = getLLVMStyle(); LinuxBraceStyle.BreakBeforeBraces = FormatStyle::BS_Linux; @@ -18639,6 +18756,10 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator void **();", Style); verifyFormat("Foo::operator void *&();", Style); verifyFormat("Foo::operator void *&&();", Style); + verifyFormat("Foo::operator void const *();", Style); + verifyFormat("Foo::operator void const **();", Style); + verifyFormat("Foo::operator void const *&();", Style); + verifyFormat("Foo::operator void const *&&();", Style); verifyFormat("Foo::operator()(void *);", Style); verifyFormat("Foo::operator*(void *);", Style); verifyFormat("Foo::operator*();", Style); @@ -18660,6 +18781,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator&();", Style); verifyFormat("Foo::operator void &();", Style); + verifyFormat("Foo::operator void const &();", Style); verifyFormat("Foo::operator()(void &);", Style); verifyFormat("Foo::operator&(void &);", Style); verifyFormat("Foo::operator&();", Style); @@ -18668,6 +18790,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator&&();", Style); verifyFormat("Foo::operator**();", Style); verifyFormat("Foo::operator void &&();", Style); + verifyFormat("Foo::operator void const &&();", Style); verifyFormat("Foo::operator()(void &&);", Style); verifyFormat("Foo::operator&&(void &&);", Style); verifyFormat("Foo::operator&&();", Style); @@ -18688,6 +18811,11 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator void*();", Style); verifyFormat("Foo::operator void**();", Style); verifyFormat("Foo::operator void*&();", Style); + verifyFormat("Foo::operator void*&&();", Style); + verifyFormat("Foo::operator void const*();", Style); + verifyFormat("Foo::operator void const**();", Style); + verifyFormat("Foo::operator void const*&();", Style); + verifyFormat("Foo::operator void const*&&();", Style); verifyFormat("Foo::operator/*comment*/ void*();", Style); verifyFormat("Foo::operator/*a*/ const /*b*/ void*();", Style); verifyFormat("Foo::operator/*a*/ volatile /*b*/ void*();", Style); @@ -18709,6 +18837,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator&();", Style); verifyFormat("Foo::operator void&();", Style); + verifyFormat("Foo::operator void const&();", Style); verifyFormat("Foo::operator/*comment*/ void&();", Style); verifyFormat("Foo::operator/*a*/ const /*b*/ void&();", Style); verifyFormat("Foo::operator/*a*/ volatile /*b*/ void&();", Style); @@ -18719,6 +18848,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator&&();", Style); verifyFormat("Foo::operator void&&();", Style); + verifyFormat("Foo::operator void const&&();", Style); verifyFormat("Foo::operator/*comment*/ void&&();", Style); verifyFormat("Foo::operator/*a*/ const /*b*/ void&&();", Style); verifyFormat("Foo::operator/*a*/ volatile /*b*/ void&&();", Style); @@ -18754,6 +18884,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator&();", Style); verifyFormat("Foo::operator void &();", Style); + verifyFormat("Foo::operator void const &();", Style); verifyFormat("Foo::operator()(void &);", Style); verifyFormat("Foo::operator&(void &);", Style); verifyFormat("Foo::operator&();", Style); @@ -18761,6 +18892,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("Foo::operator&&();", Style); verifyFormat("Foo::operator void &&();", Style); + verifyFormat("Foo::operator void const &&();", Style); verifyFormat("Foo::operator()(void &&);", Style); verifyFormat("Foo::operator&&(void &&);", Style); verifyFormat("Foo::operator&&();", Style); diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 8963c9f19024..91a98bf64c5c 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -276,6 +276,12 @@ TEST_F(FormatTestJS, UnderstandsJavaScriptOperators) { // ES6 spread operator. verifyFormat("someFunction(...a);"); verifyFormat("var x = [1, ...a, 2];"); + + // "- -1" is legal JS syntax, but must not collapse into "--". + verifyFormat("- -1;", " - -1;"); + verifyFormat("-- -1;", " -- -1;"); + verifyFormat("+ +1;", " + +1;"); + verifyFormat("++ +1;", " ++ +1;"); } TEST_F(FormatTestJS, UnderstandsAmpAmp) { diff --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp index c33f93bcf99d..aa27f6ecf93b 100644 --- a/clang/unittests/Format/FormatTestObjC.cpp +++ b/clang/unittests/Format/FormatTestObjC.cpp @@ -977,6 +977,19 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) { " performSelectorOnMainThread:@selector(loadAccessories)\n" " withObject:nil\n" " waitUntilDone:false];"); + + // The appropriate indentation is used after a block statement. + Style.ContinuationIndentWidth = 4; + verifyFormat( + "void aaaaaaaaaaaaaaaaaaaaa(int c) {\n" + " if (c) {\n" + " f();\n" + " }\n" + " [dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\n" + " eeeeeeeeeeeeeeeeeeeeeeeeeeeee:^(fffffffffffffff gggggggg) {\n" + " f(SSSSS, c);\n" + " }];\n" + "}"); } TEST_F(FormatTestObjC, ObjCAt) { diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp index 89e024dcb78b..b846e6ead28c 100644 --- a/clang/unittests/Frontend/CompilerInvocationTest.cpp +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -516,7 +516,8 @@ TEST_F(CommandLineTest, ConditionalParsingIfFalseFlagNotPresent) { CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); ASSERT_FALSE(Diags->hasErrorOccurred()); - ASSERT_FALSE(Invocation.getLangOpts()->SYCL); + ASSERT_FALSE(Invocation.getLangOpts()->SYCLIsDevice); + ASSERT_FALSE(Invocation.getLangOpts()->SYCLIsHost); ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_None); Invocation.generateCC1CommandLine(GeneratedArgs, *this); @@ -531,42 +532,42 @@ TEST_F(CommandLineTest, ConditionalParsingIfFalseFlagPresent) { CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); ASSERT_FALSE(Diags->hasErrorOccurred()); - ASSERT_FALSE(Invocation.getLangOpts()->SYCL); + ASSERT_FALSE(Invocation.getLangOpts()->SYCLIsDevice); + ASSERT_FALSE(Invocation.getLangOpts()->SYCLIsHost); ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_None); Invocation.generateCC1CommandLine(GeneratedArgs, *this); - ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl")))); + ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-device")))); + ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-host")))); ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std=")))); } TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresent) { - const char *Args[] = {"-fsycl"}; + const char *Args[] = {"-fsycl-is-host"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); ASSERT_FALSE(Diags->hasErrorOccurred()); - ASSERT_TRUE(Invocation.getLangOpts()->SYCL); ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_None); Invocation.generateCC1CommandLine(GeneratedArgs, *this); - ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl"))); + ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-host"))); ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std=")))); } TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagPresent) { - const char *Args[] = {"-fsycl", "-sycl-std=2017"}; + const char *Args[] = {"-fsycl-is-device", "-sycl-std=2017"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); ASSERT_FALSE(Diags->hasErrorOccurred()); - ASSERT_TRUE(Invocation.getLangOpts()->SYCL); ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_2017); Invocation.generateCC1CommandLine(GeneratedArgs, *this); - ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl"))); + ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-device"))); ASSERT_THAT(GeneratedArgs, Contains(StrEq("-sycl-std=2017"))); } diff --git a/clang/unittests/Introspection/CMakeLists.txt b/clang/unittests/Introspection/CMakeLists.txt new file mode 100644 index 000000000000..f9c55c5edfc4 --- /dev/null +++ b/clang/unittests/Introspection/CMakeLists.txt @@ -0,0 +1,22 @@ +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support + ) + +add_clang_unittest(IntrospectionTests + IntrospectionTest.cpp + ) + +clang_target_link_libraries(IntrospectionTests + PRIVATE + clangAST + clangASTMatchers + clangTooling + clangBasic + clangSerialization + clangFrontend + ) +target_link_libraries(IntrospectionTests + PRIVATE + LLVMTestingSupport +) diff --git a/clang/unittests/Introspection/IntrospectionTest.cpp b/clang/unittests/Introspection/IntrospectionTest.cpp new file mode 100644 index 000000000000..5e32d7d593c7 --- /dev/null +++ b/clang/unittests/Introspection/IntrospectionTest.cpp @@ -0,0 +1,147 @@ +//===- unittest/Introspection/IntrospectionTest.cpp ----------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Tests for AST location API introspection. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/NodeIntrospection.h" +#include "clang/Tooling/Tooling.h" +#include "gmock/gmock-matchers.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace clang; +using namespace clang::ast_matchers; +using namespace clang::tooling; + +using ::testing::Pair; +using ::testing::UnorderedElementsAre; + +template +std::map +FormatExpected(const MapType &Accessors) { + std::map Result; + llvm::transform(Accessors, + std::inserter(Result, Result.end()), + [](const auto &Accessor) { + return std::make_pair( + LocationCallFormatterCpp::format(Accessor.second.get()), + Accessor.first); + }); + return Result; +} + +#define STRING_LOCATION_PAIR(INSTANCE, LOC) Pair(#LOC, INSTANCE->LOC) + +TEST(Introspection, SourceLocations_Stmt) { + auto AST = buildASTFromCode("void foo() {} void bar() { foo(); }", "foo.cpp", + std::make_shared()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant( + callExpr(callee(functionDecl(hasName("foo")))).bind("fooCall"))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + auto *FooCall = BoundNodes[0].getNodeAs("fooCall"); + + auto Result = NodeIntrospection::GetLocations(FooCall); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) + { + return; + } + + auto ExpectedLocations = + FormatExpected(Result.LocationAccessors); + + EXPECT_THAT( + ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(FooCall, getBeginLoc()), + STRING_LOCATION_PAIR(FooCall, getEndLoc()), + STRING_LOCATION_PAIR(FooCall, getExprLoc()), + STRING_LOCATION_PAIR(FooCall, getRParenLoc()))); + + auto ExpectedRanges = FormatExpected(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( + FooCall, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_Decl) { + auto AST = + buildASTFromCode(R"cpp( +namespace ns1 { +namespace ns2 { +template struct Foo {}; +template struct Bar { + struct Nested { + template + Foo method(int i, bool b) const noexcept(true); + }; +}; +} // namespace ns2 +} // namespace ns1 + +template +template +ns1::ns2::Foo ns1::ns2::Bar::Nested::method(int i, bool b) const + noexcept(true) {} +)cpp", + "foo.cpp", std::make_shared()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant( + cxxMethodDecl(hasName("method")).bind("method"))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *MethodDecl = BoundNodes[0].getNodeAs("method"); + + auto Result = NodeIntrospection::GetLocations(MethodDecl); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre( + STRING_LOCATION_PAIR(MethodDecl, getBeginLoc()), + STRING_LOCATION_PAIR(MethodDecl, getBodyRBrace()), + STRING_LOCATION_PAIR(MethodDecl, getEllipsisLoc()), + STRING_LOCATION_PAIR(MethodDecl, getInnerLocStart()), + STRING_LOCATION_PAIR(MethodDecl, getLocation()), + STRING_LOCATION_PAIR(MethodDecl, getOuterLocStart()), + STRING_LOCATION_PAIR(MethodDecl, getPointOfInstantiation()), + STRING_LOCATION_PAIR(MethodDecl, getTypeSpecEndLoc()), + STRING_LOCATION_PAIR(MethodDecl, getTypeSpecStartLoc()), + STRING_LOCATION_PAIR(MethodDecl, getEndLoc()))); + + auto ExpectedRanges = FormatExpected(Result.RangeAccessors); + + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(MethodDecl, getExceptionSpecSourceRange()), + STRING_LOCATION_PAIR(MethodDecl, getParametersSourceRange()), + STRING_LOCATION_PAIR(MethodDecl, getReturnTypeSourceRange()), + STRING_LOCATION_PAIR(MethodDecl, getSourceRange()))); +} diff --git a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp index 83b4fac15a19..5be2ee3fc520 100644 --- a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp +++ b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp @@ -11,120 +11,339 @@ #include "clang/Basic/SourceManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" +using namespace clang; +using namespace ento; + namespace clang { namespace ento { -namespace { -// TestCase contains to lists of ranges. -// Original one has to be negated. -// Expected one has to be compared to negated original range. -template struct TestCase { - RangeSet original; - RangeSet expected; - - TestCase(BasicValueFactory &BVF, RangeSet::Factory &F, - const std::initializer_list &originalList, - const std::initializer_list &expectedList) - : original(createRangeSetFromList(BVF, F, originalList)), - expected(createRangeSetFromList(BVF, F, expectedList)) {} - -private: - RangeSet createRangeSetFromList(BasicValueFactory &BVF, RangeSet::Factory &F, - const std::initializer_list rangeList) { - llvm::APSInt from(sizeof(T) * 8, std::is_unsigned::value); - llvm::APSInt to = from; - RangeSet rangeSet = F.getEmptySet(); - for (auto it = rangeList.begin(); it != rangeList.end(); it += 2) { - from = *it; - to = *(it + 1); - rangeSet = rangeSet.addRange( - F, RangeSet(F, BVF.getValue(from), BVF.getValue(to))); - } - return rangeSet; - } +template static std::string toString(const RangeOrSet &Obj) { + std::string ObjRepresentation; + llvm::raw_string_ostream SS(ObjRepresentation); + Obj.dump(SS); + return SS.str(); +} +LLVM_ATTRIBUTE_UNUSED static std::string toString(const llvm::APSInt &Point) { + return Point.toString(10); +} +// We need it here for better fail diagnostics from gtest. +LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS, + const RangeSet &Set) { + return OS << toString(Set); +} - void printNegate(const TestCase &TestCase) { - TestCase.original.print(llvm::dbgs()); - llvm::dbgs() << " => "; - TestCase.expected.print(llvm::dbgs()); - } -}; +} // namespace ento +} // namespace clang -class RangeSetTest : public testing::Test { -protected: +namespace { + +template class RangeSetTest : public testing::Test { +public: // Init block std::unique_ptr AST = tooling::buildASTFromCode("struct foo;"); - ASTContext &context = AST->getASTContext(); - llvm::BumpPtrAllocator alloc; - BasicValueFactory BVF{context, alloc}; - RangeSet::Factory F; + ASTContext &Context = AST->getASTContext(); + llvm::BumpPtrAllocator Arena; + BasicValueFactory BVF{Context, Arena}; + RangeSet::Factory F{BVF}; // End init block - template void checkNegate() { - using type = T; - - // Use next values of the range {MIN, A, B, MID, C, D, MAX}. - - // MID is a value in the middle of the range - // which unary minus does not affect on, - // e.g. int8/int32(0), uint8(128), uint32(2147483648). - - constexpr type MIN = std::numeric_limits::min(); - constexpr type MAX = std::numeric_limits::max(); - constexpr type MID = std::is_signed::value - ? 0 - : ~(static_cast(-1) / static_cast(2)); - constexpr type A = MID - static_cast(42 + 42); - constexpr type B = MID - static_cast(42); - constexpr type C = -B; - constexpr type D = -A; - - static_assert(MIN < A && A < B && B < MID && MID < C && C < D && D < MAX, - "Values shall be in an ascending order"); - - // Left {[x, y], [x, y]} is what shall be negated. - // Right {[x, y], [x, y]} is what shall be compared to a negation result. - TestCase cases[] = { - {BVF, F, {MIN, A}, {MIN, MIN, D, MAX}}, - {BVF, F, {MIN, C}, {MIN, MIN, B, MAX}}, - {BVF, F, {MIN, MID}, {MIN, MIN, MID, MAX}}, - {BVF, F, {MIN, MAX}, {MIN, MAX}}, - {BVF, F, {A, D}, {A, D}}, - {BVF, F, {A, B}, {C, D}}, - {BVF, F, {MIN, A, D, MAX}, {MIN, A, D, MAX}}, - {BVF, F, {MIN, B, MID, D}, {MIN, MIN, A, MID, C, MAX}}, - {BVF, F, {MIN, MID, C, D}, {MIN, MIN, A, B, MID, MAX}}, - {BVF, F, {MIN, MID, C, MAX}, {MIN, B, MID, MAX}}, - {BVF, F, {A, MID, D, MAX}, {MIN + 1, A, MID, D}}, - {BVF, F, {A, A}, {D, D}}, - {BVF, F, {MID, MID}, {MID, MID}}, - {BVF, F, {MAX, MAX}, {MIN + 1, MIN + 1}}, - }; - - for (const auto &c : cases) { - // Negate original and check with expected. - RangeSet negatedFromOriginal = c.original.Negate(BVF, F); - EXPECT_EQ(negatedFromOriginal, c.expected); - // Negate negated back and check with original. - RangeSet negatedBackward = negatedFromOriginal.Negate(BVF, F); - EXPECT_EQ(negatedBackward, c.original); + using Self = RangeSetTest; + using RawRange = std::pair; + using RawRangeSet = std::initializer_list; + + static constexpr BaseType getMin() { + return std::numeric_limits::min(); + } + static constexpr BaseType getMax() { + return std::numeric_limits::max(); + } + static constexpr BaseType getMid() { + return isSigned() ? 0 : ~(fromInt(-1) / fromInt(2)); + } + + static constexpr bool isSigned() { return std::is_signed::value; } + static constexpr BaseType fromInt(int X) { return static_cast(X); } + + static llvm::APSInt Base; + const llvm::APSInt &from(BaseType X) { + llvm::APSInt Dummy = Base; + Dummy = X; + return BVF.getValue(Dummy); + } + + Range from(const RawRange &Init) { + return Range(from(Init.first), from(Init.second)); + } + + RangeSet from(const RawRangeSet &Init) { + RangeSet RangeSet = F.getEmptySet(); + for (const auto &Raw : Init) { + RangeSet = F.add(RangeSet, from(Raw)); } + return RangeSet; + } + + template + void wrap(F ActualFunction, RawArgTypes &&... Args) { + (this->*ActualFunction)(from(std::forward(Args))...); + } + + void checkNegateImpl(RangeSet Original, RangeSet Expected) { + RangeSet NegatedFromOriginal = F.negate(Original); + EXPECT_EQ(NegatedFromOriginal, Expected); + // Negate negated back and check with original. + RangeSet NegatedBackward = F.negate(NegatedFromOriginal); + EXPECT_EQ(NegatedBackward, Original); + } + + void checkNegate(RawRangeSet RawOriginal, RawRangeSet RawExpected) { + wrap(&Self::checkNegateImpl, RawOriginal, RawExpected); + } + + template + void checkIntersectImpl(RangeSet LHS, PointOrSet RHS, RangeSet Expected) { + RangeSet Result = F.intersect(LHS, RHS); + EXPECT_EQ(Result, Expected) + << "while intersecting " << toString(LHS) << " and " << toString(RHS); + } + + void checkIntersectRangeImpl(RangeSet LHS, const llvm::APSInt &Lower, + const llvm::APSInt &Upper, RangeSet Expected) { + RangeSet Result = F.intersect(LHS, Lower, Upper); + EXPECT_EQ(Result, Expected) + << "while intersecting " << toString(LHS) << " and [" << toString(Lower) + << ", " << toString(Upper) << "]"; + } + + void checkIntersect(RawRangeSet RawLHS, RawRangeSet RawRHS, + RawRangeSet RawExpected) { + wrap(&Self::checkIntersectImpl, RawLHS, RawRHS, RawExpected); + } + + void checkIntersect(RawRangeSet RawLHS, BaseType RawRHS, + RawRangeSet RawExpected) { + wrap(&Self::checkIntersectImpl, RawLHS, RawRHS, + RawExpected); + } + + void checkIntersect(RawRangeSet RawLHS, BaseType RawLower, BaseType RawUpper, + RawRangeSet RawExpected) { + wrap(&Self::checkIntersectRangeImpl, RawLHS, RawLower, RawUpper, + RawExpected); + } + + void checkContainsImpl(RangeSet LHS, const llvm::APSInt &RHS, bool Expected) { + bool Result = LHS.contains(RHS); + EXPECT_EQ(Result, Expected) + << toString(LHS) << (Result ? " contains " : " doesn't contain ") + << toString(RHS); + } + + void checkContains(RawRangeSet RawLHS, BaseType RawRHS, bool Expected) { + checkContainsImpl(from(RawLHS), from(RawRHS), Expected); + } + + template + void checkAddImpl(RangeSet LHS, RHSType RHS, RangeSet Expected) { + RangeSet Result = F.add(LHS, RHS); + EXPECT_EQ(Result, Expected) + << "while adding " << toString(LHS) << " and " << toString(RHS); + } + + void checkAdd(RawRangeSet RawLHS, RawRange RawRHS, RawRangeSet RawExpected) { + wrap(&Self::checkAddImpl, RawLHS, RawRHS, RawExpected); + } + + void checkAdd(RawRangeSet RawLHS, RawRangeSet RawRHS, + RawRangeSet RawExpected) { + wrap(&Self::checkAddImpl, RawRHS, RawLHS, RawExpected); + } + + void checkAdd(RawRangeSet RawLHS, BaseType RawRHS, RawRangeSet RawExpected) { + wrap(&Self::checkAddImpl, RawLHS, RawRHS, + RawExpected); + } + + void checkDeleteImpl(const llvm::APSInt &Point, RangeSet From, + RangeSet Expected) { + RangeSet Result = F.deletePoint(From, Point); + EXPECT_EQ(Result, Expected) + << "while deleting " << toString(Point) << " from " << toString(From); + } + + void checkDelete(BaseType Point, RawRangeSet RawFrom, + RawRangeSet RawExpected) { + wrap(&Self::checkDeleteImpl, Point, RawFrom, RawExpected); } }; -TEST_F(RangeSetTest, RangeSetNegateTest) { - checkNegate(); - checkNegate(); - checkNegate(); - checkNegate(); - checkNegate(); - checkNegate(); - checkNegate(); - checkNegate(); +} // namespace + +template +llvm::APSInt RangeSetTest::Base{sizeof(BaseType) * 8, !isSigned()}; + +using IntTypes = ::testing::Types; +TYPED_TEST_CASE(RangeSetTest, IntTypes); + +TYPED_TEST(RangeSetTest, RangeSetNegateTest) { + // Use next values of the range {MIN, A, B, MID, C, D, MAX}. + + constexpr TypeParam MIN = TestFixture::getMin(); + constexpr TypeParam MAX = TestFixture::getMax(); + // MID is a value in the middle of the range + // which unary minus does not affect on, + // e.g. int8/int32(0), uint8(128), uint32(2147483648). + constexpr TypeParam MID = TestFixture::getMid(); + constexpr TypeParam A = MID - TestFixture::fromInt(42 + 42); + constexpr TypeParam B = MID - TestFixture::fromInt(42); + constexpr TypeParam C = -B; + constexpr TypeParam D = -A; + + static_assert(MIN < A && A < B && B < MID && MID < C && C < D && D < MAX, + "Values shall be in an ascending order"); + + this->checkNegate({{MIN, A}}, {{MIN, MIN}, {D, MAX}}); + this->checkNegate({{MIN, C}}, {{MIN, MIN}, {B, MAX}}); + this->checkNegate({{MIN, MID}}, {{MIN, MIN}, {MID, MAX}}); + this->checkNegate({{MIN, MAX}}, {{MIN, MAX}}); + this->checkNegate({{A, D}}, {{A, D}}); + this->checkNegate({{A, B}}, {{C, D}}); + this->checkNegate({{MIN, A}, {D, MAX}}, {{MIN, A}, {D, MAX}}); + this->checkNegate({{MIN, B}, {MID, D}}, {{MIN, MIN}, {A, MID}, {C, MAX}}); + this->checkNegate({{MIN, MID}, {C, D}}, {{MIN, MIN}, {A, B}, {MID, MAX}}); + this->checkNegate({{MIN, MID}, {C, MAX}}, {{MIN, B}, {MID, MAX}}); + this->checkNegate({{A, MID}, {D, MAX}}, {{MIN + 1, A}, {MID, D}}); + this->checkNegate({{A, A}}, {{D, D}}); + this->checkNegate({{MID, MID}}, {{MID, MID}}); + this->checkNegate({{MAX, MAX}}, {{MIN + 1, MIN + 1}}); } -} // namespace -} // namespace ento -} // namespace clang +TYPED_TEST(RangeSetTest, RangeSetPointIntersectTest) { + // Check that we can correctly intersect empty sets. + this->checkIntersect({}, 42, {}); + // Check that intersection with itself produces the same set. + this->checkIntersect({{42, 42}}, 42, {{42, 42}}); + // Check more general cases. + this->checkIntersect({{0, 10}, {20, 30}, {30, 40}, {50, 60}}, 42, {}); + this->checkIntersect({{0, 10}, {20, 30}, {30, 60}}, 42, {{42, 42}}); +} + +TYPED_TEST(RangeSetTest, RangeSetRangeIntersectTest) { + constexpr TypeParam MIN = TestFixture::getMin(); + constexpr TypeParam MAX = TestFixture::getMax(); + + // Check that we can correctly intersect empty sets. + this->checkIntersect({}, 10, 20, {}); + this->checkIntersect({}, 20, 10, {}); + // Check that intersection with itself produces the same set. + this->checkIntersect({{10, 20}}, 10, 20, {{10, 20}}); + this->checkIntersect({{MIN, 10}, {20, MAX}}, 20, 10, {{MIN, 10}, {20, MAX}}); + // Check non-overlapping range intersections. + this->checkIntersect({{10, 20}}, 21, 9, {}); + this->checkIntersect({{MIN, 9}, {21, MAX}}, 10, 20, {}); + // Check more general cases. + this->checkIntersect({{0, 10}, {20, 30}, {30, 40}, {50, 60}}, 10, 35, + {{10, 10}, {20, 30}, {30, 35}}); + this->checkIntersect({{0, 10}, {20, 30}, {30, 40}, {50, 60}}, 35, 10, + {{0, 10}, {35, 40}, {50, 60}}); +} + +TYPED_TEST(RangeSetTest, RangeSetGenericIntersectTest) { + // Check that we can correctly intersect empty sets. + this->checkIntersect({}, {}, {}); + this->checkIntersect({}, {{0, 10}}, {}); + this->checkIntersect({{0, 10}}, {}, {}); + + this->checkIntersect({{0, 10}}, {{4, 6}}, {{4, 6}}); + this->checkIntersect({{0, 10}}, {{4, 20}}, {{4, 10}}); + // Check that intersection with points works as expected. + this->checkIntersect({{0, 10}}, {{4, 4}}, {{4, 4}}); + // All ranges are closed, check that intersection with edge points works as + // expected. + this->checkIntersect({{0, 10}}, {{10, 10}}, {{10, 10}}); + + // Let's check that we can skip some intervals and partially intersect + // other intervals. + this->checkIntersect({{0, 2}, {4, 5}, {6, 9}, {10, 11}, {12, 12}, {13, 15}}, + {{8, 14}, {20, 30}}, + {{8, 9}, {10, 11}, {12, 12}, {13, 14}}); + // Check more generic case. + this->checkIntersect( + {{0, 1}, {2, 3}, {5, 6}, {7, 15}, {25, 30}}, + {{4, 10}, {11, 11}, {12, 16}, {17, 17}, {19, 20}, {21, 23}, {24, 27}}, + {{5, 6}, {7, 10}, {11, 11}, {12, 15}, {25, 27}}); +} + +TYPED_TEST(RangeSetTest, RangeSetContainsTest) { + // Check with an empty set. + this->checkContains({}, 10, false); + // Check contains with sets of size one: + // * when the whole range is less + this->checkContains({{0, 5}}, 10, false); + // * when the whole range is greater + this->checkContains({{20, 25}}, 10, false); + // * when the range is just the point we are looking for + this->checkContains({{10, 10}}, 10, true); + // * when the range starts with the point + this->checkContains({{10, 15}}, 10, true); + // * when the range ends with the point + this->checkContains({{5, 10}}, 10, true); + // * when the range has the point somewhere in the middle + this->checkContains({{0, 25}}, 10, true); + // Check similar cases, but with larger sets. + this->checkContains({{0, 5}, {10, 10}, {15, 20}}, 10, true); + this->checkContains({{0, 5}, {10, 12}, {15, 20}}, 10, true); + this->checkContains({{0, 5}, {5, 7}, {8, 10}, {12, 41}}, 10, true); + + constexpr TypeParam MIN = TestFixture::getMin(); + constexpr TypeParam MAX = TestFixture::getMax(); + constexpr TypeParam MID = TestFixture::getMid(); + this->checkContains({{MIN, MAX}}, 0, true); + this->checkContains({{MIN, MAX}}, MID, true); + this->checkContains({{MIN, MAX}}, -10, true); + this->checkContains({{MIN, MAX}}, 10, true); +} + +TYPED_TEST(RangeSetTest, RangeSetAddTest) { + // Check adding single points + this->checkAdd({}, 10, {{10, 10}}); + this->checkAdd({{0, 5}}, 10, {{0, 5}, {10, 10}}); + this->checkAdd({{0, 5}, {30, 40}}, 10, {{0, 5}, {10, 10}, {30, 40}}); + + // Check adding single ranges. + this->checkAdd({}, {10, 20}, {{10, 20}}); + this->checkAdd({{0, 5}}, {10, 20}, {{0, 5}, {10, 20}}); + this->checkAdd({{0, 5}, {30, 40}}, {10, 20}, {{0, 5}, {10, 20}, {30, 40}}); + + // Check adding whole sets of ranges. + this->checkAdd({{0, 5}}, {{10, 20}}, {{0, 5}, {10, 20}}); + // Check that ordering of ranges is as expected. + this->checkAdd({{0, 5}, {30, 40}}, {{10, 20}}, {{0, 5}, {10, 20}, {30, 40}}); + this->checkAdd({{0, 5}, {30, 40}}, {{10, 20}, {50, 60}}, + {{0, 5}, {10, 20}, {30, 40}, {50, 60}}); + this->checkAdd({{10, 20}, {50, 60}}, {{0, 5}, {30, 40}, {70, 80}}, + {{0, 5}, {10, 20}, {30, 40}, {50, 60}, {70, 80}}); +} + +TYPED_TEST(RangeSetTest, RangeSetDeletePointTest) { + constexpr TypeParam MIN = TestFixture::getMin(); + constexpr TypeParam MAX = TestFixture::getMax(); + constexpr TypeParam MID = TestFixture::getMid(); + + this->checkDelete(MID, {{MIN, MAX}}, {{MIN, MID - 1}, {MID + 1, MAX}}); + // Check that delete works with an empty set. + this->checkDelete(10, {}, {}); + // Check that delete can remove entire ranges. + this->checkDelete(10, {{10, 10}}, {}); + this->checkDelete(10, {{0, 5}, {10, 10}, {20, 30}}, {{0, 5}, {20, 30}}); + // Check that delete can split existing ranges into two. + this->checkDelete(10, {{0, 5}, {7, 15}, {20, 30}}, + {{0, 5}, {7, 9}, {11, 15}, {20, 30}}); + // Check that delete of the point not from the range set works as expected. + this->checkDelete(10, {{0, 5}, {20, 30}}, {{0, 5}, {20, 30}}); +} diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp index ba40a7a643c4..8ff3387d3c18 100644 --- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -725,14 +725,14 @@ class InterpolateTest : public MemDBTest { protected: // Look up the command from a relative path, and return it in string form. // The input file is not included in the returned command. - std::string getCommand(llvm::StringRef F) { + std::string getCommand(llvm::StringRef F, bool MakeNative = true) { auto Results = inferMissingCompileCommands(std::make_unique(Entries)) - ->getCompileCommands(path(F)); + ->getCompileCommands(MakeNative ? path(F) : F); if (Results.empty()) return "none"; // drop the input file argument, so tests don't have to deal with path(). - EXPECT_EQ(Results[0].CommandLine.back(), path(F)) + EXPECT_EQ(Results[0].CommandLine.back(), MakeNative ? path(F) : F) << "Last arg should be the file"; Results[0].CommandLine.pop_back(); return llvm::join(Results[0].CommandLine, " "); @@ -812,6 +812,28 @@ TEST_F(InterpolateTest, Strip) { EXPECT_EQ(getCommand("dir/bar.cpp"), "clang -D dir/foo.cpp -Wall"); } +TEST_F(InterpolateTest, StripDoubleDash) { + add("dir/foo.cpp", "-o foo.o -std=c++14 -Wall -- dir/foo.cpp"); + // input file and output option are removed + // -Wall flag isn't + // -std option gets re-added as the last argument before the input file + // -- is removed as it's not necessary - the new input file doesn't start with + // a dash + EXPECT_EQ(getCommand("dir/bar.cpp"), "clang -D dir/foo.cpp -Wall -std=c++14"); +} + +TEST_F(InterpolateTest, InsertDoubleDash) { + add("dir/foo.cpp", "-o foo.o -std=c++14 -Wall"); + EXPECT_EQ(getCommand("-dir/bar.cpp", false), + "clang -D dir/foo.cpp -Wall -std=c++14 --"); +} + +TEST_F(InterpolateTest, InsertDoubleDashForClangCL) { + add("dir/foo.cpp", "clang-cl", "/std:c++14 /W4"); + EXPECT_EQ(getCommand("/dir/bar.cpp", false), + "clang-cl -D dir/foo.cpp /W4 /std:c++14 --"); +} + TEST_F(InterpolateTest, Case) { add("FOO/BAR/BAZ/SHOUT.cc"); add("foo/bar/baz/quiet.cc"); @@ -831,7 +853,7 @@ TEST_F(InterpolateTest, ClangCL) { add("foo.cpp", "clang-cl", "/W4"); // Language flags should be added with CL syntax. - EXPECT_EQ(getCommand("foo.h"), "clang-cl -D foo.cpp /W4 /TP"); + EXPECT_EQ(getCommand("foo.h", false), "clang-cl -D foo.cpp /W4 /TP"); } TEST_F(InterpolateTest, DriverModes) { @@ -839,8 +861,10 @@ TEST_F(InterpolateTest, DriverModes) { add("bar.cpp", "clang", "--driver-mode=cl"); // --driver-mode overrides should be respected. - EXPECT_EQ(getCommand("foo.h"), "clang-cl -D foo.cpp --driver-mode=gcc -x c++-header"); - EXPECT_EQ(getCommand("bar.h"), "clang -D bar.cpp --driver-mode=cl /TP"); + EXPECT_EQ(getCommand("foo.h"), + "clang-cl -D foo.cpp --driver-mode=gcc -x c++-header"); + EXPECT_EQ(getCommand("bar.h", false), + "clang -D bar.cpp --driver-mode=cl /TP"); } TEST(TransferCompileCommandTest, Smoke) { diff --git a/clang/unittests/Tooling/Syntax/TokensTest.cpp b/clang/unittests/Tooling/Syntax/TokensTest.cpp index 7d5943bf2520..1768529e0a62 100644 --- a/clang/unittests/Tooling/Syntax/TokensTest.cpp +++ b/clang/unittests/Tooling/Syntax/TokensTest.cpp @@ -106,6 +106,7 @@ class TokenCollectorTest : public ::testing::Test { void EndSourceFileAction() override { assert(Collector && "BeginSourceFileAction was never called"); Result = std::move(*Collector).consume(); + Result.indexExpandedTokens(); } std::unique_ptr @@ -1037,4 +1038,13 @@ TEST_F(TokenBufferTest, ExpandedBySpelled) { IsEmpty()); } +TEST_F(TokenCollectorTest, Pragmas) { + // Tokens coming from concatenations. + recordTokens(R"cpp( + void foo() { + #pragma unroll 4 + for(int i=0;i<4;++i); + } + )cpp"); +} } // namespace diff --git a/clang/utils/TableGen/CMakeLists.txt b/clang/utils/TableGen/CMakeLists.txt index 26589ec7e1ce..6379cc4e11e8 100644 --- a/clang/utils/TableGen/CMakeLists.txt +++ b/clang/utils/TableGen/CMakeLists.txt @@ -18,6 +18,7 @@ add_tablegen(clang-tblgen CLANG ClangTypeNodesEmitter.cpp MveEmitter.cpp NeonEmitter.cpp + RISCVVEmitter.cpp SveEmitter.cpp TableGen.cpp ) diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index aaef538e9bf9..e74df36899d4 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -1828,6 +1828,22 @@ struct PragmaClangAttributeSupport { } // end anonymous namespace +static bool isSupportedPragmaClangAttributeSubject(const Record &Subject) { + // FIXME: #pragma clang attribute does not currently support statement + // attributes, so test whether the subject is one that appertains to a + // declaration node. However, it may be reasonable for support for statement + // attributes to be added. + if (Subject.isSubClassOf("DeclNode") || Subject.isSubClassOf("DeclBase") || + Subject.getName() == "DeclBase") + return true; + + if (Subject.isSubClassOf("SubsetSubject")) + return isSupportedPragmaClangAttributeSubject( + *Subject.getValueAsDef("Base")); + + return false; +} + static bool doesDeclDeriveFrom(const Record *D, const Record *Base) { const Record *CurrentBase = D->getValueAsOptionalDef(BaseFieldName); if (!CurrentBase) @@ -1949,13 +1965,15 @@ bool PragmaClangAttributeSupport::isAttributedSupported( return false; const Record *SubjectObj = Attribute.getValueAsDef("Subjects"); std::vector Subjects = SubjectObj->getValueAsListOfDefs("Subjects"); - if (Subjects.empty()) - return false; + bool HasAtLeastOneValidSubject = false; for (const auto *Subject : Subjects) { + if (!isSupportedPragmaClangAttributeSubject(*Subject)) + continue; if (SubjectsToRules.find(Subject) == SubjectsToRules.end()) return false; + HasAtLeastOneValidSubject = true; } - return true; + return HasAtLeastOneValidSubject; } static std::string GenerateTestExpression(ArrayRef LangOpts) { @@ -2001,6 +2019,8 @@ PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr, const Record *SubjectObj = Attr.getValueAsDef("Subjects"); std::vector Subjects = SubjectObj->getValueAsListOfDefs("Subjects"); for (const auto *Subject : Subjects) { + if (!isSupportedPragmaClangAttributeSubject(*Subject)) + continue; auto It = SubjectsToRules.find(Subject); assert(It != SubjectsToRules.end() && "This attribute is unsupported by #pragma clang attribute"); @@ -3503,7 +3523,7 @@ static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) { return; const Record *SubjectObj = Attr.getValueAsDef("Subjects"); - std::vector Subjects = SubjectObj->getValueAsListOfDefs("Subjects"); + std::vector Subjects = SubjectObj->getValueAsListOfDefs("Subjects"); // If the list of subjects is empty, it is assumed that the attribute // appertains to everything. @@ -3512,42 +3532,99 @@ static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) { bool Warn = SubjectObj->getValueAsDef("Diag")->getValueAsBit("Warn"); - // Otherwise, generate an appertainsTo check specific to this attribute which - // checks all of the given subjects against the Decl passed in. - // - // If D is null, that means the attribute was not applied to a declaration - // at all (for instance because it was applied to a type), or that the caller - // has determined that the check should fail (perhaps prior to the creation - // of the declaration). - OS << "bool diagAppertainsToDecl(Sema &S, "; - OS << "const ParsedAttr &Attr, const Decl *D) const override {\n"; - OS << " if ("; - for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) { - // If the subject has custom code associated with it, use the generated - // function for it. The function cannot be inlined into this check (yet) - // because it requires the subject to be of a specific type, and were that - // information inlined here, it would not support an attribute with multiple - // custom subjects. - if ((*I)->isSubClassOf("SubsetSubject")) { - OS << "!" << functionNameForCustomAppertainsTo(**I) << "(D)"; - } else { - OS << "!isa<" << GetSubjectWithSuffix(*I) << ">(D)"; + // Split the subjects into declaration subjects and statement subjects. + // FIXME: subset subjects are added to the declaration list until there are + // enough statement attributes with custom subject needs to warrant + // the implementation effort. + std::vector DeclSubjects, StmtSubjects; + llvm::copy_if( + Subjects, std::back_inserter(DeclSubjects), [](const Record *R) { + return R->isSubClassOf("SubsetSubject") || !R->isSubClassOf("StmtNode"); + }); + llvm::copy_if(Subjects, std::back_inserter(StmtSubjects), + [](const Record *R) { return R->isSubClassOf("StmtNode"); }); + + // We should have sorted all of the subjects into two lists. + // FIXME: this assertion will be wrong if we ever add type attribute subjects. + assert(DeclSubjects.size() + StmtSubjects.size() == Subjects.size()); + + if (DeclSubjects.empty()) { + // If there are no decl subjects but there are stmt subjects, diagnose + // trying to apply a statement attribute to a declaration. + if (!StmtSubjects.empty()) { + OS << "bool diagAppertainsToDecl(Sema &S, const ParsedAttr &AL, "; + OS << "const Decl *D) const override {\n"; + OS << " S.Diag(AL.getLoc(), diag::err_stmt_attribute_invalid_on_decl)\n"; + OS << " << AL << D->getLocation();\n"; + OS << " return false;\n"; + OS << "}\n\n"; } + } else { + // Otherwise, generate an appertainsTo check specific to this attribute + // which checks all of the given subjects against the Decl passed in. + OS << "bool diagAppertainsToDecl(Sema &S, "; + OS << "const ParsedAttr &Attr, const Decl *D) const override {\n"; + OS << " if ("; + for (auto I = DeclSubjects.begin(), E = DeclSubjects.end(); I != E; ++I) { + // If the subject has custom code associated with it, use the generated + // function for it. The function cannot be inlined into this check (yet) + // because it requires the subject to be of a specific type, and were that + // information inlined here, it would not support an attribute with + // multiple custom subjects. + if ((*I)->isSubClassOf("SubsetSubject")) + OS << "!" << functionNameForCustomAppertainsTo(**I) << "(D)"; + else + OS << "!isa<" << GetSubjectWithSuffix(*I) << ">(D)"; - if (I + 1 != E) - OS << " && "; + if (I + 1 != E) + OS << " && "; + } + OS << ") {\n"; + OS << " S.Diag(Attr.getLoc(), diag::"; + OS << (Warn ? "warn_attribute_wrong_decl_type_str" + : "err_attribute_wrong_decl_type_str"); + OS << ")\n"; + OS << " << Attr << "; + OS << CalculateDiagnostic(*SubjectObj) << ";\n"; + OS << " return false;\n"; + OS << " }\n"; + OS << " return true;\n"; + OS << "}\n\n"; + } + + if (StmtSubjects.empty()) { + // If there are no stmt subjects but there are decl subjects, diagnose + // trying to apply a declaration attribute to a statement. + if (!DeclSubjects.empty()) { + OS << "bool diagAppertainsToStmt(Sema &S, const ParsedAttr &AL, "; + OS << "const Stmt *St) const override {\n"; + OS << " S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n"; + OS << " << AL << St->getBeginLoc();\n"; + OS << " return false;\n"; + OS << "}\n\n"; + } + } else { + // Now, do the same for statements. + OS << "bool diagAppertainsToStmt(Sema &S, "; + OS << "const ParsedAttr &Attr, const Stmt *St) const override {\n"; + OS << " if ("; + for (auto I = StmtSubjects.begin(), E = StmtSubjects.end(); I != E; ++I) { + OS << "!isa<" << (*I)->getName() << ">(St)"; + if (I + 1 != E) + OS << " && "; + } + OS << ") {\n"; + OS << " S.Diag(Attr.getLoc(), diag::"; + OS << (Warn ? "warn_attribute_wrong_decl_type_str" + : "err_attribute_wrong_decl_type_str"); + OS << ")\n"; + OS << " << Attr << "; + OS << CalculateDiagnostic(*SubjectObj) << ";\n"; + OS << " return false;\n"; + OS << " }\n"; + OS << " return true;\n"; + OS << "}\n\n"; } - OS << ") {\n"; - OS << " S.Diag(Attr.getLoc(), diag::"; - OS << (Warn ? "warn_attribute_wrong_decl_type_str" : - "err_attribute_wrong_decl_type_str"); - OS << ")\n"; - OS << " << Attr << "; - OS << CalculateDiagnostic(*SubjectObj) << ";\n"; - OS << " return false;\n"; - OS << " }\n"; - OS << " return true;\n"; - OS << "}\n\n"; } static void @@ -4214,9 +4291,13 @@ void EmitTestPragmaAttributeSupportedAttributes(RecordKeeper &Records, std::vector Subjects = SubjectObj->getValueAsListOfDefs("Subjects"); OS << " ("; + bool PrintComma = false; for (const auto &Subject : llvm::enumerate(Subjects)) { - if (Subject.index()) + if (!isSupportedPragmaClangAttributeSubject(*Subject.value())) + continue; + if (PrintComma) OS << ", "; + PrintComma = true; PragmaClangAttributeSupport::RuleOrAggregateRuleSet &RuleSet = Support.SubjectsToRules.find(Subject.value())->getSecond(); if (RuleSet.isRule()) { diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index 77c478672324..014c1adcd809 100644 --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -557,7 +557,7 @@ struct PluralPiece : SelectPiece { struct DiffPiece : Piece { DiffPiece() : Piece(DiffPieceClass) {} - Piece *Options[2] = {}; + Piece *Parts[4] = {}; int Indexes[2] = {}; static bool classof(const Piece *P) { @@ -633,9 +633,18 @@ struct DiagnosticTextBuilder { } DiagText(DiagnosticTextBuilder &Builder, StringRef Text) - : Builder(Builder), Root(parseDiagText(Text)) {} - - Piece *parseDiagText(StringRef &Text, bool Nested = false); + : Builder(Builder), Root(parseDiagText(Text, StopAt::End)) {} + + enum class StopAt { + // Parse until the end of the string. + End, + // Additionally stop if we hit a non-nested '|' or '}'. + PipeOrCloseBrace, + // Additionally stop if we hit a non-nested '$'. + Dollar, + }; + + Piece *parseDiagText(StringRef &Text, StopAt Stop); int parseModifier(StringRef &) const; public: @@ -901,7 +910,24 @@ struct DiagTextDocPrinter : DiagTextVisitor { void VisitPlural(PluralPiece *P) { VisitSelect(P); } - void VisitDiff(DiffPiece *P) { Visit(P->Options[1]); } + void VisitDiff(DiffPiece *P) { + // Render %diff{a $ b $ c|d}e,f as %select{a %e b %f c|d}. + PlaceholderPiece E(MT_Placeholder, P->Indexes[0]); + PlaceholderPiece F(MT_Placeholder, P->Indexes[1]); + + MultiPiece FirstOption; + FirstOption.Pieces.push_back(P->Parts[0]); + FirstOption.Pieces.push_back(&E); + FirstOption.Pieces.push_back(P->Parts[1]); + FirstOption.Pieces.push_back(&F); + FirstOption.Pieces.push_back(P->Parts[2]); + + SelectPiece Select(MT_Diff); + Select.Options.push_back(&FirstOption); + Select.Options.push_back(P->Parts[3]); + + VisitSelect(&Select); + } std::vector &RST; }; @@ -955,9 +981,13 @@ struct DiagTextPrinter : DiagTextVisitor { void VisitDiff(DiffPiece *P) { Result += "%diff{"; - Visit(P->Options[0]); + Visit(P->Parts[0]); + Result += "$"; + Visit(P->Parts[1]); + Result += "$"; + Visit(P->Parts[2]); Result += "|"; - Visit(P->Options[1]); + Visit(P->Parts[3]); Result += "}"; addInt(mapIndex(P->Indexes[0])); Result += ","; @@ -982,16 +1012,19 @@ int DiagnosticTextBuilder::DiagText::parseModifier(StringRef &Text) const { } Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, - bool Nested) { + StopAt Stop) { std::vector Parsed; + constexpr llvm::StringLiteral StopSets[] = {"%", "%|}", "%|}$"}; + llvm::StringRef StopSet = StopSets[static_cast(Stop)]; + while (!Text.empty()) { size_t End = (size_t)-2; do - End = Nested ? Text.find_first_of("%|}", End + 2) - : Text.find_first_of('%', End + 2); - while (End < Text.size() - 1 && Text[End] == '%' && - (Text[End + 1] == '%' || Text[End + 1] == '|')); + End = Text.find_first_of(StopSet, End + 2); + while ( + End < Text.size() - 1 && Text[End] == '%' && + (Text[End + 1] == '%' || Text[End + 1] == '|' || Text[End + 1] == '$')); if (End) { Parsed.push_back(New(Text.slice(0, End), "diagtext")); @@ -1000,7 +1033,7 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, break; } - if (Text[0] == '|' || Text[0] == '}') + if (Text[0] == '|' || Text[0] == '}' || Text[0] == '$') break; // Drop the '%'. @@ -1023,6 +1056,12 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, .Case("", MT_Placeholder) .Default(MT_Unknown); + auto ExpectAndConsume = [&](StringRef Prefix) { + if (!Text.consume_front(Prefix)) + Builder.PrintFatalError("expected '" + Prefix + "' while parsing %" + + Modifier); + }; + switch (ModType) { case MT_Unknown: Builder.PrintFatalError("Unknown modifier type: " + Modifier); @@ -1030,11 +1069,11 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, SelectPiece *Select = New(MT_Select); do { Text = Text.drop_front(); // '{' or '|' - Select->Options.push_back(parseDiagText(Text, true)); + Select->Options.push_back( + parseDiagText(Text, StopAt::PipeOrCloseBrace)); assert(!Text.empty() && "malformed %select"); } while (Text.front() == '|'); - // Drop the trailing '}'. - Text = Text.drop_front(1); + ExpectAndConsume("}"); Select->Index = parseModifier(Text); Parsed.push_back(Select); continue; @@ -1051,24 +1090,24 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, Plural->OptionPrefixes.push_back( New(Text.slice(0, End), "diagtext")); Text = Text.slice(End, StringRef::npos); - Plural->Options.push_back(parseDiagText(Text, true)); - assert(!Text.empty() && "malformed %select"); + Plural->Options.push_back( + parseDiagText(Text, StopAt::PipeOrCloseBrace)); + assert(!Text.empty() && "malformed %plural"); } while (Text.front() == '|'); - // Drop the trailing '}'. - Text = Text.drop_front(1); + ExpectAndConsume("}"); Plural->Index = parseModifier(Text); Parsed.push_back(Plural); continue; } case MT_Sub: { SubstitutionPiece *Sub = New(); - Text = Text.drop_front(); // '{' + ExpectAndConsume("{"); size_t NameSize = Text.find_first_of('}'); assert(NameSize != size_t(-1) && "failed to find the end of the name"); assert(NameSize != 0 && "empty name?"); Sub->Name = Text.substr(0, NameSize).str(); Text = Text.drop_front(NameSize); - Text = Text.drop_front(); // '}' + ExpectAndConsume("}"); if (!Text.empty()) { while (true) { if (!isdigit(Text[0])) @@ -1086,14 +1125,17 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, } case MT_Diff: { DiffPiece *Diff = New(); - Text = Text.drop_front(); // '{' - Diff->Options[0] = parseDiagText(Text, true); - Text = Text.drop_front(); // '|' - Diff->Options[1] = parseDiagText(Text, true); - - Text = Text.drop_front(); // '}' + ExpectAndConsume("{"); + Diff->Parts[0] = parseDiagText(Text, StopAt::Dollar); + ExpectAndConsume("$"); + Diff->Parts[1] = parseDiagText(Text, StopAt::Dollar); + ExpectAndConsume("$"); + Diff->Parts[2] = parseDiagText(Text, StopAt::PipeOrCloseBrace); + ExpectAndConsume("|"); + Diff->Parts[3] = parseDiagText(Text, StopAt::PipeOrCloseBrace); + ExpectAndConsume("}"); Diff->Indexes[0] = parseModifier(Text); - Text = Text.drop_front(); // ',' + ExpectAndConsume(","); Diff->Indexes[1] = parseModifier(Text); Parsed.push_back(Diff); continue; diff --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp index e9ae08ac4c05..091af2dc52a1 100644 --- a/clang/utils/TableGen/MveEmitter.cpp +++ b/clang/utils/TableGen/MveEmitter.cpp @@ -1272,6 +1272,13 @@ Result::Ptr EmitterBase::getCodeForDagArg(DagInit *D, unsigned ArgNum, return it->second; } + // Sometimes the Arg is a bit. Prior to multiclass template argument + // checking, integers would sneak through the bit declaration, + // but now they really are bits. + if (auto *BI = dyn_cast(Arg)) + return std::make_shared(getScalarType("u32"), + BI->getValue()); + if (auto *II = dyn_cast(Arg)) return std::make_shared(getScalarType("u32"), II->getValue()); @@ -1287,7 +1294,11 @@ Result::Ptr EmitterBase::getCodeForDagArg(DagInit *D, unsigned ArgNum, } } - PrintFatalError("bad dag argument type for code generation"); + PrintError("bad DAG argument type for code generation"); + PrintNote("DAG: " + D->getAsString()); + if (TypedInit *Typed = dyn_cast(Arg)) + PrintNote("argument type: " + Typed->getType()->getAsString()); + PrintFatalNote("argument number " + Twine(ArgNum) + ": " + Arg->getAsString()); } Result::Ptr EmitterBase::getCodeForArg(unsigned ArgNum, const Type *ArgType, diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp new file mode 100644 index 000000000000..4e4cf442e336 --- /dev/null +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -0,0 +1,1200 @@ +//===- RISCVVEmitter.cpp - Generate riscv_vector.h for use with clang -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend is responsible for emitting riscv_vector.h which +// includes a declaration and definition of each intrinsic functions specified +// in https://github.com/riscv/rvv-intrinsic-doc. +// +// See also the documentation in include/clang/Basic/riscv_vector.td. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Twine.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include + +using namespace llvm; +using BasicType = char; +using VScaleVal = Optional; + +namespace { + +// Exponential LMUL +class LMULType { +private: + int Log2LMUL; + +public: + LMULType(int Log2LMUL); + // Return the C/C++ string representation of LMUL + std::string str() const; + Optional getScale(unsigned ElementBitwidth) const; + void MulLog2LMUL(int Log2LMUL); + LMULType &operator*=(uint32_t RHS); +}; + +// This class is compact representation of a valid and invalid RVVType. +class RVVType { + enum ScalarTypeKind : uint32_t { + Void, + Size_t, + Ptrdiff_t, + Boolean, + SignedInteger, + UnsignedInteger, + Float, + Invalid, + }; + BasicType BT; + ScalarTypeKind ScalarType = Invalid; + LMULType LMUL; + bool IsPointer = false; + // IsConstant indices are "int", but have the constant expression. + bool IsImmediate = false; + // Const qualifier for pointer to const object or object of const type. + bool IsConstant = false; + unsigned ElementBitwidth = 0; + VScaleVal Scale = 0; + bool Valid; + + std::string BuiltinStr; + std::string ClangBuiltinStr; + std::string Str; + std::string ShortStr; + +public: + RVVType() : RVVType(BasicType(), 0, StringRef()) {} + RVVType(BasicType BT, int Log2LMUL, StringRef prototype); + + // Return the string representation of a type, which is an encoded string for + // passing to the BUILTIN() macro in Builtins.def. + const std::string &getBuiltinStr() const { return BuiltinStr; } + + // Return the clang buitlin type for RVV vector type which are used in the + // riscv_vector.h header file. + const std::string &getClangBuiltinStr() const { return ClangBuiltinStr; } + + // Return the C/C++ string representation of a type for use in the + // riscv_vector.h header file. + const std::string &getTypeStr() const { return Str; } + + // Return the short name of a type for C/C++ name suffix. + const std::string &getShortStr() { + // Not all types are used in short name, so compute the short name by + // demanded. + if (ShortStr.empty()) + initShortStr(); + return ShortStr; + } + + bool isValid() const { return Valid; } + bool isScalar() const { return Scale.hasValue() && Scale.getValue() == 0; } + bool isVector() const { return Scale.hasValue() && Scale.getValue() != 0; } + bool isFloat() const { return ScalarType == ScalarTypeKind::Float; } + bool isSignedInteger() const { + return ScalarType == ScalarTypeKind::SignedInteger; + } + bool isFloatVector(unsigned Width) const { + return isVector() && isFloat() && ElementBitwidth == Width; + } + +private: + // Verify RVV vector type and set Valid. + bool verifyType() const; + + // Creates a type based on basic types of TypeRange + void applyBasicType(); + + // Applies a prototype modifier to the current type. The result maybe an + // invalid type. + void applyModifier(StringRef prototype); + + // Compute and record a string for legal type. + void initBuiltinStr(); + // Compute and record a builtin RVV vector type string. + void initClangBuiltinStr(); + // Compute and record a type string for used in the header. + void initTypeStr(); + // Compute and record a short name of a type for C/C++ name suffix. + void initShortStr(); +}; + +using RVVTypePtr = RVVType *; +using RVVTypes = std::vector; + +enum RISCVExtension : uint8_t { + Basic = 0, + F = 1 << 1, + D = 1 << 2, + Zfh = 1 << 3 +}; + +// TODO refactor RVVIntrinsic class design after support all intrinsic +// combination. This represents an instantiation of an intrinsic with a +// particular type and prototype +class RVVIntrinsic { + +private: + std::string Name; // Builtin name + std::string MangledName; + std::string IRName; + bool HasSideEffects; + bool IsMask; + bool HasMaskedOffOperand; + bool HasVL; + bool HasNoMaskedOverloaded; + bool HasAutoDef; // There is automiatic definition in header + std::string ManualCodegen; + RVVTypePtr OutputType; // Builtin output type + RVVTypes InputTypes; // Builtin input types + // The types we use to obtain the specific LLVM intrinsic. They are index of + // InputTypes. -1 means the return type. + std::vector IntrinsicTypes; + // C/C++ intrinsic operand order is different to builtin operand order. Record + // the mapping of InputTypes index. + SmallVector CTypeOrder; + uint8_t RISCVExtensions = 0; + +public: + RVVIntrinsic(StringRef Name, StringRef Suffix, StringRef MangledName, + StringRef IRName, bool HasSideEffects, bool IsMask, + bool HasMaskedOffOperand, bool HasVL, bool HasNoMaskedOverloaded, + bool HasAutoDef, StringRef ManualCodegen, const RVVTypes &Types, + const std::vector &IntrinsicTypes, + const std::vector &PermuteOperands); + ~RVVIntrinsic() = default; + + StringRef getName() const { return Name; } + StringRef getMangledName() const { return MangledName; } + bool hasSideEffects() const { return HasSideEffects; } + bool hasMaskedOffOperand() const { return HasMaskedOffOperand; } + bool hasVL() const { return HasVL; } + bool hasNoMaskedOverloaded() const { return HasNoMaskedOverloaded; } + bool hasManualCodegen() const { return !ManualCodegen.empty(); } + bool hasAutoDef() const { return HasAutoDef; } + bool isMask() const { return IsMask; } + size_t getNumOperand() const { return InputTypes.size(); } + StringRef getIRName() const { return IRName; } + uint8_t getRISCVExtensions() const { return RISCVExtensions; } + + // Return the type string for a BUILTIN() macro in Builtins.def. + std::string getBuiltinTypeStr() const; + + // Emit the code block for switch body in EmitRISCVBuiltinExpr, it should + // init the RVVIntrinsic ID and IntrinsicTypes. + void emitCodeGenSwitchBody(raw_ostream &o) const; + + // Emit the macros for mapping C/C++ intrinsic function to builtin functions. + void emitIntrinsicMacro(raw_ostream &o) const; + + // Emit the mangled function definition. + void emitMangledFuncDef(raw_ostream &o) const; +}; + +class RVVEmitter { +private: + RecordKeeper &Records; + std::string HeaderCode; + // Concat BasicType, LMUL and Proto as key + StringMap LegalTypes; + StringSet<> IllegalTypes; + +public: + RVVEmitter(RecordKeeper &R) : Records(R) {} + + /// Emit riscv_vector.h + void createHeader(raw_ostream &o); + + /// Emit all the __builtin prototypes and code needed by Sema. + void createBuiltins(raw_ostream &o); + + /// Emit all the information needed to map builtin -> LLVM IR intrinsic. + void createCodeGen(raw_ostream &o); + + std::string getSuffixStr(char Type, int Log2LMUL, StringRef Prototypes); + +private: + /// Create all intrinsics and add them to \p Out + void createRVVIntrinsics(std::vector> &Out); + /// Compute output and input types by applying different config (basic type + /// and LMUL with type transformers). It also record result of type in legal + /// or illegal set to avoid compute the same config again. The result maybe + /// have illegal RVVType. + Optional computeTypes(BasicType BT, int Log2LMUL, + ArrayRef PrototypeSeq); + Optional computeType(BasicType BT, int Log2LMUL, StringRef Proto); + + /// Emit Acrh predecessor definitions and body, assume the element of Defs are + /// sorted by extension. + void emitArchMacroAndBody( + std::vector> &Defs, raw_ostream &o, + std::function); + + // Emit the architecture preprocessor definitions. Return true when emits + // non-empty string. + bool emitExtDefStr(uint8_t Extensions, raw_ostream &o); + // Slice Prototypes string into sub prototype string and process each sub + // prototype string individually in the Handler. + void parsePrototypes(StringRef Prototypes, + std::function Handler); +}; + +} // namespace + +//===----------------------------------------------------------------------===// +// Type implementation +//===----------------------------------------------------------------------===// + +LMULType::LMULType(int NewLog2LMUL) { + // Check Log2LMUL is -3, -2, -1, 0, 1, 2, 3 + assert(NewLog2LMUL <= 3 && NewLog2LMUL >= -3 && "Bad LMUL number!"); + Log2LMUL = NewLog2LMUL; +} + +std::string LMULType::str() const { + if (Log2LMUL < 0) + return "mf" + utostr(1ULL << (-Log2LMUL)); + return "m" + utostr(1ULL << Log2LMUL); +} + +VScaleVal LMULType::getScale(unsigned ElementBitwidth) const { + int Log2ScaleResult = 0; + switch (ElementBitwidth) { + default: + break; + case 8: + Log2ScaleResult = Log2LMUL + 3; + break; + case 16: + Log2ScaleResult = Log2LMUL + 2; + break; + case 32: + Log2ScaleResult = Log2LMUL + 1; + break; + case 64: + Log2ScaleResult = Log2LMUL; + break; + } + // Illegal vscale result would be less than 1 + if (Log2ScaleResult < 0) + return None; + return 1 << Log2ScaleResult; +} + +void LMULType::MulLog2LMUL(int log2LMUL) { Log2LMUL += log2LMUL; } + +LMULType &LMULType::operator*=(uint32_t RHS) { + assert(isPowerOf2_32(RHS)); + this->Log2LMUL = this->Log2LMUL + Log2_32(RHS); + return *this; +} + +RVVType::RVVType(BasicType BT, int Log2LMUL, StringRef prototype) + : BT(BT), LMUL(LMULType(Log2LMUL)) { + applyBasicType(); + applyModifier(prototype); + Valid = verifyType(); + if (Valid) { + initBuiltinStr(); + initTypeStr(); + if (isVector()) { + initClangBuiltinStr(); + } + } +} + +// clang-format off +// boolean type are encoded the ratio of n (SEW/LMUL) +// SEW/LMUL | 1 | 2 | 4 | 8 | 16 | 32 | 64 +// c type | vbool64_t | vbool32_t | vbool16_t | vbool8_t | vbool4_t | vbool2_t | vbool1_t +// IR type | nxv1i1 | nxv2i1 | nxv4i1 | nxv8i1 | nxv16i1 | nxv32i1 | nxv64i1 + +// type\lmul | 1/8 | 1/4 | 1/2 | 1 | 2 | 4 | 8 +// -------- |------ | -------- | ------- | ------- | -------- | -------- | -------- +// i64 | N/A | N/A | N/A | nxv1i64 | nxv2i64 | nxv4i64 | nxv8i64 +// i32 | N/A | N/A | nxv1i32 | nxv2i32 | nxv4i32 | nxv8i32 | nxv16i32 +// i16 | N/A | nxv1i16 | nxv2i16 | nxv4i16 | nxv8i16 | nxv16i16 | nxv32i16 +// i8 | nxv1i8 | nxv2i8 | nxv4i8 | nxv8i8 | nxv16i8 | nxv32i8 | nxv64i8 +// double | N/A | N/A | N/A | nxv1f64 | nxv2f64 | nxv4f64 | nxv8f64 +// float | N/A | N/A | nxv1f32 | nxv2f32 | nxv4f32 | nxv8f32 | nxv16f32 +// half | N/A | nxv1f16 | nxv2f16 | nxv4f16 | nxv8f16 | nxv16f16 | nxv32f16 +// clang-format on + +bool RVVType::verifyType() const { + if (ScalarType == Invalid) + return false; + if (isScalar()) + return true; + if (!Scale.hasValue()) + return false; + if (isFloat() && ElementBitwidth == 8) + return false; + unsigned V = Scale.getValue(); + switch (ElementBitwidth) { + case 1: + case 8: + // Check Scale is 1,2,4,8,16,32,64 + return (V <= 64 && isPowerOf2_32(V)); + case 16: + // Check Scale is 1,2,4,8,16,32 + return (V <= 32 && isPowerOf2_32(V)); + case 32: + // Check Scale is 1,2,4,8,16 + return (V <= 16 && isPowerOf2_32(V)); + case 64: + // Check Scale is 1,2,4,8 + return (V <= 8 && isPowerOf2_32(V)); + } + return false; +} + +void RVVType::initBuiltinStr() { + assert(isValid() && "RVVType is invalid"); + switch (ScalarType) { + case ScalarTypeKind::Void: + BuiltinStr = "v"; + return; + case ScalarTypeKind::Size_t: + BuiltinStr = "z"; + if (IsImmediate) + BuiltinStr = "I" + BuiltinStr; + return; + case ScalarTypeKind::Ptrdiff_t: + BuiltinStr = "Y"; + return; + case ScalarTypeKind::Boolean: + assert(ElementBitwidth == 1); + BuiltinStr += "b"; + break; + case ScalarTypeKind::SignedInteger: + case ScalarTypeKind::UnsignedInteger: + switch (ElementBitwidth) { + case 8: + BuiltinStr += "c"; + break; + case 16: + BuiltinStr += "s"; + break; + case 32: + BuiltinStr += "i"; + break; + case 64: + BuiltinStr += "Wi"; + break; + default: + llvm_unreachable("Unhandled ElementBitwidth!"); + } + if (isSignedInteger()) + BuiltinStr = "S" + BuiltinStr; + else + BuiltinStr = "U" + BuiltinStr; + break; + case ScalarTypeKind::Float: + switch (ElementBitwidth) { + case 16: + BuiltinStr += "h"; + break; + case 32: + BuiltinStr += "f"; + break; + case 64: + BuiltinStr += "d"; + break; + default: + llvm_unreachable("Unhandled ElementBitwidth!"); + } + break; + default: + llvm_unreachable("ScalarType is invalid!"); + } + if (IsImmediate) + BuiltinStr = "I" + BuiltinStr; + if (isScalar()) { + if (IsConstant) + BuiltinStr += "C"; + if (IsPointer) + BuiltinStr += "*"; + return; + } + BuiltinStr = "q" + utostr(Scale.getValue()) + BuiltinStr; +} + +void RVVType::initClangBuiltinStr() { + assert(isValid() && "RVVType is invalid"); + assert(isVector() && "Handle Vector type only"); + + ClangBuiltinStr = "__rvv_"; + switch (ScalarType) { + case ScalarTypeKind::Boolean: + ClangBuiltinStr += "bool" + utostr(64 / Scale.getValue()) + "_t"; + return; + case ScalarTypeKind::Float: + ClangBuiltinStr += "float"; + break; + case ScalarTypeKind::SignedInteger: + ClangBuiltinStr += "int"; + break; + case ScalarTypeKind::UnsignedInteger: + ClangBuiltinStr += "uint"; + break; + default: + llvm_unreachable("ScalarTypeKind is invalid"); + } + ClangBuiltinStr += utostr(ElementBitwidth) + LMUL.str() + "_t"; +} + +void RVVType::initTypeStr() { + assert(isValid() && "RVVType is invalid"); + + if (IsConstant) + Str += "const "; + + auto getTypeString = [&](StringRef TypeStr) { + if (isScalar()) + return Twine(TypeStr + Twine(ElementBitwidth) + "_t").str(); + return Twine("v" + TypeStr + Twine(ElementBitwidth) + LMUL.str() + "_t") + .str(); + }; + + switch (ScalarType) { + case ScalarTypeKind::Void: + Str = "void"; + return; + case ScalarTypeKind::Size_t: + Str = "size_t"; + return; + case ScalarTypeKind::Ptrdiff_t: + Str = "ptrdiff_t"; + return; + case ScalarTypeKind::Boolean: + if (isScalar()) + Str += "bool"; + else + // Vector bool is special case, the formulate is + // `vbool_t = MVT::nxv<64/N>i1` ex. vbool16_t = MVT::4i1 + Str += "vbool" + utostr(64 / Scale.getValue()) + "_t"; + break; + case ScalarTypeKind::Float: + if (isScalar()) { + if (ElementBitwidth == 64) + Str += "double"; + else if (ElementBitwidth == 32) + Str += "float"; + assert((ElementBitwidth == 32 || ElementBitwidth == 64) && + "Unhandled floating type"); + } else + Str += getTypeString("float"); + break; + case ScalarTypeKind::SignedInteger: + Str += getTypeString("int"); + break; + case ScalarTypeKind::UnsignedInteger: + Str += getTypeString("uint"); + break; + default: + llvm_unreachable("ScalarType is invalid!"); + } + if (IsPointer) + Str += " *"; +} + +void RVVType::initShortStr() { + assert(isVector() && "only handle vector type"); + switch (ScalarType) { + case ScalarTypeKind::Boolean: + ShortStr = "b" + utostr(64 / Scale.getValue()); + break; + case ScalarTypeKind::Float: + ShortStr = "f" + utostr(ElementBitwidth) + LMUL.str(); + break; + case ScalarTypeKind::SignedInteger: + ShortStr = "i" + utostr(ElementBitwidth) + LMUL.str(); + break; + case ScalarTypeKind::UnsignedInteger: + ShortStr = "u" + utostr(ElementBitwidth) + LMUL.str(); + break; + default: + llvm_unreachable("Unhandled case!"); + } +} + +void RVVType::applyBasicType() { + switch (BT) { + case 'c': + ElementBitwidth = 8; + ScalarType = ScalarTypeKind::SignedInteger; + break; + case 's': + ElementBitwidth = 16; + ScalarType = ScalarTypeKind::SignedInteger; + break; + case 'i': + ElementBitwidth = 32; + ScalarType = ScalarTypeKind::SignedInteger; + break; + case 'l': + ElementBitwidth = 64; + ScalarType = ScalarTypeKind::SignedInteger; + break; + case 'h': + ElementBitwidth = 16; + ScalarType = ScalarTypeKind::Float; + break; + case 'f': + ElementBitwidth = 32; + ScalarType = ScalarTypeKind::Float; + break; + case 'd': + ElementBitwidth = 64; + ScalarType = ScalarTypeKind::Float; + break; + default: + PrintFatalError("Unhandled type code!"); + } + assert(ElementBitwidth != 0 && "Bad element bitwidth!"); +} + +void RVVType::applyModifier(StringRef Transformer) { + if (Transformer.empty()) + return; + // Handle primitive type transformer + auto PType = Transformer.back(); + switch (PType) { + case 'e': + Scale = 0; + break; + case 'v': + Scale = LMUL.getScale(ElementBitwidth); + break; + case 'w': + ElementBitwidth *= 2; + LMUL *= 2; + Scale = LMUL.getScale(ElementBitwidth); + break; + case 'q': + ElementBitwidth *= 4; + LMUL *= 4; + Scale = LMUL.getScale(ElementBitwidth); + break; + case 'o': + ElementBitwidth *= 8; + LMUL *= 8; + Scale = LMUL.getScale(ElementBitwidth); + break; + case 'm': + ScalarType = ScalarTypeKind::Boolean; + Scale = LMUL.getScale(ElementBitwidth); + ElementBitwidth = 1; + break; + case '0': + ScalarType = ScalarTypeKind::Void; + break; + case 'z': + ScalarType = ScalarTypeKind::Size_t; + break; + case 't': + ScalarType = ScalarTypeKind::Ptrdiff_t; + break; + case 'c': // uint8_t + ScalarType = ScalarTypeKind::UnsignedInteger; + ElementBitwidth = 8; + Scale = 0; + break; + default: + PrintFatalError("Illegal primitive type transformers!"); + } + Transformer = Transformer.drop_back(); + + // Extract and compute complex type transformer. It can only appear one time. + if (Transformer.startswith("(")) { + size_t Idx = Transformer.find(')'); + assert(Idx != StringRef::npos); + StringRef ComplexType = Transformer.slice(1, Idx); + Transformer = Transformer.drop_front(Idx + 1); + assert(Transformer.find('(') == StringRef::npos && + "Only allow one complex type transformer"); + + auto UpdateAndCheckComplexProto = [&]() { + Scale = LMUL.getScale(ElementBitwidth); + const StringRef VectorPrototypes("vwqom"); + if (!VectorPrototypes.contains(PType)) + PrintFatalError("Complex type transformer only supports vector type!"); + if (Transformer.find_first_of("PCKWS") != StringRef::npos) + PrintFatalError( + "Illegal type transformer for Complex type transformer"); + }; + auto ComplexTT = ComplexType.split(":"); + if (ComplexTT.first == "Log2EEW") { + uint32_t Log2EEW; + ComplexTT.second.getAsInteger(10, Log2EEW); + // update new elmul = (eew/sew) * lmul + LMUL.MulLog2LMUL(Log2EEW - Log2_32(ElementBitwidth)); + // update new eew + ElementBitwidth = 1 << Log2EEW; + ScalarType = ScalarTypeKind::SignedInteger; + UpdateAndCheckComplexProto(); + } else { + PrintFatalError("Illegal complex type transformers!"); + } + } + + // Compute the remain type transformers + for (char I : Transformer) { + switch (I) { + case 'P': + if (IsConstant) + PrintFatalError("'P' transformer cannot be used after 'C'"); + if (IsPointer) + PrintFatalError("'P' transformer cannot be used twice"); + IsPointer = true; + break; + case 'C': + if (IsConstant) + PrintFatalError("'C' transformer cannot be used twice"); + IsConstant = true; + break; + case 'K': + IsImmediate = true; + break; + case 'U': + ScalarType = ScalarTypeKind::UnsignedInteger; + break; + case 'I': + ScalarType = ScalarTypeKind::SignedInteger; + break; + case 'F': + ScalarType = ScalarTypeKind::Float; + break; + case 'S': + LMUL = LMULType(0); + // Update ElementBitwidth need to update Scale too. + Scale = LMUL.getScale(ElementBitwidth); + break; + default: + PrintFatalError("Illegal non-primitive type transformer!"); + } + } +} + +//===----------------------------------------------------------------------===// +// RVVIntrinsic implementation +//===----------------------------------------------------------------------===// +RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix, + StringRef NewMangledName, StringRef IRName, + bool HasSideEffects, bool IsMask, + bool HasMaskedOffOperand, bool HasVL, + bool HasNoMaskedOverloaded, bool HasAutoDef, + StringRef ManualCodegen, const RVVTypes &OutInTypes, + const std::vector &NewIntrinsicTypes, + const std::vector &PermuteOperands) + : IRName(IRName), HasSideEffects(HasSideEffects), IsMask(IsMask), + HasMaskedOffOperand(HasMaskedOffOperand), HasVL(HasVL), + HasNoMaskedOverloaded(HasNoMaskedOverloaded), HasAutoDef(HasAutoDef), + ManualCodegen(ManualCodegen.str()) { + + // Init Name and MangledName + Name = NewName.str(); + if (NewMangledName.empty()) + MangledName = NewName.split("_").first.str(); + else + MangledName = NewMangledName.str(); + if (!Suffix.empty()) + Name += "_" + Suffix.str(); + if (IsMask) { + Name += "_m"; + } + // Init RISC-V extensions + for (const auto &T : OutInTypes) { + if (T->isFloatVector(16)) + RISCVExtensions |= RISCVExtension::Zfh; + else if (T->isFloatVector(32)) + RISCVExtensions |= RISCVExtension::F; + else if (T->isFloatVector(64)) + RISCVExtensions |= RISCVExtension::D; + } + + // Init OutputType and InputTypes + OutputType = OutInTypes[0]; + InputTypes.assign(OutInTypes.begin() + 1, OutInTypes.end()); + CTypeOrder.resize(InputTypes.size()); + std::iota(CTypeOrder.begin(), CTypeOrder.end(), 0); + // Update default order if we need permutate. + if (!PermuteOperands.empty()) { + // PermuteOperands is nonmasked version index. Update index when there is + // maskedoff operand which is always in first operand. + + unsigned Skew = HasMaskedOffOperand ? 1 : 0; + for (unsigned i = 0; i < PermuteOperands.size(); ++i) { + if (i != PermuteOperands[i]) + CTypeOrder[i] = PermuteOperands[i] + Skew; + } + // Verify the result of CTypeOrder has legal value. + if (*std::max_element(CTypeOrder.begin(), CTypeOrder.end()) >= + CTypeOrder.size()) + PrintFatalError( + "The index of PermuteOperand is bigger than the operand number"); + SmallSet Seen; + for (auto Idx : CTypeOrder) { + if (!Seen.insert(Idx).second) + PrintFatalError( + "The different element in PermuteOperand could not be equal"); + } + } + + if (IsMask) { + if (HasVL) + // Builtin type order: op0, op1, ..., mask, vl + // C type order: mask, op0, op1, ..., vl + std::rotate(CTypeOrder.begin(), CTypeOrder.end() - 2, + CTypeOrder.end() - 1); + else + // Builtin type order: op0, op1, ..., mask + // C type order: mask, op0, op1, ..., + std::rotate(CTypeOrder.begin(), CTypeOrder.end() - 1, CTypeOrder.end()); + } + + // IntrinsicTypes is nonmasked version index. Need to update it + // if there is maskedoff operand (It is always in first operand). + IntrinsicTypes = NewIntrinsicTypes; + if (IsMask && HasMaskedOffOperand) { + for (auto &I : IntrinsicTypes) { + if (I >= 0) + I += 1; + } + } +} + +std::string RVVIntrinsic::getBuiltinTypeStr() const { + std::string S; + S += OutputType->getBuiltinStr(); + for (const auto &T : InputTypes) { + S += T->getBuiltinStr(); + } + return S; +} + +void RVVIntrinsic::emitCodeGenSwitchBody(raw_ostream &OS) const { + + OS << " ID = Intrinsic::riscv_" + getIRName() + ";\n"; + if (hasManualCodegen()) { + OS << ManualCodegen; + OS << "break;\n"; + return; + } + OS << " IntrinsicTypes = {"; + ListSeparator LS; + for (const auto &Idx : IntrinsicTypes) { + if (Idx == -1) + OS << LS << "ResultType"; + else + OS << LS << "Ops[" << Idx << "]->getType()"; + } + + // VL could be i64 or i32, need to encode it in IntrinsicTypes. VL is + // always last operand. + if (hasVL()) + OS << ", Ops[" << getNumOperand() - 1 << "]->getType()"; + OS << "};\n"; + OS << " break;\n"; +} + +void RVVIntrinsic::emitIntrinsicMacro(raw_ostream &OS) const { + OS << "#define " << getName() << "("; + if (getNumOperand() > 0) { + ListSeparator LS; + for (const auto &I : CTypeOrder) + OS << LS << "op" << I; + } + OS << ") \\\n"; + OS << "__builtin_rvv_" << getName() << "("; + if (getNumOperand() > 0) { + ListSeparator LS; + for (unsigned i = 0; i < InputTypes.size(); ++i) + OS << LS << "(" << InputTypes[i]->getTypeStr() << ")(op" << i << ")"; + } + OS << ")\n"; +} + +void RVVIntrinsic::emitMangledFuncDef(raw_ostream &OS) const { + OS << OutputType->getTypeStr() << " " << getMangledName() << "("; + // Emit function arguments + if (getNumOperand() > 0) { + ListSeparator LS; + for (unsigned i = 0; i < CTypeOrder.size(); ++i) + OS << LS << InputTypes[CTypeOrder[i]]->getTypeStr() << " op" << i; + } + OS << "){\n"; + OS << " return " << getName() << "("; + // Emit parameter variables + if (getNumOperand() > 0) { + ListSeparator LS; + for (unsigned i = 0; i < CTypeOrder.size(); ++i) + OS << LS << "op" << i; + } + OS << ");\n"; + OS << "}\n\n"; +} + +//===----------------------------------------------------------------------===// +// RVVEmitter implementation +//===----------------------------------------------------------------------===// +void RVVEmitter::createHeader(raw_ostream &OS) { + + OS << "/*===---- riscv_vector.h - RISC-V V-extension RVVIntrinsics " + "-------------------===\n" + " *\n" + " *\n" + " * Part of the LLVM Project, under the Apache License v2.0 with LLVM " + "Exceptions.\n" + " * See https://llvm.org/LICENSE.txt for license information.\n" + " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n" + " *\n" + " *===-----------------------------------------------------------------" + "------===\n" + " */\n\n"; + + OS << "#ifndef __RISCV_VECTOR_H\n"; + OS << "#define __RISCV_VECTOR_H\n\n"; + + OS << "#include \n"; + OS << "#include \n\n"; + + OS << "#ifndef __riscv_vector\n"; + OS << "#error \"Vector intrinsics require the vector extension.\"\n"; + OS << "#endif\n\n"; + + OS << "#ifdef __cplusplus\n"; + OS << "extern \"C\" {\n"; + OS << "#endif\n\n"; + + std::vector> Defs; + createRVVIntrinsics(Defs); + + // Print header code + if (!HeaderCode.empty()) { + OS << HeaderCode; + } + + auto printType = [&](auto T) { + OS << "typedef " << T->getClangBuiltinStr() << " " << T->getTypeStr() + << ";\n"; + }; + + constexpr int Log2LMULs[] = {-3, -2, -1, 0, 1, 2, 3}; + // Print RVV boolean types. + for (int Log2LMUL : Log2LMULs) { + auto T = computeType('c', Log2LMUL, "m"); + if (T.hasValue()) + printType(T.getValue()); + } + // Print RVV int/float types. + for (char I : StringRef("csil")) { + for (int Log2LMUL : Log2LMULs) { + auto T = computeType(I, Log2LMUL, "v"); + if (T.hasValue()) { + printType(T.getValue()); + auto UT = computeType(I, Log2LMUL, "Uv"); + printType(UT.getValue()); + } + } + } + OS << "#if defined(__riscv_zfh)\n"; + for (int Log2LMUL : Log2LMULs) { + auto T = computeType('h', Log2LMUL, "v"); + if (T.hasValue()) + printType(T.getValue()); + } + OS << "#endif\n"; + + OS << "#if defined(__riscv_f)\n"; + for (int Log2LMUL : Log2LMULs) { + auto T = computeType('f', Log2LMUL, "v"); + if (T.hasValue()) + printType(T.getValue()); + } + OS << "#endif\n"; + + OS << "#if defined(__riscv_d)\n"; + for (int Log2LMUL : Log2LMULs) { + auto T = computeType('d', Log2LMUL, "v"); + if (T.hasValue()) + printType(T.getValue()); + } + OS << "#endif\n\n"; + + // The same extension include in the same arch guard marco. + std::stable_sort(Defs.begin(), Defs.end(), + [](const std::unique_ptr &A, + const std::unique_ptr &B) { + return A->getRISCVExtensions() < B->getRISCVExtensions(); + }); + + // Print intrinsic functions with macro + emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) { + Inst.emitIntrinsicMacro(OS); + }); + + OS << "#define __riscv_v_intrinsic_overloading 1\n"; + + // Print Overloaded APIs + OS << "#define __rvv_overloaded static inline " + "__attribute__((__always_inline__, __nodebug__, __overloadable__))\n"; + + emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) { + if (!Inst.isMask() && !Inst.hasNoMaskedOverloaded()) + return; + OS << "__rvv_overloaded "; + Inst.emitMangledFuncDef(OS); + }); + + OS << "\n#ifdef __cplusplus\n"; + OS << "}\n"; + OS << "#endif // __riscv_vector\n"; + OS << "#endif // __RISCV_VECTOR_H\n"; +} + +void RVVEmitter::createBuiltins(raw_ostream &OS) { + std::vector> Defs; + createRVVIntrinsics(Defs); + + OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n"; + OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, " + "ATTRS, \"experimental-v\")\n"; + OS << "#endif\n"; + for (auto &Def : Defs) { + OS << "RISCVV_BUILTIN(__builtin_rvv_" << Def->getName() << ",\"" + << Def->getBuiltinTypeStr() << "\", "; + if (!Def->hasSideEffects()) + OS << "\"n\")\n"; + else + OS << "\"\")\n"; + } + OS << "#undef RISCVV_BUILTIN\n"; +} + +void RVVEmitter::createCodeGen(raw_ostream &OS) { + std::vector> Defs; + createRVVIntrinsics(Defs); + + // The same intrinsic IR name has the same switch body. + std::stable_sort(Defs.begin(), Defs.end(), + [](const std::unique_ptr &A, + const std::unique_ptr &B) { + return A->getIRName() < B->getIRName(); + }); + // Print switch body when the ir name changes from previous iteration. + RVVIntrinsic *PrevDef = Defs.begin()->get(); + for (auto &Def : Defs) { + StringRef CurIRName = Def->getIRName(); + if (CurIRName != PrevDef->getIRName()) { + PrevDef->emitCodeGenSwitchBody(OS); + } + PrevDef = Def.get(); + OS << "case RISCV::BI__builtin_rvv_" << Def->getName() << ":\n"; + } + Defs.back()->emitCodeGenSwitchBody(OS); + OS << "\n"; +} + +void RVVEmitter::parsePrototypes(StringRef Prototypes, + std::function Handler) { + const StringRef Primaries("evwqom0ztc"); + while (!Prototypes.empty()) { + size_t Idx = 0; + // Skip over complex prototype because it could contain primitive type + // character. + if (Prototypes[0] == '(') + Idx = Prototypes.find_first_of(')'); + Idx = Prototypes.find_first_of(Primaries, Idx); + assert(Idx != StringRef::npos); + Handler(Prototypes.slice(0, Idx + 1)); + Prototypes = Prototypes.drop_front(Idx + 1); + } +} + +std::string RVVEmitter::getSuffixStr(char Type, int Log2LMUL, + StringRef Prototypes) { + SmallVector SuffixStrs; + parsePrototypes(Prototypes, [&](StringRef Proto) { + auto T = computeType(Type, Log2LMUL, Proto); + SuffixStrs.push_back(T.getValue()->getShortStr()); + }); + return join(SuffixStrs, "_"); +} + +void RVVEmitter::createRVVIntrinsics( + std::vector> &Out) { + std::vector RV = Records.getAllDerivedDefinitions("RVVBuiltin"); + for (auto *R : RV) { + StringRef Name = R->getValueAsString("Name"); + StringRef SuffixProto = R->getValueAsString("Suffix"); + StringRef MangledName = R->getValueAsString("MangledName"); + StringRef Prototypes = R->getValueAsString("Prototype"); + StringRef TypeRange = R->getValueAsString("TypeRange"); + bool HasMask = R->getValueAsBit("HasMask"); + bool HasMaskedOffOperand = R->getValueAsBit("HasMaskedOffOperand"); + bool HasVL = R->getValueAsBit("HasVL"); + bool HasNoMaskedOverloaded = R->getValueAsBit("HasNoMaskedOverloaded"); + bool HasSideEffects = R->getValueAsBit("HasSideEffects"); + std::vector Log2LMULList = R->getValueAsListOfInts("Log2LMUL"); + StringRef ManualCodegen = R->getValueAsString("ManualCodegen"); + StringRef ManualCodegenMask = R->getValueAsString("ManualCodegenMask"); + std::vector IntrinsicTypes = + R->getValueAsListOfInts("IntrinsicTypes"); + std::vector PermuteOperands = + R->getValueAsListOfInts("PermuteOperands"); + StringRef IRName = R->getValueAsString("IRName"); + StringRef IRNameMask = R->getValueAsString("IRNameMask"); + + StringRef HeaderCodeStr = R->getValueAsString("HeaderCode"); + bool HasAutoDef = HeaderCodeStr.empty(); + if (!HeaderCodeStr.empty()) { + HeaderCode += HeaderCodeStr.str(); + } + // Parse prototype and create a list of primitive type with transformers + // (operand) in ProtoSeq. ProtoSeq[0] is output operand. + SmallVector ProtoSeq; + parsePrototypes(Prototypes, [&ProtoSeq](StringRef Proto) { + ProtoSeq.push_back(Proto.str()); + }); + + // Compute Builtin types + SmallVector ProtoMaskSeq = ProtoSeq; + if (HasMask) { + // If HasMask, append 'm' to last operand. + ProtoMaskSeq.push_back("m"); + // If HasMaskedOffOperand, insert result type as first input operand. + if (HasMaskedOffOperand) + ProtoMaskSeq.insert(ProtoMaskSeq.begin() + 1, ProtoSeq[0]); + } + // If HasVL, append 'z' to last operand + if (HasVL) { + ProtoSeq.push_back("z"); + ProtoMaskSeq.push_back("z"); + } + + // Create Intrinsics for each type and LMUL. + for (char I : TypeRange) { + for (int Log2LMUL : Log2LMULList) { + Optional Types = computeTypes(I, Log2LMUL, ProtoSeq); + // Ignored to create new intrinsic if there are any illegal types. + if (!Types.hasValue()) + continue; + + auto SuffixStr = getSuffixStr(I, Log2LMUL, SuffixProto); + // Create a non-mask intrinsic + Out.push_back(std::make_unique( + Name, SuffixStr, MangledName, IRName, HasSideEffects, + /*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL, + HasNoMaskedOverloaded, HasAutoDef, ManualCodegen, Types.getValue(), + IntrinsicTypes, PermuteOperands)); + if (HasMask) { + // Create a mask intrinsic + Optional MaskTypes = + computeTypes(I, Log2LMUL, ProtoMaskSeq); + Out.push_back(std::make_unique( + Name, SuffixStr, MangledName, IRNameMask, HasSideEffects, + /*IsMask=*/true, HasMaskedOffOperand, HasVL, + HasNoMaskedOverloaded, HasAutoDef, ManualCodegenMask, + MaskTypes.getValue(), IntrinsicTypes, PermuteOperands)); + } + } // end for Log2LMULList + } // end for TypeRange + } +} + +Optional +RVVEmitter::computeTypes(BasicType BT, int Log2LMUL, + ArrayRef PrototypeSeq) { + RVVTypes Types; + for (const std::string &Proto : PrototypeSeq) { + auto T = computeType(BT, Log2LMUL, Proto); + if (!T.hasValue()) + return llvm::None; + // Record legal type index + Types.push_back(T.getValue()); + } + return Types; +} + +Optional RVVEmitter::computeType(BasicType BT, int Log2LMUL, + StringRef Proto) { + std::string Idx = Twine(Twine(BT) + Twine(Log2LMUL) + Proto).str(); + // Search first + auto It = LegalTypes.find(Idx); + if (It != LegalTypes.end()) + return &(It->second); + if (IllegalTypes.count(Idx)) + return llvm::None; + // Compute type and record the result. + RVVType T(BT, Log2LMUL, Proto); + if (T.isValid()) { + // Record legal type index and value. + LegalTypes.insert({Idx, T}); + return &(LegalTypes[Idx]); + } + // Record illegal type index. + IllegalTypes.insert(Idx); + return llvm::None; +} + +void RVVEmitter::emitArchMacroAndBody( + std::vector> &Defs, raw_ostream &OS, + std::function PrintBody) { + uint8_t PrevExt = (*Defs.begin())->getRISCVExtensions(); + bool NeedEndif = emitExtDefStr(PrevExt, OS); + for (auto &Def : Defs) { + uint8_t CurExt = Def->getRISCVExtensions(); + if (CurExt != PrevExt) { + if (NeedEndif) + OS << "#endif\n\n"; + NeedEndif = emitExtDefStr(CurExt, OS); + PrevExt = CurExt; + } + if (Def->hasAutoDef()) + PrintBody(OS, *Def); + } + if (NeedEndif) + OS << "#endif\n\n"; +} + +bool RVVEmitter::emitExtDefStr(uint8_t Extents, raw_ostream &OS) { + if (Extents == RISCVExtension::Basic) + return false; + OS << "#if "; + ListSeparator LS(" || "); + if (Extents & RISCVExtension::F) + OS << LS << "defined(__riscv_f)"; + if (Extents & RISCVExtension::D) + OS << LS << "defined(__riscv_d)"; + if (Extents & RISCVExtension::Zfh) + OS << LS << "defined(__riscv_zfh)"; + OS << "\n"; + return true; +} + +namespace clang { +void EmitRVVHeader(RecordKeeper &Records, raw_ostream &OS) { + RVVEmitter(Records).createHeader(OS); +} + +void EmitRVVBuiltins(RecordKeeper &Records, raw_ostream &OS) { + RVVEmitter(Records).createBuiltins(OS); +} + +void EmitRVVBuiltinCG(RecordKeeper &Records, raw_ostream &OS) { + RVVEmitter(Records).createCodeGen(OS); +} + +} // End namespace clang diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp index 1b919a77988b..55d62fa9f9bd 100644 --- a/clang/utils/TableGen/TableGen.cpp +++ b/clang/utils/TableGen/TableGen.cpp @@ -83,6 +83,9 @@ enum ActionType { GenArmCdeBuiltinSema, GenArmCdeBuiltinCG, GenArmCdeBuiltinAliases, + GenRISCVVectorHeader, + GenRISCVVectorBuiltins, + GenRISCVVectorBuiltinCG, GenAttrDocs, GenDiagDocs, GenOptDocs, @@ -228,6 +231,12 @@ cl::opt Action( "Generate ARM CDE builtin code-generator for clang"), clEnumValN(GenArmCdeBuiltinAliases, "gen-arm-cde-builtin-aliases", "Generate list of valid ARM CDE builtin aliases for clang"), + clEnumValN(GenRISCVVectorHeader, "gen-riscv-vector-header", + "Generate riscv_vector.h for clang"), + clEnumValN(GenRISCVVectorBuiltins, "gen-riscv-vector-builtins", + "Generate riscv_vector_builtins.inc for clang"), + clEnumValN(GenRISCVVectorBuiltinCG, "gen-riscv-vector-builtin-codegen", + "Generate riscv_vector_builtin_cg.inc for clang"), clEnumValN(GenAttrDocs, "gen-attr-docs", "Generate attribute documentation"), clEnumValN(GenDiagDocs, "gen-diag-docs", @@ -428,6 +437,15 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenArmCdeBuiltinAliases: EmitCdeBuiltinAliases(Records, OS); break; + case GenRISCVVectorHeader: + EmitRVVHeader(Records, OS); + break; + case GenRISCVVectorBuiltins: + EmitRVVBuiltins(Records, OS); + break; + case GenRISCVVectorBuiltinCG: + EmitRVVBuiltinCG(Records, OS); + break; case GenAttrDocs: EmitClangAttrDocs(Records, OS); break; diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h index 33a06bfe4469..6930f242681f 100644 --- a/clang/utils/TableGen/TableGenBackends.h +++ b/clang/utils/TableGen/TableGenBackends.h @@ -106,6 +106,10 @@ void EmitMveBuiltinSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitMveBuiltinCG(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitMveBuiltinAliases(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitRVVHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitRVVBuiltins(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitRVVBuiltinCG(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); + void EmitCdeHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitCdeBuiltinDef(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitCdeBuiltinSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index d7baa595d6ee..0660816b83c1 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -63,7 +63,7 @@

C++ Support in Clang

C++2b (tentatively C++23) -std=c++2b - No + Partial @@ -151,7 +151,7 @@

C++11 implementation status

P1957R2 (DR) - Clang 11 + Clang 11 Static assertions @@ -1022,7 +1022,7 @@

C++20 implementation status

[[likely]] and [[unlikely]] attributes P0479R5 - Clang 12 + Clang 12 typename optional in more contexts @@ -1150,7 +1150,7 @@

C++20 implementation status

P1766R1 (DR) - Clang 11 + Clang 11 P1811R0 @@ -1234,7 +1234,7 @@

C++20 implementation status

Pseudo-destructors end object lifetimes P0593R6 (DR) - Clang 11 + Clang 11 More implicit moves @@ -1270,13 +1270,13 @@

C++2b implementation status

Literal suffix uz, z for size_t, ssize_t P0330R8 - No + Clang 13 Make () in lambdas optional in all cases P1102R2 - No + Clang 13 diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake index fe4c61abd403..ca2f34e618ab 100644 --- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake +++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake @@ -124,6 +124,21 @@ macro(set_output_name output name arch) else() if(ANDROID AND ${arch} STREQUAL "i386") set(${output} "${name}-i686${COMPILER_RT_OS_SUFFIX}") + elseif("${arch}" MATCHES "^arm") + if(COMPILER_RT_DEFAULT_TARGET_ONLY) + set(triple "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}") + else() + set(triple "${TARGET_TRIPLE}") + endif() + # When using arch-suffixed runtime library names, clang only looks for + # libraries named "arm" or "armhf", see getArchNameForCompilerRTLib in + # clang. Therefore, try to inspect both the arch name and the triple + # if it seems like we're building an armhf target. + if ("${arch}" MATCHES "hf$" OR "${triple}" MATCHES "hf$") + set(${output} "${name}-armhf${COMPILER_RT_OS_SUFFIX}") + else() + set(${output} "${name}-arm${COMPILER_RT_OS_SUFFIX}") + endif() else() set(${output} "${name}-${arch}${COMPILER_RT_OS_SUFFIX}") endif() diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index 129be87ec5d8..e119e9e42466 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -327,6 +327,14 @@ macro(construct_compiler_rt_default_triple) string(REPLACE "-" ";" TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE}) list(GET TARGET_TRIPLE_LIST 0 COMPILER_RT_DEFAULT_TARGET_ARCH) + + # Map various forms of the architecture names to the canonical forms + # (as they are used by clang, see getArchNameForCompilerRTLib). + if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "^i.86$") + # Android uses i686, but that's remapped at a later stage. + set(COMPILER_RT_DEFAULT_TARGET_ARCH "i386") + endif() + # Determine if test target triple is specified explicitly, and doesn't match the # default. if(NOT COMPILER_RT_DEFAULT_TARGET_TRIPLE STREQUAL TARGET_TRIPLE) diff --git a/compiler-rt/include/fuzzer/FuzzedDataProvider.h b/compiler-rt/include/fuzzer/FuzzedDataProvider.h index 6cbfc39bc20b..71cb427ec4a9 100644 --- a/compiler-rt/include/fuzzer/FuzzedDataProvider.h +++ b/compiler-rt/include/fuzzer/FuzzedDataProvider.h @@ -390,7 +390,7 @@ TS FuzzedDataProvider::ConvertUnsignedToSigned(TU value) { return static_cast(value); } else { constexpr auto TS_min = std::numeric_limits::min(); - return TS_min + static_cast(value - TS_min); + return TS_min + static_cast(value - TS_min); } } diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc index 9112c9fa12b2..ffc7dee4ed6d 100644 --- a/compiler-rt/include/profile/InstrProfData.inc +++ b/compiler-rt/include/profile/InstrProfData.inc @@ -813,6 +813,7 @@ typedef struct InstrProfValueData { * range and used to store in the runtime profile data records and the VP * metadata. For example, it's 2 for [2, 2] and 64 for [65, 127]. */ +#define INSTR_PROF_NUM_BUCKETS 22 /* * Clz and Popcount. This code was copied from @@ -872,7 +873,7 @@ InstrProfGetRangeRepValue(uint64_t Value) { return Value; else // Otherwise, take to the previous power of two + 1. - return (1 << (64 - InstProfClzll(Value) - 1)) + 1; + return (UINT64_C(1) << (64 - InstProfClzll(Value) - 1)) + 1; } /* Return true if the range that an (observed) memop size value belongs to has diff --git a/compiler-rt/include/sanitizer/tsan_interface.h b/compiler-rt/include/sanitizer/tsan_interface.h index 96b8ad58541c..cfa9d3b5f632 100644 --- a/compiler-rt/include/sanitizer/tsan_interface.h +++ b/compiler-rt/include/sanitizer/tsan_interface.h @@ -141,7 +141,7 @@ void __tsan_external_write(void *addr, void *caller_pc, void *tag); // and freed by __tsan_destroy_fiber. // - TSAN context of current fiber or thread can be obtained // by calling __tsan_get_current_fiber. -// - __tsan_switch_to_fiber should be called immediatly before switch +// - __tsan_switch_to_fiber should be called immediately before switch // to fiber, such as call of swapcontext. // - Fiber name can be set by __tsan_set_fiber_name. void *__tsan_get_current_fiber(void); @@ -154,6 +154,15 @@ void __tsan_set_fiber_name(void *fiber, const char *name); // Do not establish a happens-before relation between fibers static const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0; +// User-provided callback invoked on TSan initialization. +void __tsan_on_initialize(); + +// User-provided callback invoked on TSan shutdown. +// `failed` - Nonzero if TSan did detect issues, zero otherwise. +// Return `0` if TSan should exit as if no issues were detected. Return nonzero +// if TSan should exit as if issues were detected. +int __tsan_on_finalize(int failed); + #ifdef __cplusplus } // extern "C" #endif diff --git a/compiler-rt/lib/asan/asan_descriptions.cpp b/compiler-rt/lib/asan/asan_descriptions.cpp index 153c874a4e77..42f2215c14d6 100644 --- a/compiler-rt/lib/asan/asan_descriptions.cpp +++ b/compiler-rt/lib/asan/asan_descriptions.cpp @@ -48,7 +48,7 @@ void DescribeThread(AsanThreadContext *context) { return; } context->announced = true; - InternalScopedString str(1024); + InternalScopedString str; str.append("Thread %s", AsanThreadIdAndName(context).c_str()); if (context->parent_tid == kInvalidTid) { str.append(" created by unknown thread\n"); @@ -77,7 +77,6 @@ static bool GetShadowKind(uptr addr, ShadowKind *shadow_kind) { } else if (AddrIsInLowShadow(addr)) { *shadow_kind = kShadowKindLow; } else { - CHECK(0 && "Address is not in memory and not in shadow?"); return false; } return true; @@ -126,7 +125,7 @@ static void GetAccessToHeapChunkInformation(ChunkAccess *descr, static void PrintHeapChunkAccess(uptr addr, const ChunkAccess &descr) { Decorator d; - InternalScopedString str(4096); + InternalScopedString str; str.append("%s", d.Location()); switch (descr.access_type) { case kAccessTypeLeft: @@ -243,7 +242,7 @@ static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr, else if (addr >= prev_var_end && addr - prev_var_end >= var.beg - addr_end) pos_descr = "underflows"; } - InternalScopedString str(1024); + InternalScopedString str; str.append(" [%zd, %zd)", var.beg, var_end); // Render variable name. str.append(" '"); @@ -276,7 +275,7 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) { // Global descriptions static void DescribeAddressRelativeToGlobal(uptr addr, uptr access_size, const __asan_global &g) { - InternalScopedString str(4096); + InternalScopedString str; Decorator d; str.append("%s", d.Location()); if (addr < g.beg) { @@ -464,7 +463,13 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size, return; } data.kind = kAddressKindWild; - addr = 0; + data.wild.addr = addr; + data.wild.access_size = access_size; +} + +void WildAddressDescription::Print() const { + Printf("Address %p is a wild pointer inside of access range of size %p.\n", + addr, access_size); } void PrintAddressDescription(uptr addr, uptr access_size, diff --git a/compiler-rt/lib/asan/asan_descriptions.h b/compiler-rt/lib/asan/asan_descriptions.h index ee0e2061559e..650e2eb9173a 100644 --- a/compiler-rt/lib/asan/asan_descriptions.h +++ b/compiler-rt/lib/asan/asan_descriptions.h @@ -146,6 +146,13 @@ struct StackAddressDescription { bool GetStackAddressInformation(uptr addr, uptr access_size, StackAddressDescription *descr); +struct WildAddressDescription { + uptr addr; + uptr access_size; + + void Print() const; +}; + struct GlobalAddressDescription { uptr addr; // Assume address is close to at most four globals. @@ -193,7 +200,7 @@ class AddressDescription { HeapAddressDescription heap; StackAddressDescription stack; GlobalAddressDescription global; - uptr addr; + WildAddressDescription wild; }; }; @@ -211,7 +218,7 @@ class AddressDescription { uptr Address() const { switch (data.kind) { case kAddressKindWild: - return data.addr; + return data.wild.addr; case kAddressKindShadow: return data.shadow.addr; case kAddressKindHeap: @@ -226,7 +233,7 @@ class AddressDescription { void Print(const char *bug_descr = nullptr) const { switch (data.kind) { case kAddressKindWild: - Printf("Address %p is a wild pointer.\n", data.addr); + data.wild.Print(); return; case kAddressKindShadow: return data.shadow.Print(); diff --git a/compiler-rt/lib/asan/asan_errors.cpp b/compiler-rt/lib/asan/asan_errors.cpp index 541c6e0353b5..e68e6971f963 100644 --- a/compiler-rt/lib/asan/asan_errors.cpp +++ b/compiler-rt/lib/asan/asan_errors.cpp @@ -343,7 +343,8 @@ void ErrorODRViolation::Print() { Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(), global1.beg); Printf("%s", d.Default()); - InternalScopedString g1_loc(256), g2_loc(256); + InternalScopedString g1_loc; + InternalScopedString g2_loc; PrintGlobalLocation(&g1_loc, global1); PrintGlobalLocation(&g2_loc, global2); Printf(" [1] size=%zd '%s' %s\n", global1.size, @@ -360,7 +361,7 @@ void ErrorODRViolation::Print() { Report( "HINT: if you don't care about these errors you may set " "ASAN_OPTIONS=detect_odr_violation=0\n"); - InternalScopedString error_msg(256); + InternalScopedString error_msg; error_msg.append("%s: global '%s' at %s", scariness.GetDescription(), MaybeDemangleGlobalName(global1.name), g1_loc.data()); ReportErrorSummary(error_msg.data()); @@ -554,7 +555,7 @@ static void PrintShadowMemoryForAddress(uptr addr) { uptr shadow_addr = MemToShadow(addr); const uptr n_bytes_per_row = 16; uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1); - InternalScopedString str(4096 * 8); + InternalScopedString str; str.append("Shadow bytes around the buggy address:\n"); for (int i = -5; i <= 5; i++) { uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row; diff --git a/compiler-rt/lib/asan/asan_fake_stack.cpp b/compiler-rt/lib/asan/asan_fake_stack.cpp index 295e6debc96c..1f873fec7d7c 100644 --- a/compiler-rt/lib/asan/asan_fake_stack.cpp +++ b/compiler-rt/lib/asan/asan_fake_stack.cpp @@ -65,7 +65,7 @@ FakeStack *FakeStack::Create(uptr stack_size_log) { void FakeStack::Destroy(int tid) { PoisonAll(0); if (Verbosity() >= 2) { - InternalScopedString str(kNumberOfSizeClasses * 50); + InternalScopedString str; for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) str.append("%zd: %zd/%zd; ", class_id, hint_position_[class_id], NumberOfFrames(stack_size_log(), class_id)); diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp index 7b5a929963c6..106a52607631 100644 --- a/compiler-rt/lib/asan/asan_rtl.cpp +++ b/compiler-rt/lib/asan/asan_rtl.cpp @@ -490,9 +490,6 @@ static void AsanInitInternal() { if (flags()->start_deactivated) AsanDeactivate(); - // interceptors - InitTlsSize(); - // Create main thread. AsanThread *main_thread = CreateMainThread(); CHECK_EQ(0, main_thread->tid()); @@ -568,7 +565,7 @@ void UnpoisonStack(uptr bottom, uptr top, const char *type) { type, top, bottom, top - bottom, top - bottom); return; } - PoisonShadow(bottom, top - bottom, 0); + PoisonShadow(bottom, RoundUpTo(top - bottom, SHADOW_GRANULARITY), 0); } static void UnpoisonDefaultStack() { diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp index ae3bcba204c6..f7778c0f1e34 100644 --- a/compiler-rt/lib/asan/asan_thread.cpp +++ b/compiler-rt/lib/asan/asan_thread.cpp @@ -307,7 +307,7 @@ void AsanThread::SetThreadStackAndTls(const InitOptions *options) { uptr stack_size = 0; GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size, &tls_begin_, &tls_size); - stack_top_ = stack_bottom_ + stack_size; + stack_top_ = RoundDownTo(stack_bottom_ + stack_size, SHADOW_GRANULARITY); tls_end_ = tls_begin_ + tls_size; dtls_ = DTLS_Get(); diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 73b6bead8424..c81c535c8538 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -5,6 +5,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) cmake_minimum_required(VERSION 3.13.4) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) project(CompilerRTBuiltins C ASM) set(COMPILER_RT_STANDALONE_BUILD TRUE) set(COMPILER_RT_BUILTINS_STANDALONE_BUILD TRUE) @@ -488,7 +489,7 @@ if(MINGW) arm/aeabi_uldivmod.S arm/chkstk.S mingw_fixfloat.c - ${GENERIC_SOURCES} + ${arm_SOURCES} ) elseif(NOT WIN32) # TODO the EABI sources should only be added to EABI targets @@ -626,7 +627,12 @@ if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX") endif() set(powerpc64le_SOURCES ${powerpc64_SOURCES}) -set(riscv_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES}) +set(riscv_SOURCES + riscv/save.S + riscv/restore.S + ${GENERIC_SOURCES} + ${GENERIC_TF_SOURCES} +) set(riscv32_SOURCES riscv/mulsi3.S ${riscv_SOURCES} @@ -701,10 +707,11 @@ else () list(REMOVE_ITEM ${arch}_SOURCES ${arm_Thumb1_VFPv2_DP_SOURCES} ${arm_Thumb1_VFPv2_SP_SOURCES} ${arm_Thumb1_SjLj_EH_SOURCES}) else() # Exclude any double-precision builtins if VFP is single-precision-only - check_c_source_compiles("#if !(__ARM_FP & 0x8) + try_compile_only(COMPILER_RT_HAS_${arch}_VFP_DP + SOURCE "#if !(__ARM_FP & 0x8) #error No double-precision support! #endif - int main() { return 0; }" COMPILER_RT_HAS_${arch}_VFP_DP) + int main() { return 0; }") if(NOT COMPILER_RT_HAS_${arch}_VFP_DP) list(REMOVE_ITEM ${arch}_SOURCES ${arm_Thumb1_VFPv2_DP_SOURCES}) endif() diff --git a/compiler-rt/lib/builtins/arm/fp_mode.c b/compiler-rt/lib/builtins/arm/fp_mode.c index 300b71935ad4..c0ca9095142e 100644 --- a/compiler-rt/lib/builtins/arm/fp_mode.c +++ b/compiler-rt/lib/builtins/arm/fp_mode.c @@ -18,7 +18,7 @@ ARM_DOWNWARD | ARM_TOWARDZERO) #define ARM_RMODE_SHIFT 22 -#define ARM_INEXACT 0x1000 +#define ARM_INEXACT 0x10 #ifndef __ARM_FP // For soft float targets, allow changing rounding mode by overriding the weak diff --git a/compiler-rt/lib/builtins/riscv/restore.S b/compiler-rt/lib/builtins/riscv/restore.S new file mode 100644 index 000000000000..12f0d3365655 --- /dev/null +++ b/compiler-rt/lib/builtins/riscv/restore.S @@ -0,0 +1,166 @@ +//===-- restore.S - restore up to 12 callee-save registers ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Multiple entry points depending on number of registers to restore +// +//===----------------------------------------------------------------------===// + +// All of the entry points are in the same section since we rely on many of +// them falling through into each other and don't want the linker to +// accidentally split them up, garbage collect, or reorder them. +// +// The entry points are grouped up into 2s for rv64 and 4s for rv32 since this +// is the minimum grouping which will maintain the required 16-byte stack +// alignment. + + .text + +#if __riscv_xlen == 32 + + .globl __riscv_restore_12 + .type __riscv_restore_12,@function +__riscv_restore_12: + lw s11, 12(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_11/10/9/8 + + .globl __riscv_restore_11 + .type __riscv_restore_11,@function + .globl __riscv_restore_10 + .type __riscv_restore_10,@function + .globl __riscv_restore_9 + .type __riscv_restore_9,@function + .globl __riscv_restore_8 + .type __riscv_restore_8,@function +__riscv_restore_11: +__riscv_restore_10: +__riscv_restore_9: +__riscv_restore_8: + lw s10, 0(sp) + lw s9, 4(sp) + lw s8, 8(sp) + lw s7, 12(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_7/6/5/4 + + .globl __riscv_restore_7 + .type __riscv_restore_7,@function + .globl __riscv_restore_6 + .type __riscv_restore_6,@function + .globl __riscv_restore_5 + .type __riscv_restore_5,@function + .globl __riscv_restore_4 + .type __riscv_restore_4,@function +__riscv_restore_7: +__riscv_restore_6: +__riscv_restore_5: +__riscv_restore_4: + lw s6, 0(sp) + lw s5, 4(sp) + lw s4, 8(sp) + lw s3, 12(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_3/2/1/0 + + .globl __riscv_restore_3 + .type __riscv_restore_3,@function + .globl __riscv_restore_2 + .type __riscv_restore_2,@function + .globl __riscv_restore_1 + .type __riscv_restore_1,@function + .globl __riscv_restore_0 + .type __riscv_restore_0,@function +__riscv_restore_3: +__riscv_restore_2: +__riscv_restore_1: +__riscv_restore_0: + lw s2, 0(sp) + lw s1, 4(sp) + lw s0, 8(sp) + lw ra, 12(sp) + addi sp, sp, 16 + ret + +#elif __riscv_xlen == 64 + + .globl __riscv_restore_12 + .type __riscv_restore_12,@function +__riscv_restore_12: + ld s11, 8(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_11/10/9/8 + + .globl __riscv_restore_11 + .type __riscv_restore_11,@function + .globl __riscv_restore_10 + .type __riscv_restore_10,@function +__riscv_restore_11: +__riscv_restore_10: + ld s10, 0(sp) + ld s9, 8(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_9/8 + + .globl __riscv_restore_9 + .type __riscv_restore_9,@function + .globl __riscv_restore_8 + .type __riscv_restore_8,@function +__riscv_restore_9: +__riscv_restore_8: + ld s8, 0(sp) + ld s7, 8(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_7/6 + + .globl __riscv_restore_7 + .type __riscv_restore_7,@function + .globl __riscv_restore_6 + .type __riscv_restore_6,@function +__riscv_restore_7: +__riscv_restore_6: + ld s6, 0(sp) + ld s5, 8(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_5/4 + + .globl __riscv_restore_5 + .type __riscv_restore_5,@function + .globl __riscv_restore_4 + .type __riscv_restore_4,@function +__riscv_restore_5: +__riscv_restore_4: + ld s4, 0(sp) + ld s3, 8(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_3/2 + + .globl __riscv_restore_3 + .type __riscv_restore_3,@function + .globl __riscv_restore_2 + .type __riscv_restore_2,@function + .globl __riscv_restore_1 + .type __riscv_restore_1,@function + .globl __riscv_restore_0 + .type __riscv_restore_0,@function +__riscv_restore_3: +__riscv_restore_2: + ld s2, 0(sp) + ld s1, 8(sp) + addi sp, sp, 16 + // fallthrough into __riscv_restore_1/0 + +__riscv_restore_1: +__riscv_restore_0: + ld s0, 0(sp) + ld ra, 8(sp) + addi sp, sp, 16 + ret + +#else +# error "xlen must be 32 or 64 for save-restore implementation +#endif diff --git a/compiler-rt/lib/builtins/riscv/save.S b/compiler-rt/lib/builtins/riscv/save.S new file mode 100644 index 000000000000..d811bf584fc3 --- /dev/null +++ b/compiler-rt/lib/builtins/riscv/save.S @@ -0,0 +1,184 @@ +//===-- save.S - save up to 12 callee-saved registers ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Multiple entry points depending on number of registers to save +// +//===----------------------------------------------------------------------===// + +// The entry points are grouped up into 2s for rv64 and 4s for rv32 since this +// is the minimum grouping which will maintain the required 16-byte stack +// alignment. + + .text + +#if __riscv_xlen == 32 + + .globl __riscv_save_12 + .type __riscv_save_12,@function +__riscv_save_12: + addi sp, sp, -64 + mv t1, zero + sw s11, 12(sp) + j .Lriscv_save_11_8 + + .globl __riscv_save_11 + .type __riscv_save_11,@function + .globl __riscv_save_10 + .type __riscv_save_10,@function + .globl __riscv_save_9 + .type __riscv_save_9,@function + .globl __riscv_save_8 + .type __riscv_save_8,@function +__riscv_save_11: +__riscv_save_10: +__riscv_save_9: +__riscv_save_8: + addi sp, sp, -64 + li t1, 16 +.Lriscv_save_11_8: + sw s10, 16(sp) + sw s9, 20(sp) + sw s8, 24(sp) + sw s7, 28(sp) + j .Lriscv_save_7_4 + + .globl __riscv_save_7 + .type __riscv_save_7,@function + .globl __riscv_save_6 + .type __riscv_save_6,@function + .globl __riscv_save_5 + .type __riscv_save_5,@function + .globl __riscv_save_4 + .type __riscv_save_4,@function +__riscv_save_7: +__riscv_save_6: +__riscv_save_5: +__riscv_save_4: + addi sp, sp, -64 + li t1, 32 +.Lriscv_save_7_4: + sw s6, 32(sp) + sw s5, 36(sp) + sw s4, 40(sp) + sw s3, 44(sp) + sw s2, 48(sp) + sw s1, 52(sp) + sw s0, 56(sp) + sw ra, 60(sp) + add sp, sp, t1 + jr t0 + + .globl __riscv_save_3 + .type __riscv_save_3,@function + .globl __riscv_save_2 + .type __riscv_save_2,@function + .globl __riscv_save_1 + .type __riscv_save_1,@function + .globl __riscv_save_0 + .type __riscv_save_0,@function +__riscv_save_3: +__riscv_save_2: +__riscv_save_1: +__riscv_save_0: + addi sp, sp, -16 + sw s2, 0(sp) + sw s1, 4(sp) + sw s0, 8(sp) + sw ra, 12(sp) + jr t0 + +#elif __riscv_xlen == 64 + + .globl __riscv_save_12 + .type __riscv_save_12,@function +__riscv_save_12: + addi sp, sp, -112 + mv t1, zero + sd s11, 8(sp) + j .Lriscv_save_11_10 + + .globl __riscv_save_11 + .type __riscv_save_11,@function + .globl __riscv_save_10 + .type __riscv_save_10,@function +__riscv_save_11: +__riscv_save_10: + addi sp, sp, -112 + li t1, 16 +.Lriscv_save_11_10: + sd s10, 16(sp) + sd s9, 24(sp) + j .Lriscv_save_9_8 + + .globl __riscv_save_9 + .type __riscv_save_9,@function + .globl __riscv_save_8 + .type __riscv_save_8,@function +__riscv_save_9: +__riscv_save_8: + addi sp, sp, -112 + li t1, 32 +.Lriscv_save_9_8: + sd s8, 32(sp) + sd s7, 40(sp) + j .Lriscv_save_7_6 + + .globl __riscv_save_7 + .type __riscv_save_7,@function + .globl __riscv_save_6 + .type __riscv_save_6,@function +__riscv_save_7: +__riscv_save_6: + addi sp, sp, -112 + li t1, 48 +.Lriscv_save_7_6: + sd s6, 48(sp) + sd s5, 56(sp) + j .Lriscv_save_5_4 + + .globl __riscv_save_5 + .type __riscv_save_5,@function + .globl __riscv_save_4 + .type __riscv_save_4,@function +__riscv_save_5: +__riscv_save_4: + addi sp, sp, -112 + li t1, 64 +.Lriscv_save_5_4: + sd s4, 64(sp) + sd s3, 72(sp) + j .Lriscv_save_3_2 + + .globl __riscv_save_3 + .type __riscv_save_3,@function + .globl __riscv_save_2 + .type __riscv_save_2,@function +__riscv_save_3: +__riscv_save_2: + addi sp, sp, -112 + li t1, 80 +.Lriscv_save_3_2: + sd s2, 80(sp) + sd s1, 88(sp) + sd s0, 96(sp) + sd ra, 104(sp) + add sp, sp, t1 + jr t0 + + .globl __riscv_save_1 + .type __riscv_save_1,@function + .globl __riscv_save_0 + .type __riscv_save_0,@function + addi sp, sp, -16 + sd s0, 0(sp) + sd ra, 8(sp) + jr t0 + +#else +# error "xlen must be 32 or 64 for save-restore implementation +#endif diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp index da01a63fa86d..2aff8869d2cf 100644 --- a/compiler-rt/lib/dfsan/dfsan.cpp +++ b/compiler-rt/lib/dfsan/dfsan.cpp @@ -708,6 +708,14 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label __dfso_dfsan_get_label( return data_label; } +// This function is used if dfsan_get_origin is called when origin tracking is +// off. +extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin __dfsw_dfsan_get_origin( + long data, dfsan_label data_label, dfsan_label *ret_label) { + *ret_label = 0; + return 0; +} + extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin __dfso_dfsan_get_origin( long data, dfsan_label data_label, dfsan_label *ret_label, dfsan_origin data_origin, dfsan_origin *ret_origin) { @@ -728,6 +736,13 @@ dfsan_read_origin_of_first_taint(const void *addr, uptr size) { return GetOriginIfTainted((uptr)addr, size); } +SANITIZER_INTERFACE_ATTRIBUTE void dfsan_set_label_origin(dfsan_label label, + dfsan_origin origin, + void *addr, + uptr size) { + __dfsan_set_label(label, origin, addr, size); +} + extern "C" SANITIZER_INTERFACE_ATTRIBUTE const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label) { return &__dfsan_label_info[label]; @@ -847,6 +862,7 @@ dfsan_get_init_origin(const void *addr) { dfsan_origin origin_id = o.raw_id(); while (o.isChainedOrigin()) { StackTrace stack; + origin_id = o.raw_id(); o = o.getNextChainedOrigin(&stack); } return origin_id; diff --git a/compiler-rt/lib/dfsan/dfsan.h b/compiler-rt/lib/dfsan/dfsan.h index c2f173f079ff..73b4e4dcd297 100644 --- a/compiler-rt/lib/dfsan/dfsan.h +++ b/compiler-rt/lib/dfsan/dfsan.h @@ -48,6 +48,10 @@ void dfsan_clear_thread_local_state(); // from the address addr. dfsan_origin dfsan_read_origin_of_first_taint(const void *addr, uptr size); +// Set the data within [addr, addr+size) with label and origin. +void dfsan_set_label_origin(dfsan_label label, dfsan_origin origin, void *addr, + uptr size); + // Copy or move the origins of the len bytes from src to dst. void dfsan_mem_origin_transfer(const void *dst, const void *src, uptr len); } // extern "C" diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp index 72c1065939d0..667743f8d8c5 100644 --- a/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -1,4 +1,4 @@ -//===-- dfsan.cpp ---------------------------------------------------------===// +//===-- dfsan_custom.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -37,10 +37,12 @@ #include #include "dfsan/dfsan.h" +#include "dfsan/dfsan_chained_origin_depot.h" #include "dfsan/dfsan_thread.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_linux.h" +#include "sanitizer_common/sanitizer_stackdepot.h" using namespace __dfsan; @@ -87,6 +89,14 @@ __dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_stat( + const char *path, struct stat *buf, dfsan_label path_label, + dfsan_label buf_label, dfsan_label *ret_label, dfsan_origin path_origin, + dfsan_origin buf_origin, dfsan_origin *ret_origin) { + int ret = __dfsw_stat(path, buf, path_label, buf_label, ret_label); + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf, dfsan_label fd_label, dfsan_label buf_label, @@ -98,27 +108,58 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf, return ret; } -SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c, - dfsan_label s_label, - dfsan_label c_label, - dfsan_label *ret_label) { +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_fstat( + int fd, struct stat *buf, dfsan_label fd_label, dfsan_label buf_label, + dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, + dfsan_origin *ret_origin) { + int ret = __dfsw_fstat(fd, buf, fd_label, buf_label, ret_label); + return ret; +} + +static char *dfsan_strchr_with_label(const char *s, int c, size_t *bytes_read, + dfsan_label s_label, dfsan_label c_label, + dfsan_label *ret_label) { + char *match_pos = nullptr; for (size_t i = 0;; ++i) { if (s[i] == c || s[i] == 0) { - if (flags().strict_data_dependencies) { - *ret_label = s_label; - } else { - *ret_label = dfsan_union(dfsan_read_label(s, i + 1), - dfsan_union(s_label, c_label)); - } - // If s[i] is the \0 at the end of the string, and \0 is not the // character we are searching for, then return null. - if (s[i] == 0 && c != 0) { - return nullptr; - } - return const_cast(s + i); + *bytes_read = i + 1; + match_pos = s[i] == 0 && c != 0 ? nullptr : const_cast(s + i); + break; } } + if (flags().strict_data_dependencies) + *ret_label = s_label; + else + *ret_label = dfsan_union(dfsan_read_label(s, *bytes_read), + dfsan_union(s_label, c_label)); + return match_pos; +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c, + dfsan_label s_label, + dfsan_label c_label, + dfsan_label *ret_label) { + size_t bytes_read; + return dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, + ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strchr( + const char *s, int c, dfsan_label s_label, dfsan_label c_label, + dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin, + dfsan_origin *ret_origin) { + size_t bytes_read; + char *r = + dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, ret_label); + if (flags().strict_data_dependencies) { + *ret_origin = s_origin; + } else if (*ret_label) { + dfsan_origin o = dfsan_read_origin_of_first_taint(s, bytes_read); + *ret_origin = o ? o : (s_label ? s_origin : c_origin); + } + return r; } SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s, @@ -139,36 +180,87 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s, return const_cast(ret); } +SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strpbrk( + const char *s, const char *accept, dfsan_label s_label, + dfsan_label accept_label, dfsan_label *ret_label, dfsan_origin s_origin, + dfsan_origin accept_origin, dfsan_origin *ret_origin) { + const char *ret = __dfsw_strpbrk(s, accept, s_label, accept_label, ret_label); + if (flags().strict_data_dependencies) { + if (ret) + *ret_origin = s_origin; + } else { + if (*ret_label) { + size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1; + dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_bytes_read); + if (o) { + *ret_origin = o; + } else { + o = dfsan_read_origin_of_first_taint(accept, strlen(accept) + 1); + *ret_origin = o ? o : (s_label ? s_origin : accept_origin); + } + } + } + return const_cast(ret); +} + static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n, - dfsan_label s1_label, dfsan_label s2_label, - dfsan_label n_label, dfsan_label *ret_label) { + size_t *bytes_read) { const char *cs1 = (const char *) s1, *cs2 = (const char *) s2; for (size_t i = 0; i != n; ++i) { if (cs1[i] != cs2[i]) { - if (flags().strict_data_dependencies) { - *ret_label = 0; - } else { - *ret_label = dfsan_union(dfsan_read_label(cs1, i + 1), - dfsan_read_label(cs2, i + 1)); - } + *bytes_read = i + 1; return cs1[i] - cs2[i]; } } - - if (flags().strict_data_dependencies) { - *ret_label = 0; - } else { - *ret_label = dfsan_union(dfsan_read_label(cs1, n), - dfsan_read_label(cs2, n)); - } + *bytes_read = n; return 0; } +static dfsan_label dfsan_get_memcmp_label(const void *s1, const void *s2, + size_t pos) { + if (flags().strict_data_dependencies) + return 0; + return dfsan_union(dfsan_read_label(s1, pos), dfsan_read_label(s2, pos)); +} + +static void dfsan_get_memcmp_origin(const void *s1, const void *s2, size_t pos, + dfsan_label *ret_label, + dfsan_origin *ret_origin) { + *ret_label = dfsan_get_memcmp_label(s1, s2, pos); + if (*ret_label == 0) + return; + dfsan_origin o = dfsan_read_origin_of_first_taint(s1, pos); + *ret_origin = o ? o : dfsan_read_origin_of_first_taint(s2, pos); +} + +static int dfsan_memcmp_bcmp_label(const void *s1, const void *s2, size_t n, + dfsan_label *ret_label) { + size_t bytes_read; + int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read); + *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); + return r; +} + +static int dfsan_memcmp_bcmp_origin(const void *s1, const void *s2, size_t n, + dfsan_label *ret_label, + dfsan_origin *ret_origin) { + size_t bytes_read; + int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read); + dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); + return r; +} + DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc, const void *s1, const void *s2, size_t n, dfsan_label s1_label, dfsan_label s2_label, dfsan_label n_label) +DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, uptr caller_pc, + const void *s1, const void *s2, size_t n, + dfsan_label s1_label, dfsan_label s2_label, + dfsan_label n_label, dfsan_origin s1_origin, + dfsan_origin s2_origin, dfsan_origin n_origin) + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2, size_t n, dfsan_label s1_label, dfsan_label s2_label, @@ -176,7 +268,18 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2, dfsan_label *ret_label) { CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n, s1_label, s2_label, n_label); - return dfsan_memcmp_bcmp(s1, s2, n, s1_label, s2_label, n_label, ret_label); + return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_memcmp( + const void *s1, const void *s2, size_t n, dfsan_label s1_label, + dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, + dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, + dfsan_origin *ret_origin) { + CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, GET_CALLER_PC(), s1, + s2, n, s1_label, s2_label, n_label, s1_origin, + s2_origin, n_origin); + return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin); } SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2, @@ -184,51 +287,97 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2, dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) { - return dfsan_memcmp_bcmp(s1, s2, n, s1_label, s2_label, n_label, ret_label); + return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_bcmp( + const void *s1, const void *s2, size_t n, dfsan_label s1_label, + dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, + dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, + dfsan_origin *ret_origin) { + return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin); +} + +// When n == 0, compare strings without byte limit. +// When n > 0, compare the first (at most) n bytes of s1 and s2. +static int dfsan_strncmp(const char *s1, const char *s2, size_t n, + size_t *bytes_read) { + for (size_t i = 0;; ++i) { + if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || (n > 0 && i == n - 1)) { + *bytes_read = i + 1; + return s1[i] - s2[i]; + } + } } DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc, const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label) +DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, uptr caller_pc, + const char *s1, const char *s2, + dfsan_label s1_label, dfsan_label s2_label, + dfsan_origin s1_origin, dfsan_origin s2_origin) + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, dfsan_label *ret_label) { CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2, s1_label, s2_label); - for (size_t i = 0;; ++i) { - if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0) { - if (flags().strict_data_dependencies) { - *ret_label = 0; - } else { - *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), - dfsan_read_label(s2, i + 1)); - } - return s1[i] - s2[i]; - } - } - return 0; -} - -SANITIZER_INTERFACE_ATTRIBUTE int -__dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label, - dfsan_label s2_label, dfsan_label *ret_label) { + size_t bytes_read; + int r = dfsan_strncmp(s1, s2, 0, &bytes_read); + *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); + return r; +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcmp( + const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, + dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin, + dfsan_origin *ret_origin) { + CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, GET_CALLER_PC(), s1, + s2, s1_label, s2_label, s1_origin, s2_origin); + size_t bytes_read; + int r = dfsan_strncmp(s1, s2, 0, &bytes_read); + dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); + return r; +} + +// When n == 0, compare strings without byte limit. +// When n > 0, compare the first (at most) n bytes of s1 and s2. +static int dfsan_strncasecmp(const char *s1, const char *s2, size_t n, + size_t *bytes_read) { for (size_t i = 0;; ++i) { char s1_lower = tolower(s1[i]); char s2_lower = tolower(s2[i]); - if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0) { - if (flags().strict_data_dependencies) { - *ret_label = 0; - } else { - *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), - dfsan_read_label(s2, i + 1)); - } + if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 || + (n > 0 && i == n - 1)) { + *bytes_read = i + 1; return s1_lower - s2_lower; } } - return 0; +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcasecmp(const char *s1, + const char *s2, + dfsan_label s1_label, + dfsan_label s2_label, + dfsan_label *ret_label) { + size_t bytes_read; + int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read); + *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); + return r; +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcasecmp( + const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, + dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin, + dfsan_origin *ret_origin) { + size_t bytes_read; + int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read); + dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); + return r; } DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc, @@ -236,6 +385,12 @@ DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc, dfsan_label s1_label, dfsan_label s2_label, dfsan_label n_label) +DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, uptr caller_pc, + const char *s1, const char *s2, size_t n, + dfsan_label s1_label, dfsan_label s2_label, + dfsan_label n_label, dfsan_origin s1_origin, + dfsan_origin s2_origin, dfsan_origin n_origin) + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2, size_t n, dfsan_label s1_label, dfsan_label s2_label, @@ -249,44 +404,60 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2, CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2, n, s1_label, s2_label, n_label); - for (size_t i = 0;; ++i) { - if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n - 1) { - if (flags().strict_data_dependencies) { - *ret_label = 0; - } else { - *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), - dfsan_read_label(s2, i + 1)); - } - return s1[i] - s2[i]; - } + size_t bytes_read; + int r = dfsan_strncmp(s1, s2, n, &bytes_read); + *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); + return r; +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncmp( + const char *s1, const char *s2, size_t n, dfsan_label s1_label, + dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, + dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, + dfsan_origin *ret_origin) { + if (n == 0) { + *ret_label = 0; + return 0; } - return 0; + + CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, GET_CALLER_PC(), + s1, s2, n, s1_label, s2_label, n_label, s1_origin, + s2_origin, n_origin); + + size_t bytes_read; + int r = dfsan_strncmp(s1, s2, n, &bytes_read); + dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); + return r; } -SANITIZER_INTERFACE_ATTRIBUTE int -__dfsw_strncasecmp(const char *s1, const char *s2, size_t n, - dfsan_label s1_label, dfsan_label s2_label, - dfsan_label n_label, dfsan_label *ret_label) { +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncasecmp( + const char *s1, const char *s2, size_t n, dfsan_label s1_label, + dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) { if (n == 0) { *ret_label = 0; return 0; } - for (size_t i = 0;; ++i) { - char s1_lower = tolower(s1[i]); - char s2_lower = tolower(s2[i]); + size_t bytes_read; + int r = dfsan_strncasecmp(s1, s2, n, &bytes_read); + *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); + return r; +} - if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 || i == n - 1) { - if (flags().strict_data_dependencies) { - *ret_label = 0; - } else { - *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), - dfsan_read_label(s2, i + 1)); - } - return s1_lower - s2_lower; - } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncasecmp( + const char *s1, const char *s2, size_t n, dfsan_label s1_label, + dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, + dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, + dfsan_origin *ret_origin) { + if (n == 0) { + *ret_label = 0; + return 0; } - return 0; + + size_t bytes_read; + int r = dfsan_strncasecmp(s1, s2, n, &bytes_read); + dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); + return r; } SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size, @@ -299,6 +470,15 @@ SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size, return p; } +SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_calloc( + size_t nmemb, size_t size, dfsan_label nmemb_label, dfsan_label size_label, + dfsan_label *ret_label, dfsan_origin nmemb_origin, dfsan_origin size_origin, + dfsan_origin *ret_origin) { + void *p = __dfsw_calloc(nmemb, size, nmemb_label, size_label, ret_label); + *ret_origin = 0; + return p; +} + SANITIZER_INTERFACE_ATTRIBUTE size_t __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) { size_t ret = strlen(s); @@ -310,6 +490,17 @@ __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) { return ret; } +SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strlen(const char *s, + dfsan_label s_label, + dfsan_label *ret_label, + dfsan_origin s_origin, + dfsan_origin *ret_origin) { + size_t ret = __dfsw_strlen(s, s_label, ret_label); + if (!flags().strict_data_dependencies) + *ret_origin = dfsan_read_origin_of_first_taint(s, ret + 1); + return ret; +} + static void *dfsan_memmove(void *dest, const void *src, size_t n) { dfsan_label *sdest = shadow_for(dest); const dfsan_label *ssrc = shadow_for(src); @@ -317,6 +508,11 @@ static void *dfsan_memmove(void *dest, const void *src, size_t n) { return internal_memmove(dest, src, n); } +static void *dfsan_memmove_with_origin(void *dest, const void *src, size_t n) { + dfsan_mem_origin_transfer(dest, src, n); + return dfsan_memmove(dest, src, n); +} + static void *dfsan_memcpy(void *dest, const void *src, size_t n) { dfsan_label *sdest = shadow_for(dest); const dfsan_label *ssrc = shadow_for(src); @@ -324,11 +520,22 @@ static void *dfsan_memcpy(void *dest, const void *src, size_t n) { return internal_memcpy(dest, src, n); } +static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) { + dfsan_mem_origin_transfer(dest, src, n); + return dfsan_memcpy(dest, src, n); +} + static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) { internal_memset(s, c, n); dfsan_set_label(c_label, s, n); } +static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label, + dfsan_origin c_origin, size_t n) { + internal_memset(s, c, n); + dfsan_set_label_origin(c_label, c_origin, s, n); +} + SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memcpy(void *dest, const void *src, size_t n, dfsan_label dest_label, dfsan_label src_label, @@ -337,6 +544,17 @@ void *__dfsw_memcpy(void *dest, const void *src, size_t n, return dfsan_memcpy(dest, src, n); } +SANITIZER_INTERFACE_ATTRIBUTE +void *__dfso_memcpy(void *dest, const void *src, size_t n, + dfsan_label dest_label, dfsan_label src_label, + dfsan_label n_label, dfsan_label *ret_label, + dfsan_origin dest_origin, dfsan_origin src_origin, + dfsan_origin n_origin, dfsan_origin *ret_origin) { + *ret_label = dest_label; + *ret_origin = dest_origin; + return dfsan_memcpy_with_origin(dest, src, n); +} + SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memmove(void *dest, const void *src, size_t n, dfsan_label dest_label, dfsan_label src_label, @@ -345,6 +563,17 @@ void *__dfsw_memmove(void *dest, const void *src, size_t n, return dfsan_memmove(dest, src, n); } +SANITIZER_INTERFACE_ATTRIBUTE +void *__dfso_memmove(void *dest, const void *src, size_t n, + dfsan_label dest_label, dfsan_label src_label, + dfsan_label n_label, dfsan_label *ret_label, + dfsan_origin dest_origin, dfsan_origin src_origin, + dfsan_origin n_origin, dfsan_origin *ret_origin) { + *ret_label = dest_label; + *ret_origin = dest_origin; + return dfsan_memmove_with_origin(dest, src, n); +} + SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memset(void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label, @@ -354,6 +583,18 @@ void *__dfsw_memset(void *s, int c, size_t n, return s; } +SANITIZER_INTERFACE_ATTRIBUTE +void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label, + dfsan_label c_label, dfsan_label n_label, + dfsan_label *ret_label, dfsan_origin s_origin, + dfsan_origin c_origin, dfsan_origin n_origin, + dfsan_origin *ret_origin) { + dfsan_memset_with_origin(s, c, c_label, c_origin, n); + *ret_label = s_label; + *ret_origin = s_origin; + return s; +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label, @@ -368,6 +609,23 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat( + char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label, + dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin, + dfsan_origin *ret_origin) { + size_t dest_len = strlen(dest); + char *ret = strcat(dest, src); // NOLINT + dfsan_label *sdest = shadow_for(dest + dest_len); + const dfsan_label *ssrc = shadow_for(src); + size_t src_len = strlen(src); + dfsan_mem_origin_transfer(dest + dest_len, src, src_len); + internal_memcpy((void *)sdest, (const void *)ssrc, + src_len * sizeof(dfsan_label)); + *ret_label = dest_label; + *ret_origin = dest_origin; + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE char * __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) { size_t len = strlen(s); @@ -377,6 +635,18 @@ __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) { return static_cast(p); } +SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s, + dfsan_label s_label, + dfsan_label *ret_label, + dfsan_origin s_origin, + dfsan_origin *ret_origin) { + size_t len = strlen(s); + void *p = malloc(len + 1); + dfsan_memcpy_with_origin(p, s, len + 1); + *ret_label = 0; + return static_cast(p); +} + SANITIZER_INTERFACE_ATTRIBUTE char * __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label, dfsan_label s2_label, dfsan_label n_label, @@ -393,6 +663,24 @@ __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label, return s1; } +SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy( + char *s1, const char *s2, size_t n, dfsan_label s1_label, + dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, + dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, + dfsan_origin *ret_origin) { + size_t len = strlen(s2); + if (len < n) { + dfsan_memcpy_with_origin(s1, s2, len + 1); + dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1); + } else { + dfsan_memcpy_with_origin(s1, s2, n); + } + + *ret_label = s1_label; + *ret_origin = s1_origin; + return s1; +} + SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_pread(int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label, dfsan_label buf_label, @@ -405,6 +693,16 @@ __dfsw_pread(int fd, void *buf, size_t count, off_t offset, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread( + int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label, + dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label, + dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, + dfsan_origin count_origin, dfsan_label offset_origin, + dfsan_origin *ret_origin) { + return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label, + offset_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_read(int fd, void *buf, size_t count, dfsan_label fd_label, dfsan_label buf_label, @@ -417,6 +715,15 @@ __dfsw_read(int fd, void *buf, size_t count, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read( + int fd, void *buf, size_t count, dfsan_label fd_label, + dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, + dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, + dfsan_origin *ret_origin) { + return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label, + ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label, @@ -429,7 +736,14 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id, return ret; } -static void unpoison(const void *ptr, uptr size) { +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime( + clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label, + dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin, + dfsan_origin tp_origin, dfsan_origin *ret_origin) { + return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label); +} + +static void dfsan_set_zero_label(const void *ptr, uptr size) { dfsan_set_label(0, const_cast(ptr), size); } @@ -442,11 +756,19 @@ __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label, void *handle = dlopen(filename, flag); link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle); if (map) - ForEachMappedRegion(map, unpoison); + ForEachMappedRegion(map, dfsan_set_zero_label); *ret_label = 0; return handle; } +SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen( + const char *filename, int flag, dfsan_label filename_label, + dfsan_label flag_label, dfsan_label *ret_label, + dfsan_origin filename_origin, dfsan_origin flag_origin, + dfsan_origin *ret_origin) { + return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label); +} + static void *DFsanThreadStartFunc(void *arg) { DFsanThread *t = (DFsanThread *)arg; SetCurrentThread(t); @@ -456,7 +778,8 @@ static void *DFsanThreadStartFunc(void *arg) { static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *start_routine_trampoline, void *start_routine, void *arg, - dfsan_label *ret_label) { + dfsan_label *ret_label, + bool track_origins = false) { pthread_attr_t myattr; if (!attr) { pthread_attr_init(&myattr); @@ -466,8 +789,9 @@ static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, // Ensure that the thread stack is large enough to hold all TLS data. AdjustStackSize((void *)(const_cast(attr))); - DFsanThread *t = DFsanThread::Create(start_routine_trampoline, - (thread_callback_t)start_routine, arg); + DFsanThread *t = + DFsanThread::Create(start_routine_trampoline, + (thread_callback_t)start_routine, arg, track_origins); int res = pthread_create(thread, attr, DFsanThreadStartFunc, t); if (attr == &myattr) @@ -487,6 +811,20 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create( start_routine, arg, ret_label); } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create( + pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine_trampoline)(void *, void *, dfsan_label, + dfsan_label *, dfsan_origin, + dfsan_origin *), + void *start_routine, void *arg, dfsan_label thread_label, + dfsan_label attr_label, dfsan_label start_routine_label, + dfsan_label arg_label, dfsan_label *ret_label, dfsan_origin thread_origin, + dfsan_origin attr_origin, dfsan_origin start_routine_origin, + dfsan_origin arg_origin, dfsan_origin *ret_origin) { + return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline, + start_routine, arg, ret_label, true); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread, void **retval, dfsan_label thread_label, @@ -499,6 +837,15 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join( + pthread_t thread, void **retval, dfsan_label thread_label, + dfsan_label retval_label, dfsan_label *ret_label, + dfsan_origin thread_origin, dfsan_origin retval_origin, + dfsan_origin *ret_origin) { + return __dfsw_pthread_join(thread, retval, thread_label, retval_label, + ret_label); +} + struct dl_iterate_phdr_info { int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, size_t size, void *data, dfsan_label info_label, @@ -508,6 +855,17 @@ struct dl_iterate_phdr_info { void *data; }; +struct dl_iterate_phdr_origin_info { + int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, + size_t size, void *data, dfsan_label info_label, + dfsan_label size_label, dfsan_label data_label, + dfsan_label *ret_label, dfsan_origin info_origin, + dfsan_origin size_origin, dfsan_origin data_origin, + dfsan_origin *ret_origin); + void *callback; + void *data; +}; + int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) { dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data; dfsan_set_label(0, *info); @@ -521,6 +879,21 @@ int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) { 0, &ret_label); } +int dl_iterate_phdr_origin_cb(struct dl_phdr_info *info, size_t size, + void *data) { + dl_iterate_phdr_origin_info *dipi = (dl_iterate_phdr_origin_info *)data; + dfsan_set_label(0, *info); + dfsan_set_label(0, const_cast(info->dlpi_name), + strlen(info->dlpi_name) + 1); + dfsan_set_label( + 0, const_cast(reinterpret_cast(info->dlpi_phdr)), + sizeof(*info->dlpi_phdr) * info->dlpi_phnum); + dfsan_label ret_label; + dfsan_origin ret_origin; + return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0, + 0, &ret_label, 0, 0, 0, &ret_origin); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, size_t size, void *data, dfsan_label info_label, @@ -533,6 +906,23 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr( + int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, + size_t size, void *data, dfsan_label info_label, + dfsan_label size_label, dfsan_label data_label, + dfsan_label *ret_label, dfsan_origin info_origin, + dfsan_origin size_origin, + dfsan_origin data_origin, + dfsan_origin *ret_origin), + void *callback, void *data, dfsan_label callback_label, + dfsan_label data_label, dfsan_label *ret_label, + dfsan_origin callback_origin, dfsan_origin data_origin, + dfsan_origin *ret_origin) { + dl_iterate_phdr_origin_info dipi = {callback_trampoline, callback, data}; + *ret_label = 0; + return dl_iterate_phdr(dl_iterate_phdr_origin_cb, &dipi); +} + // This function is only available for glibc 2.27 or newer. Mark it weak so // linking succeeds with older glibcs. SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep, @@ -547,6 +937,13 @@ SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info( dfsan_set_label(0, alignp, sizeof(*alignp)); } +SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info( + size_t *sizep, size_t *alignp, dfsan_label sizep_label, + dfsan_label alignp_label, dfsan_origin sizep_origin, + dfsan_origin alignp_origin) { + __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label); +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, dfsan_label buf_label, dfsan_label *ret_label) { @@ -561,6 +958,25 @@ char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, + dfsan_label buf_label, dfsan_label *ret_label, + dfsan_origin timep_origin, dfsan_origin buf_origin, + dfsan_origin *ret_origin) { + char *ret = ctime_r(timep, buf); + if (ret) { + dfsan_set_label_origin( + dfsan_read_label(timep, sizeof(time_t)), + dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf, + strlen(buf) + 1); + *ret_label = buf_label; + *ret_origin = buf_origin; + } else { + *ret_label = 0; + } + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, dfsan_label size_label, dfsan_label stream_label, @@ -575,6 +991,19 @@ char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label, + dfsan_label size_label, dfsan_label stream_label, + dfsan_label *ret_label, dfsan_origin s_origin, + dfsan_origin size_origin, dfsan_origin stream_origin, + dfsan_origin *ret_origin) { + char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label, + ret_label); + if (ret) + *ret_origin = s_origin; + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, dfsan_label size_label, dfsan_label *ret_label) { @@ -588,16 +1017,32 @@ char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label, + dfsan_label size_label, dfsan_label *ret_label, + dfsan_origin buf_origin, dfsan_origin size_origin, + dfsan_origin *ret_origin) { + char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label); + if (ret) + *ret_origin = buf_origin; + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_get_current_dir_name(dfsan_label *ret_label) { char *ret = get_current_dir_name(); - if (ret) { + if (ret) dfsan_set_label(0, ret, strlen(ret) + 1); - } *ret_label = 0; return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_get_current_dir_name(dfsan_label *ret_label, + dfsan_origin *ret_origin) { + return __dfsw_get_current_dir_name(ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, dfsan_label len_label, dfsan_label *ret_label) { @@ -609,6 +1054,14 @@ int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_gethostname(char *name, size_t len, dfsan_label name_label, + dfsan_label len_label, dfsan_label *ret_label, + dfsan_origin name_origin, dfsan_origin len_origin, + dfsan_label *ret_origin) { + return __dfsw_gethostname(name, len, name_label, len_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getrlimit(int resource, struct rlimit *rlim, dfsan_label resource_label, dfsan_label rlim_label, @@ -621,6 +1074,15 @@ int __dfsw_getrlimit(int resource, struct rlimit *rlim, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_getrlimit(int resource, struct rlimit *rlim, + dfsan_label resource_label, dfsan_label rlim_label, + dfsan_label *ret_label, dfsan_origin resource_origin, + dfsan_origin rlim_origin, dfsan_origin *ret_origin) { + return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label, + ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, dfsan_label usage_label, dfsan_label *ret_label) { @@ -632,6 +1094,14 @@ int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label, + dfsan_label usage_label, dfsan_label *ret_label, + dfsan_origin who_origin, dfsan_origin usage_origin, + dfsan_label *ret_origin) { + return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, dfsan_label src_label, dfsan_label *ret_label) { @@ -645,14 +1115,34 @@ char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, } SANITIZER_INTERFACE_ATTRIBUTE -long int __dfsw_strtol(const char *nptr, char **endptr, int base, - dfsan_label nptr_label, dfsan_label endptr_label, - dfsan_label base_label, dfsan_label *ret_label) { - char *tmp_endptr; - long int ret = strtol(nptr, &tmp_endptr, base); - if (endptr) { - *endptr = tmp_endptr; +char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label, + dfsan_label src_label, dfsan_label *ret_label, + dfsan_origin dst_origin, dfsan_origin src_origin, + dfsan_origin *ret_origin) { + char *ret = strcpy(dest, src); // NOLINT + if (ret) { + size_t str_len = strlen(src) + 1; + dfsan_mem_origin_transfer(dest, src, str_len); + internal_memcpy(shadow_for(dest), shadow_for(src), + sizeof(dfsan_label) * str_len); } + *ret_label = dst_label; + *ret_origin = dst_origin; + return ret; +} + +static long int dfsan_strtol(const char *nptr, char **endptr, int base, + char **tmp_endptr) { + assert(tmp_endptr); + long int ret = strtol(nptr, tmp_endptr, base); + if (endptr) + *endptr = *tmp_endptr; + return ret; +} + +static void dfsan_strtolong_label(const char *nptr, const char *tmp_endptr, + dfsan_label base_label, + dfsan_label *ret_label) { if (tmp_endptr > nptr) { // If *tmp_endptr is '\0' include its label as well. *ret_label = dfsan_union( @@ -661,18 +1151,58 @@ long int __dfsw_strtol(const char *nptr, char **endptr, int base, } else { *ret_label = 0; } +} + +static void dfsan_strtolong_origin(const char *nptr, const char *tmp_endptr, + dfsan_label base_label, + dfsan_label *ret_label, + dfsan_origin base_origin, + dfsan_origin *ret_origin) { + if (tmp_endptr > nptr) { + // When multiple inputs are tainted, we propagate one of its origins. + // Because checking if base_label is tainted does not need additional + // computation, we prefer to propagating base_origin. + *ret_origin = base_label + ? base_origin + : dfsan_read_origin_of_first_taint( + nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); + } +} + +SANITIZER_INTERFACE_ATTRIBUTE +long int __dfsw_strtol(const char *nptr, char **endptr, int base, + dfsan_label nptr_label, dfsan_label endptr_label, + dfsan_label base_label, dfsan_label *ret_label) { + char *tmp_endptr; + long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); return ret; } SANITIZER_INTERFACE_ATTRIBUTE -double __dfsw_strtod(const char *nptr, char **endptr, +long int __dfso_strtol(const char *nptr, char **endptr, int base, dfsan_label nptr_label, dfsan_label endptr_label, - dfsan_label *ret_label) { + dfsan_label base_label, dfsan_label *ret_label, + dfsan_origin nptr_origin, dfsan_origin endptr_origin, + dfsan_origin base_origin, dfsan_origin *ret_origin) { char *tmp_endptr; - double ret = strtod(nptr, &tmp_endptr); - if (endptr) { - *endptr = tmp_endptr; - } + long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); + dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, + ret_origin); + return ret; +} + +static double dfsan_strtod(const char *nptr, char **endptr, char **tmp_endptr) { + assert(tmp_endptr); + double ret = strtod(nptr, tmp_endptr); + if (endptr) + *endptr = *tmp_endptr; + return ret; +} + +static void dfsan_strtod_label(const char *nptr, const char *tmp_endptr, + dfsan_label *ret_label) { if (tmp_endptr > nptr) { // If *tmp_endptr is '\0' include its label as well. *ret_label = dfsan_read_label( @@ -681,46 +1211,109 @@ double __dfsw_strtod(const char *nptr, char **endptr, } else { *ret_label = 0; } +} + +SANITIZER_INTERFACE_ATTRIBUTE +double __dfsw_strtod(const char *nptr, char **endptr, dfsan_label nptr_label, + dfsan_label endptr_label, dfsan_label *ret_label) { + char *tmp_endptr; + double ret = dfsan_strtod(nptr, endptr, &tmp_endptr); + dfsan_strtod_label(nptr, tmp_endptr, ret_label); return ret; } SANITIZER_INTERFACE_ATTRIBUTE -long long int __dfsw_strtoll(const char *nptr, char **endptr, int base, - dfsan_label nptr_label, dfsan_label endptr_label, - dfsan_label base_label, dfsan_label *ret_label) { +double __dfso_strtod(const char *nptr, char **endptr, dfsan_label nptr_label, + dfsan_label endptr_label, dfsan_label *ret_label, + dfsan_origin nptr_origin, dfsan_origin endptr_origin, + dfsan_origin *ret_origin) { char *tmp_endptr; - long long int ret = strtoll(nptr, &tmp_endptr, base); - if (endptr) { - *endptr = tmp_endptr; - } + double ret = dfsan_strtod(nptr, endptr, &tmp_endptr); + dfsan_strtod_label(nptr, tmp_endptr, ret_label); if (tmp_endptr > nptr) { // If *tmp_endptr is '\0' include its label as well. - *ret_label = dfsan_union( - base_label, - dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); + *ret_origin = dfsan_read_origin_of_first_taint( + nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); } else { - *ret_label = 0; + *ret_origin = 0; } return ret; } +static long long int dfsan_strtoll(const char *nptr, char **endptr, int base, + char **tmp_endptr) { + assert(tmp_endptr); + long long int ret = strtoll(nptr, tmp_endptr, base); + if (endptr) + *endptr = *tmp_endptr; + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +long long int __dfsw_strtoll(const char *nptr, char **endptr, int base, + dfsan_label nptr_label, dfsan_label endptr_label, + dfsan_label base_label, dfsan_label *ret_label) { + char *tmp_endptr; + long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +long long int __dfso_strtoll(const char *nptr, char **endptr, int base, + dfsan_label nptr_label, dfsan_label endptr_label, + dfsan_label base_label, dfsan_label *ret_label, + dfsan_origin nptr_origin, + dfsan_origin endptr_origin, + dfsan_origin base_origin, + dfsan_origin *ret_origin) { + char *tmp_endptr; + long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); + dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, + ret_origin); + return ret; +} + +static unsigned long int dfsan_strtoul(const char *nptr, char **endptr, + int base, char **tmp_endptr) { + assert(tmp_endptr); + unsigned long int ret = strtoul(nptr, tmp_endptr, base); + if (endptr) + *endptr = *tmp_endptr; + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base, dfsan_label nptr_label, dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label) { char *tmp_endptr; - unsigned long int ret = strtoul(nptr, &tmp_endptr, base); - if (endptr) { - *endptr = tmp_endptr; - } - if (tmp_endptr > nptr) { - // If *tmp_endptr is '\0' include its label as well. - *ret_label = dfsan_union( - base_label, - dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); - } else { - *ret_label = 0; - } + unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +unsigned long int __dfso_strtoul( + const char *nptr, char **endptr, int base, dfsan_label nptr_label, + dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label, + dfsan_origin nptr_origin, dfsan_origin endptr_origin, + dfsan_origin base_origin, dfsan_origin *ret_origin) { + char *tmp_endptr; + unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); + dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, + ret_origin); + return ret; +} + +static long long unsigned int dfsan_strtoull(const char *nptr, char **endptr, + int base, char **tmp_endptr) { + assert(tmp_endptr); + long long unsigned int ret = strtoull(nptr, tmp_endptr, base); + if (endptr) + *endptr = *tmp_endptr; return ret; } @@ -731,18 +1324,22 @@ long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr, dfsan_label base_label, dfsan_label *ret_label) { char *tmp_endptr; - long long unsigned int ret = strtoull(nptr, &tmp_endptr, base); - if (endptr) { - *endptr = tmp_endptr; - } - if (tmp_endptr > nptr) { - // If *tmp_endptr is '\0' include its label as well. - *ret_label = dfsan_union( - base_label, - dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); - } else { - *ret_label = 0; - } + long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +long long unsigned int __dfso_strtoull( + const char *nptr, char **endptr, int base, dfsan_label nptr_label, + dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label, + dfsan_origin nptr_origin, dfsan_origin endptr_origin, + dfsan_origin base_origin, dfsan_origin *ret_origin) { + char *tmp_endptr; + long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr); + dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); + dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, + ret_origin); return ret; } @@ -756,6 +1353,12 @@ time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) { return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label, + dfsan_origin t_origin, dfsan_origin *ret_origin) { + return __dfsw_time(t, t_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, dfsan_label src_label, dfsan_label dst_label, @@ -769,6 +1372,24 @@ int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, + dfsan_label src_label, dfsan_label dst_label, + dfsan_label *ret_label, dfsan_origin af_origin, + dfsan_origin src_origin, dfsan_origin dst_origin, + dfsan_origin *ret_origin) { + int ret = inet_pton(af, src, dst); + if (ret == 1) { + int src_len = strlen(src) + 1; + dfsan_set_label_origin( + dfsan_read_label(src, src_len), + dfsan_read_origin_of_first_taint(src, src_len), dst, + af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); + } + *ret_label = 0; + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, dfsan_label timep_label, dfsan_label result_label, @@ -784,6 +1405,26 @@ struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result, + dfsan_label timep_label, dfsan_label result_label, + dfsan_label *ret_label, dfsan_origin timep_origin, + dfsan_origin result_origin, + dfsan_origin *ret_origin) { + struct tm *ret = localtime_r(timep, result); + if (ret) { + dfsan_set_label_origin( + dfsan_read_label(timep, sizeof(time_t)), + dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result, + sizeof(struct tm)); + *ret_label = result_label; + *ret_origin = result_origin; + } else { + *ret_label = 0; + } + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result, @@ -802,6 +1443,19 @@ int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen, + struct passwd **result, dfsan_label uid_label, + dfsan_label pwd_label, dfsan_label buf_label, + dfsan_label buflen_label, dfsan_label result_label, + dfsan_label *ret_label, dfsan_origin uid_origin, + dfsan_origin pwd_origin, dfsan_origin buf_origin, + dfsan_origin buflen_origin, dfsan_origin result_origin, + dfsan_origin *ret_origin) { + return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label, + buf_label, buflen_label, result_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout, dfsan_label epfd_label, @@ -814,6 +1468,19 @@ int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents, + int timeout, dfsan_label epfd_label, + dfsan_label events_label, dfsan_label maxevents_label, + dfsan_label timeout_label, dfsan_label *ret_label, + dfsan_origin epfd_origin, dfsan_origin events_origin, + dfsan_origin maxevents_origin, + dfsan_origin timeout_origin, dfsan_origin *ret_origin) { + return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label, + events_label, maxevents_label, timeout_label, + ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, dfsan_label dfs_label, dfsan_label nfds_label, @@ -828,6 +1495,16 @@ int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout, + dfsan_label dfs_label, dfsan_label nfds_label, + dfsan_label timeout_label, dfsan_label *ret_label, + dfsan_origin dfs_origin, dfsan_origin nfds_origin, + dfsan_origin timeout_origin, dfsan_origin *ret_origin) { + return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label, + ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout, @@ -851,6 +1528,20 @@ int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout, + dfsan_label nfds_label, dfsan_label readfds_label, + dfsan_label writefds_label, dfsan_label exceptfds_label, + dfsan_label timeout_label, dfsan_label *ret_label, + dfsan_origin nfds_origin, dfsan_origin readfds_origin, + dfsan_origin writefds_origin, dfsan_origin exceptfds_origin, + dfsan_origin timeout_origin, dfsan_origin *ret_origin) { + return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label, + readfds_label, writefds_label, exceptfds_label, + timeout_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, dfsan_label pid_label, @@ -864,14 +1555,35 @@ int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, + dfsan_label pid_label, + dfsan_label cpusetsize_label, + dfsan_label mask_label, dfsan_label *ret_label, + dfsan_origin pid_origin, + dfsan_origin cpusetsize_origin, + dfsan_origin mask_origin, + dfsan_origin *ret_origin) { + return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label, + cpusetsize_label, mask_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label, dfsan_label *ret_label) { int ret = sigemptyset(set); dfsan_set_label(0, set, sizeof(sigset_t)); + *ret_label = 0; return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label, + dfsan_label *ret_label, dfsan_origin set_origin, + dfsan_origin *ret_origin) { + return __dfsw_sigemptyset(set, set_label, ret_label); +} + class SignalHandlerScope { public: SignalHandlerScope() { @@ -988,11 +1700,18 @@ int __dfsw_sigaction(int signum, const struct sigaction *act, } SANITIZER_INTERFACE_ATTRIBUTE -sighandler_t __dfsw_signal(int signum, - void *(*handler_trampoline)(void *, int, dfsan_label, - dfsan_label *), - sighandler_t handler, dfsan_label signum_label, - dfsan_label handler_label, dfsan_label *ret_label) { +int __dfso_sigaction(int signum, const struct sigaction *act, + struct sigaction *oldact, dfsan_label signum_label, + dfsan_label act_label, dfsan_label oldact_label, + dfsan_label *ret_label, dfsan_origin signum_origin, + dfsan_origin act_origin, dfsan_origin oldact_origin, + dfsan_origin *ret_origin) { + return __dfsw_sigaction(signum, act, oldact, signum_label, act_label, + oldact_label, ret_label); +} + +static sighandler_t dfsan_signal(int signum, sighandler_t handler, + dfsan_label *ret_label) { CHECK_LT(signum, kMaxSignals); SignalSpinLocker lock; uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed); @@ -1010,6 +1729,26 @@ sighandler_t __dfsw_signal(int signum, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +sighandler_t __dfsw_signal(int signum, + void *(*handler_trampoline)(void *, int, dfsan_label, + dfsan_label *), + sighandler_t handler, dfsan_label signum_label, + dfsan_label handler_label, dfsan_label *ret_label) { + return dfsan_signal(signum, handler, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE +sighandler_t __dfso_signal( + int signum, + void *(*handler_trampoline)(void *, int, dfsan_label, dfsan_label *, + dfsan_origin, dfsan_origin *), + sighandler_t handler, dfsan_label signum_label, dfsan_label handler_label, + dfsan_label *ret_label, dfsan_origin signum_origin, + dfsan_origin handler_origin, dfsan_origin *ret_origin) { + return dfsan_signal(signum, handler, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, dfsan_label old_ss_label, dfsan_label *ret_label) { @@ -1020,6 +1759,14 @@ int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, + dfsan_label old_ss_label, dfsan_label *ret_label, + dfsan_origin ss_origin, dfsan_origin old_ss_origin, + dfsan_origin *ret_origin) { + return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz, dfsan_label tv_label, dfsan_label tz_label, @@ -1035,6 +1782,14 @@ int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_gettimeofday(struct timeval *tv, struct timezone *tz, + dfsan_label tv_label, dfsan_label tz_label, + dfsan_label *ret_label, dfsan_origin tv_origin, + dfsan_origin tz_origin, dfsan_origin *ret_origin) { + return __dfsw_gettimeofday(tv, tz, tv_label, tz_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label, @@ -1053,6 +1808,24 @@ SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_memchr( + void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label, + dfsan_label n_label, dfsan_label *ret_label, dfsan_origin s_origin, + dfsan_origin c_origin, dfsan_origin n_origin, dfsan_origin *ret_origin) { + void *ret = __dfsw_memchr(s, c, n, s_label, c_label, n_label, ret_label); + if (flags().strict_data_dependencies) { + if (ret) + *ret_origin = s_origin; + } else { + size_t len = + ret ? reinterpret_cast(ret) - reinterpret_cast(s) + 1 + : n; + dfsan_origin o = dfsan_read_origin_of_first_taint(s, len); + *ret_origin = o ? o : (s_label ? s_origin : c_origin); + } + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c, dfsan_label s_label, dfsan_label c_label, @@ -1069,6 +1842,23 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strrchr( + char *s, int c, dfsan_label s_label, dfsan_label c_label, + dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin, + dfsan_origin *ret_origin) { + char *ret = __dfsw_strrchr(s, c, s_label, c_label, ret_label); + if (flags().strict_data_dependencies) { + if (ret) + *ret_origin = s_origin; + } else { + size_t s_len = strlen(s) + 1; + dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_len); + *ret_origin = o ? o : (s_label ? s_origin : c_origin); + } + + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle, dfsan_label haystack_label, dfsan_label needle_label, @@ -1087,6 +1877,33 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strstr(char *haystack, char *needle, + dfsan_label haystack_label, + dfsan_label needle_label, + dfsan_label *ret_label, + dfsan_origin haystack_origin, + dfsan_origin needle_origin, + dfsan_origin *ret_origin) { + char *ret = + __dfsw_strstr(haystack, needle, haystack_label, needle_label, ret_label); + if (flags().strict_data_dependencies) { + if (ret) + *ret_origin = haystack_origin; + } else { + size_t needle_len = strlen(needle); + size_t len = ret ? ret + needle_len - haystack : strlen(haystack) + 1; + dfsan_origin o = dfsan_read_origin_of_first_taint(haystack, len); + if (o) { + *ret_origin = o; + } else { + o = dfsan_read_origin_of_first_taint(needle, needle_len + 1); + *ret_origin = o ? o : (haystack_label ? haystack_origin : needle_origin); + } + } + + return ret; +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req, struct timespec *rem, dfsan_label req_label, @@ -1101,6 +1918,13 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req, return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_nanosleep( + const struct timespec *req, struct timespec *rem, dfsan_label req_label, + dfsan_label rem_label, dfsan_label *ret_label, dfsan_origin req_origin, + dfsan_origin rem_origin, dfsan_origin *ret_origin) { + return __dfsw_nanosleep(req, rem, req_label, rem_label, ret_label); +} + static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) { dfsan_set_label(0, msg, sizeof(*msg)); dfsan_set_label(0, msg->msg_name, msg->msg_namelen); @@ -1129,6 +1953,19 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg( return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_recvmmsg( + int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, + struct timespec *timeout, dfsan_label sockfd_label, + dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label, + dfsan_label timeout_label, dfsan_label *ret_label, + dfsan_origin sockfd_origin, dfsan_origin msgvec_origin, + dfsan_origin vlen_origin, dfsan_origin flags_origin, + dfsan_origin timeout_origin, dfsan_origin *ret_origin) { + return __dfsw_recvmmsg(sockfd, msgvec, vlen, flags, timeout, sockfd_label, + msgvec_label, vlen_label, flags_label, timeout_label, + ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg( int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label, dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) { @@ -1139,6 +1976,15 @@ SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg( return ret; } +SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_recvmsg( + int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label, + dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label, + dfsan_origin sockfd_origin, dfsan_origin msg_origin, + dfsan_origin flags_origin, dfsan_origin *ret_origin) { + return __dfsw_recvmsg(sockfd, msg, flags, sockfd_label, msg_label, + flags_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_socketpair(int domain, int type, int protocol, int sv[2], dfsan_label domain_label, dfsan_label type_label, @@ -1152,6 +1998,16 @@ __dfsw_socketpair(int domain, int type, int protocol, int sv[2], return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_socketpair( + int domain, int type, int protocol, int sv[2], dfsan_label domain_label, + dfsan_label type_label, dfsan_label protocol_label, dfsan_label sv_label, + dfsan_label *ret_label, dfsan_origin domain_origin, + dfsan_origin type_origin, dfsan_origin protocol_origin, + dfsan_origin sv_origin, dfsan_origin *ret_origin) { + return __dfsw_socketpair(domain, type, protocol, sv, domain_label, type_label, + protocol_label, sv_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt( int sockfd, int level, int optname, void *optval, socklen_t *optlen, dfsan_label sockfd_label, dfsan_label level_label, @@ -1166,6 +2022,19 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt( return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockopt( + int sockfd, int level, int optname, void *optval, socklen_t *optlen, + dfsan_label sockfd_label, dfsan_label level_label, + dfsan_label optname_label, dfsan_label optval_label, + dfsan_label optlen_label, dfsan_label *ret_label, + dfsan_origin sockfd_origin, dfsan_origin level_origin, + dfsan_origin optname_origin, dfsan_origin optval_origin, + dfsan_origin optlen_origin, dfsan_origin *ret_origin) { + return __dfsw_getsockopt(sockfd, level, optname, optval, optlen, sockfd_label, + level_label, optname_label, optval_label, + optlen_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname( int sockfd, struct sockaddr *addr, socklen_t *addrlen, dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, @@ -1181,6 +2050,16 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname( return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockname( + int sockfd, struct sockaddr *addr, socklen_t *addrlen, + dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, + dfsan_label *ret_label, dfsan_origin sockfd_origin, + dfsan_origin addr_origin, dfsan_origin addrlen_origin, + dfsan_origin *ret_origin) { + return __dfsw_getsockname(sockfd, addr, addrlen, sockfd_label, addr_label, + addrlen_label, ret_label); +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername( int sockfd, struct sockaddr *addr, socklen_t *addrlen, dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, @@ -1196,6 +2075,16 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername( return ret; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername( + int sockfd, struct sockaddr *addr, socklen_t *addrlen, + dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, + dfsan_label *ret_label, dfsan_origin sockfd_origin, + dfsan_origin addr_origin, dfsan_origin addrlen_origin, + dfsan_origin *ret_origin) { + return __dfsw_getpeername(sockfd, addr, addrlen, sockfd_label, addr_label, + addrlen_label, ret_label); +} + // Type of the trampoline function passed to the custom version of // dfsan_set_write_callback. typedef void (*write_trampoline_t)( @@ -1203,6 +2092,11 @@ typedef void (*write_trampoline_t)( int fd, const void *buf, ssize_t count, dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label); +typedef void (*write_origin_trampoline_t)( + void *callback, int fd, const void *buf, ssize_t count, + dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label, + dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin); + // Calls to dfsan_set_write_callback() set the values in this struct. // Calls to the custom version of write() read (and invoke) them. static struct { @@ -1210,6 +2104,11 @@ static struct { void *write_callback = nullptr; } write_callback_info; +static struct { + write_origin_trampoline_t write_callback_trampoline = nullptr; + void *write_callback = nullptr; +} write_origin_callback_info; + SANITIZER_INTERFACE_ATTRIBUTE void __dfsw_dfsan_set_write_callback( write_trampoline_t write_callback_trampoline, @@ -1220,6 +2119,15 @@ __dfsw_dfsan_set_write_callback( write_callback_info.write_callback = write_callback; } +SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback( + write_origin_trampoline_t write_callback_trampoline, void *write_callback, + dfsan_label write_callback_label, dfsan_label *ret_label, + dfsan_origin write_callback_origin, dfsan_origin *ret_origin) { + write_origin_callback_info.write_callback_trampoline = + write_callback_trampoline; + write_origin_callback_info.write_callback = write_callback; +} + SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_write(int fd, const void *buf, size_t count, dfsan_label fd_label, dfsan_label buf_label, @@ -1234,6 +2142,21 @@ __dfsw_write(int fd, const void *buf, size_t count, *ret_label = 0; return write(fd, buf, count); } + +SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write( + int fd, const void *buf, size_t count, dfsan_label fd_label, + dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, + dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, + dfsan_origin *ret_origin) { + if (write_origin_callback_info.write_callback) { + write_origin_callback_info.write_callback_trampoline( + write_origin_callback_info.write_callback, fd, buf, count, fd_label, + buf_label, count_label, fd_origin, buf_origin, count_origin); + } + + *ret_label = 0; + return write(fd, buf, count); +} } // namespace __dfsan // Type used to extract a dfsan_label with va_arg() @@ -1323,6 +2246,7 @@ struct Formatter { // positional arguments. static int format_buffer(char *str, size_t size, const char *fmt, dfsan_label *va_labels, dfsan_label *ret_label, + dfsan_origin *va_origins, dfsan_origin *ret_origin, va_list ap) { Formatter formatter(str, fmt, size); @@ -1378,8 +2302,13 @@ static int format_buffer(char *str, size_t size, const char *fmt, default: retval = formatter.format(va_arg(ap, int)); } - dfsan_set_label(*va_labels++, formatter.str_cur(), - formatter.num_written_bytes(retval)); + if (va_origins == nullptr) + dfsan_set_label(*va_labels++, formatter.str_cur(), + formatter.num_written_bytes(retval)); + else + dfsan_set_label_origin(*va_labels++, *va_origins++, + formatter.str_cur(), + formatter.num_written_bytes(retval)); end_fmt = true; break; @@ -1396,21 +2325,36 @@ static int format_buffer(char *str, size_t size, const char *fmt, } else { retval = formatter.format(va_arg(ap, double)); } - dfsan_set_label(*va_labels++, formatter.str_cur(), - formatter.num_written_bytes(retval)); + if (va_origins == nullptr) + dfsan_set_label(*va_labels++, formatter.str_cur(), + formatter.num_written_bytes(retval)); + else + dfsan_set_label_origin(*va_labels++, *va_origins++, + formatter.str_cur(), + formatter.num_written_bytes(retval)); end_fmt = true; break; case 'c': retval = formatter.format(va_arg(ap, int)); - dfsan_set_label(*va_labels++, formatter.str_cur(), - formatter.num_written_bytes(retval)); + if (va_origins == nullptr) + dfsan_set_label(*va_labels++, formatter.str_cur(), + formatter.num_written_bytes(retval)); + else + dfsan_set_label_origin(*va_labels++, *va_origins++, + formatter.str_cur(), + formatter.num_written_bytes(retval)); end_fmt = true; break; case 's': { char *arg = va_arg(ap, char *); retval = formatter.format(arg); + if (va_origins) { + va_origins++; + dfsan_mem_origin_transfer(formatter.str_cur(), arg, + formatter.num_written_bytes(retval)); + } va_labels++; internal_memcpy(shadow_for(formatter.str_cur()), shadow_for(arg), sizeof(dfsan_label) * @@ -1421,8 +2365,13 @@ static int format_buffer(char *str, size_t size, const char *fmt, case 'p': retval = formatter.format(va_arg(ap, void *)); - dfsan_set_label(*va_labels++, formatter.str_cur(), - formatter.num_written_bytes(retval)); + if (va_origins == nullptr) + dfsan_set_label(*va_labels++, formatter.str_cur(), + formatter.num_written_bytes(retval)); + else + dfsan_set_label_origin(*va_labels++, *va_origins++, + formatter.str_cur(), + formatter.num_written_bytes(retval)); end_fmt = true; break; @@ -1430,6 +2379,8 @@ static int format_buffer(char *str, size_t size, const char *fmt, int *ptr = va_arg(ap, int *); *ptr = (int)formatter.str_off; va_labels++; + if (va_origins) + va_origins++; dfsan_set_label(0, ptr, sizeof(ptr)); end_fmt = true; break; @@ -1445,6 +2396,8 @@ static int format_buffer(char *str, size_t size, const char *fmt, case '*': formatter.width = va_arg(ap, int); va_labels++; + if (va_origins) + va_origins++; break; default: @@ -1462,6 +2415,8 @@ static int format_buffer(char *str, size_t size, const char *fmt, } *ret_label = 0; + if (ret_origin) + *ret_origin = 0; // Number of bytes written in total. return formatter.str_off; @@ -1474,7 +2429,22 @@ int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label, dfsan_label *ret_label, ...) { va_list ap; va_start(ap, ret_label); - int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, ap); + int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr, + nullptr, ap); + va_end(ap); + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_sprintf(char *str, const char *format, dfsan_label str_label, + dfsan_label format_label, dfsan_label *va_labels, + dfsan_label *ret_label, dfsan_origin str_origin, + dfsan_origin format_origin, dfsan_origin *va_origins, + dfsan_origin *ret_origin, ...) { + va_list ap; + va_start(ap, ret_origin); + int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins, + ret_origin, ap); va_end(ap); return ret; } @@ -1486,11 +2456,52 @@ int __dfsw_snprintf(char *str, size_t size, const char *format, dfsan_label *ret_label, ...) { va_list ap; va_start(ap, ret_label); - int ret = format_buffer(str, size, format, va_labels, ret_label, ap); + int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr, + nullptr, ap); va_end(ap); return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_snprintf(char *str, size_t size, const char *format, + dfsan_label str_label, dfsan_label size_label, + dfsan_label format_label, dfsan_label *va_labels, + dfsan_label *ret_label, dfsan_origin str_origin, + dfsan_origin size_origin, dfsan_origin format_origin, + dfsan_origin *va_origins, dfsan_origin *ret_origin, ...) { + va_list ap; + va_start(ap, ret_origin); + int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins, + ret_origin, ap); + va_end(ap); + return ret; +} + +static void BeforeFork() { + StackDepotLockAll(); + GetChainedOriginDepot()->LockAll(); +} + +static void AfterFork() { + GetChainedOriginDepot()->UnlockAll(); + StackDepotUnlockAll(); +} + +SANITIZER_INTERFACE_ATTRIBUTE +pid_t __dfsw_fork(dfsan_label *ret_label) { + pid_t pid = fork(); + *ret_label = 0; + return pid; +} + +SANITIZER_INTERFACE_ATTRIBUTE +pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) { + BeforeFork(); + pid_t pid = __dfsw_fork(ret_label); + AfterFork(); + return pid; +} + // Default empty implementations (weak). Users should redefine them. SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {} SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *, diff --git a/compiler-rt/lib/dfsan/dfsan_thread.cpp b/compiler-rt/lib/dfsan/dfsan_thread.cpp index 7fd9c8eff350..aa1209aafc33 100644 --- a/compiler-rt/lib/dfsan/dfsan_thread.cpp +++ b/compiler-rt/lib/dfsan/dfsan_thread.cpp @@ -7,13 +7,15 @@ namespace __dfsan { DFsanThread *DFsanThread::Create(void *start_routine_trampoline, - thread_callback_t start_routine, void *arg) { + thread_callback_t start_routine, void *arg, + bool track_origins) { uptr PageSize = GetPageSizeCached(); uptr size = RoundUpTo(sizeof(DFsanThread), PageSize); DFsanThread *thread = (DFsanThread *)MmapOrDie(size, __func__); thread->start_routine_trampoline_ = start_routine_trampoline; thread->start_routine_ = start_routine; thread->arg_ = arg; + thread->track_origins_ = track_origins; thread->destructor_iterations_ = GetPthreadDestructorIterations(); return thread; @@ -57,11 +59,19 @@ thread_return_t DFsanThread::ThreadStart() { typedef void *(*thread_callback_trampoline_t)(void *, void *, dfsan_label, dfsan_label *); + typedef void *(*thread_callback_origin_trampoline_t)( + void *, void *, dfsan_label, dfsan_label *, dfsan_origin, dfsan_origin *); dfsan_label ret_label; - return ((thread_callback_trampoline_t) + if (!track_origins_) + return ((thread_callback_trampoline_t) + start_routine_trampoline_)((void *)start_routine_, arg_, 0, + &ret_label); + + dfsan_origin ret_origin; + return ((thread_callback_origin_trampoline_t) start_routine_trampoline_)((void *)start_routine_, arg_, 0, - &ret_label); + &ret_label, 0, &ret_origin); } DFsanThread::StackBounds DFsanThread::GetStackBounds() const { diff --git a/compiler-rt/lib/dfsan/dfsan_thread.h b/compiler-rt/lib/dfsan/dfsan_thread.h index c28f1dfd47da..616bbc52661c 100644 --- a/compiler-rt/lib/dfsan/dfsan_thread.h +++ b/compiler-rt/lib/dfsan/dfsan_thread.h @@ -24,7 +24,8 @@ class DFsanThread { // via mmap() and *must* be valid in zero-initialized state. static DFsanThread *Create(void *start_routine_trampoline, - thread_callback_t start_routine, void *arg); + thread_callback_t start_routine, void *arg, + bool track_origins = false); static void TSDDtor(void *tsd); void Destroy(); @@ -54,6 +55,7 @@ class DFsanThread { void *start_routine_trampoline_; thread_callback_t start_routine_; void *arg_; + bool track_origins_; StackBounds stack_; diff --git a/compiler-rt/lib/dfsan/done_abilist.txt b/compiler-rt/lib/dfsan/done_abilist.txt index 1c993aa0b533..d41ee33203c9 100644 --- a/compiler-rt/lib/dfsan/done_abilist.txt +++ b/compiler-rt/lib/dfsan/done_abilist.txt @@ -30,6 +30,8 @@ fun:dfsan_flush=uninstrumented fun:dfsan_flush=discard fun:dfsan_print_origin_trace=uninstrumented fun:dfsan_print_origin_trace=discard +fun:dfsan_get_origin=uninstrumented +fun:dfsan_get_origin=custom fun:dfsan_get_init_origin=uninstrumented fun:dfsan_get_init_origin=discard @@ -270,6 +272,9 @@ fun:snprintf=custom fun:asprintf=discard fun:qsort=discard +# fork +fun:fork=custom + ############################################################################### # pthread ############################################################################### @@ -397,3 +402,5 @@ fun:__sanitizer_cov_pcs_init=discard # Ignores the dfsan wrappers. fun:__dfsw_*=uninstrumented fun:__dfsw_*=discard +fun:__dfso_*=uninstrumented +fun:__dfso_*=discard diff --git a/compiler-rt/lib/dfsan/scripts/check_custom_wrappers.sh b/compiler-rt/lib/dfsan/scripts/check_custom_wrappers.sh index 135027ece6e2..5f7160eb1478 100755 --- a/compiler-rt/lib/dfsan/scripts/check_custom_wrappers.sh +++ b/compiler-rt/lib/dfsan/scripts/check_custom_wrappers.sh @@ -20,11 +20,11 @@ on_exit() { # Ignore __sanitizer_cov_trace* because they are implemented elsewhere. trap on_exit EXIT grep -E "^fun:.*=custom" ${DFSAN_ABI_LIST} \ - | grep -v "dfsan_get_label\|__sanitizer_cov_trace" \ + | grep -v "dfsan_get_label\|dfsan_get_origin\|__sanitizer_cov_trace" \ | sed "s/^fun:\(.*\)=custom.*/\1/" | sort > $DIFF_A grep -E "__dfsw.*\(" ${DFSAN_CUSTOM_WRAPPERS} \ | grep -v "__sanitizer_cov_trace" \ - | sed "s/.*__dfsw_\(.*\)(.*/\1/" | sort > $DIFF_B + | sed "s/.*__dfsw_\(.*\)(.*/\1/" | sort | uniq > $DIFF_B diff -u $DIFF_A $DIFF_B > ${DIFFOUT} if [ $? -ne 0 ] then @@ -35,7 +35,7 @@ fi grep -E __dfsw_ ${DFSAN_CUSTOM_WRAPPERS} \ | grep -v "__sanitizer_cov_trace" \ - | sed "s/.*__dfsw_\([^(]*\).*/\1/" | sort > $DIFF_A + | sed "s/.*__dfsw_\([^(]*\).*/\1/" | sort | uniq > $DIFF_A grep -E "^[[:space:]]*test_.*\(\);" ${DFSAN_CUSTOM_TESTS} \ | sed "s/.*test_\(.*\)();/\1/" | sort > $DIFF_B diff -u $DIFF_A $DIFF_B > ${DIFFOUT} diff --git a/compiler-rt/lib/fuzzer/FuzzerBuiltins.h b/compiler-rt/lib/fuzzer/FuzzerBuiltins.h index 4c0ada82662d..ce0bd5cb47f4 100644 --- a/compiler-rt/lib/fuzzer/FuzzerBuiltins.h +++ b/compiler-rt/lib/fuzzer/FuzzerBuiltins.h @@ -26,7 +26,6 @@ inline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); } inline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); } inline uint32_t Clzll(unsigned long long X) { return __builtin_clzll(X); } -inline uint32_t Clz(unsigned long long X) { return __builtin_clz(X); } inline int Popcountll(unsigned long long X) { return __builtin_popcountll(X); } } // namespace fuzzer diff --git a/compiler-rt/lib/fuzzer/FuzzerBuiltinsMsvc.h b/compiler-rt/lib/fuzzer/FuzzerBuiltinsMsvc.h index c5bec9787d8e..ab191b60ef6e 100644 --- a/compiler-rt/lib/fuzzer/FuzzerBuiltinsMsvc.h +++ b/compiler-rt/lib/fuzzer/FuzzerBuiltinsMsvc.h @@ -52,12 +52,6 @@ inline uint32_t Clzll(uint64_t X) { return 64; } -inline uint32_t Clz(uint32_t X) { - unsigned long LeadZeroIdx = 0; - if (_BitScanReverse(&LeadZeroIdx, X)) return 31 - LeadZeroIdx; - return 32; -} - inline int Popcountll(unsigned long long X) { #if !defined(_M_ARM) && !defined(_M_X64) return __popcnt(X) + __popcnt(X >> 32); diff --git a/compiler-rt/lib/fuzzer/FuzzerCorpus.h b/compiler-rt/lib/fuzzer/FuzzerCorpus.h index daea4f5213b1..f8c126072c96 100644 --- a/compiler-rt/lib/fuzzer/FuzzerCorpus.h +++ b/compiler-rt/lib/fuzzer/FuzzerCorpus.h @@ -44,7 +44,7 @@ struct InputInfo { // Power schedule. bool NeedsEnergyUpdate = false; double Energy = 0.0; - size_t SumIncidence = 0; + double SumIncidence = 0.0; Vector> FeatureFreqs; // Delete feature Idx and its frequency from FeatureFreqs. @@ -74,27 +74,28 @@ struct InputInfo { void UpdateEnergy(size_t GlobalNumberOfFeatures, bool ScalePerExecTime, std::chrono::microseconds AverageUnitExecutionTime) { Energy = 0.0; - SumIncidence = 0; + SumIncidence = 0.0; // Apply add-one smoothing to locally discovered features. for (auto F : FeatureFreqs) { - size_t LocalIncidence = F.second + 1; - Energy -= LocalIncidence * logl(LocalIncidence); + double LocalIncidence = F.second + 1; + Energy -= LocalIncidence * log(LocalIncidence); SumIncidence += LocalIncidence; } // Apply add-one smoothing to locally undiscovered features. - // PreciseEnergy -= 0; // since logl(1.0) == 0) - SumIncidence += (GlobalNumberOfFeatures - FeatureFreqs.size()); + // PreciseEnergy -= 0; // since log(1.0) == 0) + SumIncidence += + static_cast(GlobalNumberOfFeatures - FeatureFreqs.size()); // Add a single locally abundant feature apply add-one smoothing. - size_t AbdIncidence = NumExecutedMutations + 1; - Energy -= AbdIncidence * logl(AbdIncidence); + double AbdIncidence = static_cast(NumExecutedMutations + 1); + Energy -= AbdIncidence * log(AbdIncidence); SumIncidence += AbdIncidence; // Normalize. if (SumIncidence != 0) - Energy = (Energy / SumIncidence) + logl(SumIncidence); + Energy = Energy / SumIncidence + log(SumIncidence); if (ScalePerExecTime) { // Scaling to favor inputs with lower execution time. @@ -213,6 +214,8 @@ class InputCorpus { assert(!U.empty()); if (FeatureDebug) Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures); + // Inputs.size() is cast to uint32_t below. + assert(Inputs.size() < std::numeric_limits::max()); Inputs.push_back(new InputInfo()); InputInfo &II = *Inputs.back(); II.U = U; @@ -224,7 +227,7 @@ class InputCorpus { II.HasFocusFunction = HasFocusFunction; // Assign maximal energy to the new seed. II.Energy = RareFeatures.empty() ? 1.0 : log(RareFeatures.size()); - II.SumIncidence = RareFeatures.size(); + II.SumIncidence = static_cast(RareFeatures.size()); II.NeedsEnergyUpdate = false; std::sort(II.UniqFeatureSet.begin(), II.UniqFeatureSet.end()); ComputeSHA1(U.data(), U.size(), II.Sha1); @@ -399,7 +402,7 @@ class InputCorpus { // Zero energy seeds will never be fuzzed and remain zero energy. if (II->Energy > 0.0) { II->SumIncidence += 1; - II->Energy += logl(II->SumIncidence) / II->SumIncidence; + II->Energy += log(II->SumIncidence) / II->SumIncidence; } } @@ -426,7 +429,8 @@ class InputCorpus { NumUpdatedFeatures++; if (FeatureDebug) Printf("ADD FEATURE %zd sz %d\n", Idx, NewSize); - SmallestElementPerFeature[Idx] = Inputs.size(); + // Inputs.size() is guaranteed to be less than UINT32_MAX by AddToCorpus. + SmallestElementPerFeature[Idx] = static_cast(Inputs.size()); InputSizesPerFeature[Idx] = NewSize; return true; } @@ -464,7 +468,7 @@ class InputCorpus { static const bool FeatureDebug = false; - size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; } + uint32_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; } void ValidateFeatureSet() { if (FeatureDebug) @@ -539,9 +543,11 @@ class InputCorpus { if (VanillaSchedule) { for (size_t i = 0; i < N; i++) - Weights[i] = Inputs[i]->NumFeatures - ? (i + 1) * (Inputs[i]->HasFocusFunction ? 1000 : 1) - : 0.; + Weights[i] = + Inputs[i]->NumFeatures + ? static_cast((i + 1) * + (Inputs[i]->HasFocusFunction ? 1000 : 1)) + : 0.; } if (FeatureDebug) { diff --git a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp index 0e9cdf7e66b1..23d422590d19 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp @@ -60,6 +60,7 @@ bool BlockCoverage::AppendCoverage(std::istream &IN) { CoveredBlocks.push_back(BB); } if (CoveredBlocks.empty()) return false; + // Ensures no CoverageVector is longer than UINT32_MAX. uint32_t NumBlocks = CoveredBlocks.back(); CoveredBlocks.pop_back(); for (auto BB : CoveredBlocks) @@ -200,7 +201,8 @@ bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction, Printf("INFO: AUTOFOCUS: %zd %s\n", FocusFuncIdx, FunctionNames[FocusFuncIdx].c_str()); for (size_t i = 0; i < NumFunctions; i++) { - if (!Weights[i]) continue; + if (Weights[i] == 0.0) + continue; Printf(" [%zd] W %g\tBB-tot %u\tBB-cov %u\tEntryFreq %u:\t%s\n", i, Weights[i], Coverage.GetNumberOfBlocks(i), Coverage.GetNumberOfCoveredBlocks(i), Coverage.GetCounter(i, 0), diff --git a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.h b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.h index d6e3de30a4ef..07c03bb25651 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.h +++ b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.h @@ -42,7 +42,8 @@ int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath, const Vector &CorporaFiles); class BlockCoverage { - public: +public: + // These functions guarantee no CoverageVector is longer than UINT32_MAX. bool AppendCoverage(std::istream &IN); bool AppendCoverage(const std::string &S); @@ -50,7 +51,8 @@ class BlockCoverage { uint32_t GetCounter(size_t FunctionId, size_t BasicBlockId) { auto It = Functions.find(FunctionId); - if (It == Functions.end()) return 0; + if (It == Functions.end()) + return 0; const auto &Counters = It->second; if (BasicBlockId < Counters.size()) return Counters[BasicBlockId]; @@ -61,7 +63,7 @@ class BlockCoverage { auto It = Functions.find(FunctionId); if (It == Functions.end()) return 0; const auto &Counters = It->second; - return Counters.size(); + return static_cast(Counters.size()); } uint32_t GetNumberOfCoveredBlocks(size_t FunctionId) { @@ -78,8 +80,7 @@ class BlockCoverage { Vector FunctionWeights(size_t NumFunctions) const; void clear() { Functions.clear(); } - private: - +private: typedef Vector CoverageVector; uint32_t NumberOfCoveredBlocks(const CoverageVector &Counters) const { @@ -91,7 +92,8 @@ class BlockCoverage { } uint32_t NumberOfUncoveredBlocks(const CoverageVector &Counters) const { - return Counters.size() - NumberOfCoveredBlocks(Counters); + return static_cast(Counters.size()) - + NumberOfCoveredBlocks(Counters); } uint32_t SmallestNonZeroCounter(const CoverageVector &Counters) const { diff --git a/compiler-rt/lib/fuzzer/FuzzerDictionary.h b/compiler-rt/lib/fuzzer/FuzzerDictionary.h index 301c5d9afecf..db55907d9363 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDictionary.h +++ b/compiler-rt/lib/fuzzer/FuzzerDictionary.h @@ -23,12 +23,14 @@ template class FixedWord { public: static const size_t kMaxSize = kMaxSizeT; FixedWord() {} - FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); } + FixedWord(const uint8_t *B, size_t S) { Set(B, S); } - void Set(const uint8_t *B, uint8_t S) { + void Set(const uint8_t *B, size_t S) { + static_assert(kMaxSizeT <= std::numeric_limits::max(), + "FixedWord::kMaxSizeT cannot fit in a uint8_t."); assert(S <= kMaxSize); memcpy(Data, B, S); - Size = S; + Size = static_cast(S); } bool operator==(const FixedWord &w) const { diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index 447cafce7fd4..ceaa9070512f 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -159,14 +159,14 @@ static bool ParseOneFlag(const char *Param) { const char *Str = FlagValue(Param, Name); if (Str) { if (FlagDescriptions[F].IntFlag) { - int Val = MyStol(Str); - *FlagDescriptions[F].IntFlag = Val; + auto Val = MyStol(Str); + *FlagDescriptions[F].IntFlag = static_cast(Val); if (Flags.verbosity >= 2) Printf("Flag: %s %d\n", Name, Val); return true; } else if (FlagDescriptions[F].UIntFlag) { - unsigned int Val = std::stoul(Str); - *FlagDescriptions[F].UIntFlag = Val; + auto Val = std::stoul(Str); + *FlagDescriptions[F].UIntFlag = static_cast(Val); if (Flags.verbosity >= 2) Printf("Flag: %s %u\n", Name, Val); return true; @@ -789,8 +789,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { unsigned Seed = Flags.seed; // Initialize Seed. if (Seed == 0) - Seed = - std::chrono::system_clock::now().time_since_epoch().count() + GetPid(); + Seed = static_cast( + std::chrono::system_clock::now().time_since_epoch().count() + GetPid()); if (Flags.verbosity) Printf("INFO: Seed: %u\n", Seed); diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp index 44976b90ce54..5134a5d979e6 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp @@ -142,7 +142,9 @@ struct GlobalEnv { CollectDFT(SF); } auto Time2 = std::chrono::system_clock::now(); - Job->DftTimeInSeconds = duration_cast(Time2 - Time1).count(); + auto DftTimeInSeconds = duration_cast(Time2 - Time1).count(); + assert(DftTimeInSeconds < std::numeric_limits::max()); + Job->DftTimeInSeconds = static_cast(DftTimeInSeconds); } if (!Seeds.empty()) { Job->SeedListPath = diff --git a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp index 6e3bf44f8b45..149742b4c2fe 100644 --- a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp @@ -440,8 +440,9 @@ void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) { if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) && secondsSinceProcessStartUp() >= 2) PrintStats("pulse "); - if (TimeOfUnit > TimeOfLongestUnitInSeconds * 1.1 && - TimeOfUnit >= Options.ReportSlowUnits) { + auto Threshhold = + static_cast(static_cast(TimeOfLongestUnitInSeconds) * 1.1); + if (TimeOfUnit > Threshhold && TimeOfUnit >= Options.ReportSlowUnits) { TimeOfLongestUnitInSeconds = TimeOfUnit; Printf("Slowest unit: %zd s:\n", TimeOfLongestUnitInSeconds); WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-"); @@ -501,6 +502,8 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, bool *FoundUniqFeatures) { if (!Size) return false; + // Largest input length should be INT_MAX. + assert(Size < std::numeric_limits::max()); ExecuteCallback(Data, Size); auto TimeOfUnit = duration_cast(UnitStopTime - UnitStartTime); @@ -508,8 +511,8 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, UniqFeatureSetTmp.clear(); size_t FoundUniqFeaturesOfII = 0; size_t NumUpdatesBefore = Corpus.NumFeatureUpdates(); - TPC.CollectFeatures([&](size_t Feature) { - if (Corpus.AddFeature(Feature, Size, Options.Shrink)) + TPC.CollectFeatures([&](uint32_t Feature) { + if (Corpus.AddFeature(Feature, static_cast(Size), Options.Shrink)) UniqFeatureSetTmp.push_back(Feature); if (Options.Entropic) Corpus.UpdateFeatureFrequency(II, Feature); @@ -575,7 +578,10 @@ static bool LooseMemeq(const uint8_t *A, const uint8_t *B, size_t Size) { !memcmp(A + Size - Limit / 2, B + Size - Limit / 2, Limit / 2); } -void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) { +// This method is not inlined because it would cause a test to fail where it +// is part of the stack unwinding. See D97975 for details. +ATTRIBUTE_NOINLINE void Fuzzer::ExecuteCallback(const uint8_t *Data, + size_t Size) { TPC.RecordInitialStack(); TotalNumberOfRuns++; assert(InFuzzingThread()); diff --git a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp index e865f154895c..162453ceae2c 100644 --- a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp @@ -82,9 +82,9 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) { while (std::getline(IS, Line, '\n')) { std::istringstream ISS1(Line); std::string Marker; - size_t N; - ISS1 >> Marker; - ISS1 >> N; + uint32_t N; + if (!(ISS1 >> Marker) || !(ISS1 >> N)) + return false; if (Marker == "STARTED") { // STARTED FILE_ID FILE_SIZE if (ExpectedStartMarker != N) diff --git a/compiler-rt/lib/fuzzer/FuzzerMutate.cpp b/compiler-rt/lib/fuzzer/FuzzerMutate.cpp index cf34a9fe8e2e..5209b86641fb 100644 --- a/compiler-rt/lib/fuzzer/FuzzerMutate.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerMutate.cpp @@ -61,14 +61,16 @@ MutationDispatcher::MutationDispatcher(Random &Rand, } static char RandCh(Random &Rand) { - if (Rand.RandBool()) return Rand(256); + if (Rand.RandBool()) + return static_cast(Rand(256)); const char Special[] = "!*'();:@&=+$,/?%#[]012Az-`~.\xff\x00"; return Special[Rand(sizeof(Special) - 1)]; } size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize) { - return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand()); + return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, + Rand.Rand()); } size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size, @@ -82,7 +84,8 @@ size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size, CustomCrossOverInPlaceHere.resize(MaxSize); auto &U = CustomCrossOverInPlaceHere; size_t NewSize = EF->LLVMFuzzerCustomCrossOver( - Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand()); + Data, Size, Other.data(), Other.size(), U.data(), U.size(), + Rand.Rand()); if (!NewSize) return 0; assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit"); @@ -135,7 +138,8 @@ size_t MutationDispatcher::Mutate_InsertRepeatedBytes(uint8_t *Data, // Insert new values at Data[Idx]. memmove(Data + Idx + N, Data + Idx, Size - Idx); // Give preference to 0x00 and 0xff. - uint8_t Byte = Rand.RandBool() ? Rand(256) : (Rand.RandBool() ? 0 : 255); + uint8_t Byte = static_cast( + Rand.RandBool() ? Rand(256) : (Rand.RandBool() ? 0 : 255)); for (size_t i = 0; i < N; i++) Data[Idx + i] = Byte; return Size + N; @@ -227,8 +231,8 @@ DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP( T Arg1, T Arg2, const uint8_t *Data, size_t Size) { if (Rand.RandBool()) Arg1 = Bswap(Arg1); if (Rand.RandBool()) Arg2 = Bswap(Arg2); - T Arg1Mutation = Arg1 + Rand(-1, 1); - T Arg2Mutation = Arg2 + Rand(-1, 1); + T Arg1Mutation = static_cast(Arg1 + Rand(-1, 1)); + T Arg2Mutation = static_cast(Arg2 + Rand(-1, 1)); return MakeDictionaryEntryFromCMP(&Arg1, &Arg2, &Arg1Mutation, &Arg2Mutation, sizeof(Arg1), Data, Size); } @@ -245,23 +249,23 @@ size_t MutationDispatcher::Mutate_AddWordFromTORC( DictionaryEntry DE; switch (Rand(4)) { case 0: { - auto X = TPC.TORC8.Get(Rand.Rand()); + auto X = TPC.TORC8.Get(Rand.Rand()); DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size); } break; case 1: { - auto X = TPC.TORC4.Get(Rand.Rand()); + auto X = TPC.TORC4.Get(Rand.Rand()); if ((X.A >> 16) == 0 && (X.B >> 16) == 0 && Rand.RandBool()) DE = MakeDictionaryEntryFromCMP((uint16_t)X.A, (uint16_t)X.B, Data, Size); else DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size); } break; case 2: { - auto X = TPC.TORCW.Get(Rand.Rand()); + auto X = TPC.TORCW.Get(Rand.Rand()); DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size); } break; case 3: if (Options.UseMemmem) { - auto X = TPC.MMT.Get(Rand.Rand()); - DE = DictionaryEntry(X); + auto X = TPC.MMT.Get(Rand.Rand()); + DE = DictionaryEntry(X); } break; default: assert(0); @@ -387,12 +391,12 @@ size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) { assert(Off + sizeof(T) <= Size); T Val; if (Off < 64 && !Rand(4)) { - Val = Size; + Val = static_cast(Size); if (Rand.RandBool()) Val = Bswap(Val); } else { memcpy(&Val, Data + Off, sizeof(Val)); - T Add = Rand(21); + T Add = static_cast(Rand(21)); Add -= 10; if (Rand.RandBool()) Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes. diff --git a/compiler-rt/lib/fuzzer/FuzzerRandom.h b/compiler-rt/lib/fuzzer/FuzzerRandom.h index 659283eee207..ad6c07eb5ef5 100644 --- a/compiler-rt/lib/fuzzer/FuzzerRandom.h +++ b/compiler-rt/lib/fuzzer/FuzzerRandom.h @@ -18,18 +18,27 @@ class Random : public std::minstd_rand { public: Random(unsigned int seed) : std::minstd_rand(seed) {} result_type operator()() { return this->std::minstd_rand::operator()(); } - size_t Rand() { return this->operator()(); } - size_t RandBool() { return Rand() % 2; } + template + typename std::enable_if::value, T>::type Rand() { + return static_cast(this->operator()()); + } + size_t RandBool() { return this->operator()() % 2; } size_t SkewTowardsLast(size_t n) { size_t T = this->operator()(n * n); - size_t Res = sqrt(T); + size_t Res = static_cast(sqrt(T)); return Res; } - size_t operator()(size_t n) { return n ? Rand() % n : 0; } - intptr_t operator()(intptr_t From, intptr_t To) { + template + typename std::enable_if::value, T>::type operator()(T n) { + return n ? Rand() % n : 0; + } + template + typename std::enable_if::value, T>::type + operator()(T From, T To) { assert(From < To); - intptr_t RangeSize = To - From + 1; - return operator()(RangeSize) + From; + auto RangeSize = static_cast(To) - + static_cast(From) + 1; + return static_cast(this->operator()(RangeSize) + From); } }; diff --git a/compiler-rt/lib/fuzzer/FuzzerSHA1.cpp b/compiler-rt/lib/fuzzer/FuzzerSHA1.cpp index 2005dc700305..b05655c8ef4d 100644 --- a/compiler-rt/lib/fuzzer/FuzzerSHA1.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerSHA1.cpp @@ -134,12 +134,13 @@ void sha1_hashBlock(sha1nfo *s) { s->state[4] += e; } -void sha1_addUncounted(sha1nfo *s, uint8_t data) { - uint8_t * const b = (uint8_t*) s->buffer; +// Adds the least significant byte of |data|. +void sha1_addUncounted(sha1nfo *s, uint32_t data) { + uint8_t *const b = (uint8_t *)s->buffer; #ifdef SHA_BIG_ENDIAN - b[s->bufferOffset] = data; + b[s->bufferOffset] = static_cast(data); #else - b[s->bufferOffset ^ 3] = data; + b[s->bufferOffset ^ 3] = static_cast(data); #endif s->bufferOffset++; if (s->bufferOffset == BLOCK_LENGTH) { diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp index 91e94d824002..d808b9b00fa3 100644 --- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp @@ -106,6 +106,15 @@ void TracePC::PrintModuleInfo() { } if (size_t NumExtraCounters = ExtraCountersEnd() - ExtraCountersBegin()) Printf("INFO: %zd Extra Counters\n", NumExtraCounters); + + size_t MaxFeatures = CollectFeatures([](uint32_t) {}); + if (MaxFeatures > std::numeric_limits::max()) + Printf("WARNING: The coverage PC tables may produce up to %zu features.\n" + "This exceeds the maximum 32-bit value. Some features may be\n" + "ignored, and fuzzing may become less precise. If possible,\n" + "consider refactoring the fuzzer into several smaller fuzzers\n" + "linked against only a portion of the current target.\n", + MaxFeatures); } ATTRIBUTE_NO_SANITIZE_ALL @@ -356,7 +365,7 @@ void TracePC::AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2, uint8_t HammingDistance = 0; for (; I < Len; I++) { if (B1[I] != B2[I] || (StopAtZero && B1[I] == 0)) { - HammingDistance = Popcountll(B1[I] ^ B2[I]); + HammingDistance = static_cast(Popcountll(B1[I] ^ B2[I])); break; } } diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.h b/compiler-rt/lib/fuzzer/FuzzerTracePC.h index 63b232062651..1fa9ed11c698 100644 --- a/compiler-rt/lib/fuzzer/FuzzerTracePC.h +++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.h @@ -79,7 +79,7 @@ class TracePC { void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; } void SetPrintNewFuncs(size_t P) { NumPrintNewFuncs = P; } void UpdateObservedPCs(); - template void CollectFeatures(Callback CB) const; + template size_t CollectFeatures(Callback CB) const; void ResetMaps() { ValueProfileMap.Reset(); @@ -234,16 +234,16 @@ unsigned CounterToFeature(T Counter) { return Bit; } -template // void Callback(size_t Feature) -ATTRIBUTE_NO_SANITIZE_ADDRESS -ATTRIBUTE_NOINLINE -void TracePC::CollectFeatures(Callback HandleFeature) const { +template // void Callback(uint32_t Feature) +ATTRIBUTE_NO_SANITIZE_ADDRESS ATTRIBUTE_NOINLINE size_t +TracePC::CollectFeatures(Callback HandleFeature) const { auto Handle8bitCounter = [&](size_t FirstFeature, size_t Idx, uint8_t Counter) { if (UseCounters) - HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Counter)); + HandleFeature(static_cast(FirstFeature + Idx * 8 + + CounterToFeature(Counter))); else - HandleFeature(FirstFeature + Idx); + HandleFeature(static_cast(FirstFeature + Idx)); }; size_t FirstFeature = 0; @@ -263,16 +263,18 @@ void TracePC::CollectFeatures(Callback HandleFeature) const { if (UseValueProfileMask) { ValueProfileMap.ForEach([&](size_t Idx) { - HandleFeature(FirstFeature + Idx); + HandleFeature(static_cast(FirstFeature + Idx)); }); FirstFeature += ValueProfileMap.SizeInBits(); } // Step function, grows similar to 8 * Log_2(A). - auto StackDepthStepFunction = [](uint32_t A) -> uint32_t { - if (!A) return A; - uint32_t Log2 = Log(A); - if (Log2 < 3) return A; + auto StackDepthStepFunction = [](size_t A) -> size_t { + if (!A) + return A; + auto Log2 = Log(A); + if (Log2 < 3) + return A; Log2 -= 3; return (Log2 + 1) * 8 + ((A >> Log2) & 7); }; @@ -280,8 +282,13 @@ void TracePC::CollectFeatures(Callback HandleFeature) const { assert(StackDepthStepFunction(1024 * 4) == 80); assert(StackDepthStepFunction(1024 * 1024) == 144); - if (auto MaxStackOffset = GetMaxStackOffset()) - HandleFeature(FirstFeature + StackDepthStepFunction(MaxStackOffset / 8)); + if (auto MaxStackOffset = GetMaxStackOffset()) { + HandleFeature(static_cast( + FirstFeature + StackDepthStepFunction(MaxStackOffset / 8))); + FirstFeature += StackDepthStepFunction(std::numeric_limits::max()); + } + + return FirstFeature; } extern TracePC TPC; diff --git a/compiler-rt/lib/fuzzer/FuzzerUtil.cpp b/compiler-rt/lib/fuzzer/FuzzerUtil.cpp index 7eecb68d0729..4b161c4139a5 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtil.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtil.cpp @@ -111,7 +111,7 @@ bool ParseOneDictionaryEntry(const std::string &Str, Unit *U) { char Hex[] = "0xAA"; Hex[2] = Str[Pos + 2]; Hex[3] = Str[Pos + 3]; - U->push_back(strtol(Hex, nullptr, 16)); + U->push_back(static_cast(strtol(Hex, nullptr, 16))); Pos += 3; continue; } diff --git a/compiler-rt/lib/fuzzer/FuzzerUtil.h b/compiler-rt/lib/fuzzer/FuzzerUtil.h index e90be085008e..2ae58102759c 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtil.h +++ b/compiler-rt/lib/fuzzer/FuzzerUtil.h @@ -90,7 +90,9 @@ std::string SearchRegexCmd(const std::string &Regex); size_t SimpleFastHash(const uint8_t *Data, size_t Size); -inline uint32_t Log(uint32_t X) { return 32 - Clz(X) - 1; } +inline size_t Log(size_t X) { + return static_cast((sizeof(unsigned long long) * 8) - Clzll(X) - 1); +} inline size_t PageSize() { return 4096; } inline uint8_t *RoundUpByPage(uint8_t *P) { diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp index af4394616776..5034b4a28d3f 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp @@ -515,7 +515,7 @@ int ExecuteCommand(const Command &Cmd) { return rc; } - return Info.return_code; + return static_cast(Info.return_code); } bool ExecuteCommand(const Command &BaseCmd, std::string *CmdOutput) { diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index c5322110cb66..ce08ec3508c4 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -136,8 +136,6 @@ static void HWAsanCheckFailed(const char *file, int line, const char *cond, Die(); } -static constexpr uptr kMemoryUsageBufferSize = 4096; - static void HwasanFormatMemoryUsage(InternalScopedString &s) { HwasanThreadList &thread_list = hwasanThreadList(); auto thread_stats = thread_list.GetThreadStats(); @@ -155,6 +153,8 @@ static void HwasanFormatMemoryUsage(InternalScopedString &s) { } #if SANITIZER_ANDROID +static constexpr uptr kMemoryUsageBufferSize = 4096; + static char *memory_usage_buffer = nullptr; static void InitMemoryUsage() { @@ -171,7 +171,7 @@ void UpdateMemoryUsage() { return; if (!memory_usage_buffer) InitMemoryUsage(); - InternalScopedString s(kMemoryUsageBufferSize); + InternalScopedString s; HwasanFormatMemoryUsage(s); internal_strncpy(memory_usage_buffer, s.data(), kMemoryUsageBufferSize - 1); memory_usage_buffer[kMemoryUsageBufferSize - 1] = '\0'; @@ -265,8 +265,6 @@ void __hwasan_init() { hwasan_init_is_running = 1; SanitizerToolName = "HWAddressSanitizer"; - InitTlsSize(); - CacheBinaryName(); InitializeFlags(); @@ -493,7 +491,7 @@ extern "C" void *__hwasan_extra_spill_area() { } void __hwasan_print_memory_usage() { - InternalScopedString s(kMemoryUsageBufferSize); + InternalScopedString s; HwasanFormatMemoryUsage(s); Printf("%s\n", s.data()); } diff --git a/compiler-rt/lib/hwasan/hwasan.h b/compiler-rt/lib/hwasan/hwasan.h index d4521efd089a..24d96cedc044 100644 --- a/compiler-rt/lib/hwasan/hwasan.h +++ b/compiler-rt/lib/hwasan/hwasan.h @@ -14,11 +14,12 @@ #ifndef HWASAN_H #define HWASAN_H +#include "hwasan_flags.h" +#include "hwasan_interface_internal.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_stacktrace.h" -#include "hwasan_interface_internal.h" -#include "hwasan_flags.h" #include "ubsan/ubsan_platform.h" #ifndef HWASAN_CONTAINS_UBSAN @@ -35,10 +36,31 @@ typedef u8 tag_t; +#if defined(__x86_64__) +// Tags are done in middle bits using userspace aliasing. +constexpr unsigned kAddressTagShift = 39; +constexpr unsigned kTagBits = 3; + +// The alias region is placed next to the shadow so the upper bits of all +// taggable addresses matches the upper bits of the shadow base. This shift +// value determines which upper bits must match. It has a floor of 44 since the +// shadow is always 8TB. +// TODO(morehouse): In alias mode we can shrink the shadow and use a +// simpler/faster shadow calculation. +constexpr unsigned kTaggableRegionCheckShift = + __sanitizer::Max(kAddressTagShift + kTagBits + 1U, 44U); +#else // TBI (Top Byte Ignore) feature of AArch64: bits [63:56] are ignored in address // translation and can be used to store a tag. -const unsigned kAddressTagShift = 56; -const uptr kAddressTagMask = 0xFFUL << kAddressTagShift; +constexpr unsigned kAddressTagShift = 56; +constexpr unsigned kTagBits = 8; +#endif // defined(__x86_64__) + +// Mask for extracting tag bits from the lower 8 bits. +constexpr uptr kTagMask = (1UL << kTagBits) - 1; + +// Mask for extracting tag bits from full pointers. +constexpr uptr kAddressTagMask = kTagMask << kAddressTagShift; // Minimal alignment of the shadow base address. Determines the space available // for threads and stack histories. This is an ABI constant. @@ -50,7 +72,7 @@ const unsigned kRecordFPLShift = 4; const unsigned kRecordFPModulus = 1 << (64 - kRecordFPShift + kRecordFPLShift); static inline tag_t GetTagFromPointer(uptr p) { - return p >> kAddressTagShift; + return (p >> kAddressTagShift) & kTagMask; } static inline uptr UntagAddr(uptr tagged_addr) { diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp index 0b6b7347892e..a6fc794082a5 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp @@ -29,8 +29,8 @@ static AllocatorCache fallback_allocator_cache; static SpinMutex fallback_mutex; static atomic_uint8_t hwasan_allocator_tagging_enabled; -static const tag_t kFallbackAllocTag = 0xBB; -static const tag_t kFallbackFreeTag = 0xBC; +static constexpr tag_t kFallbackAllocTag = 0xBB & kTagMask; +static constexpr tag_t kFallbackFreeTag = 0xBC; enum RightAlignMode { kRightAlignNever, @@ -84,7 +84,8 @@ void HwasanAllocatorInit() { atomic_store_relaxed(&hwasan_allocator_tagging_enabled, !flags()->disable_allocator_tagging); SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null); - allocator.Init(common_flags()->allocator_release_to_os_interval_ms); + allocator.Init(common_flags()->allocator_release_to_os_interval_ms, + kAliasRegionStart); for (uptr i = 0; i < sizeof(tail_magic); i++) tail_magic[i] = GetCurrentThread()->GenerateRandomTag(); } @@ -148,7 +149,8 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, // Tagging can only be skipped when both tag_in_malloc and tag_in_free are // false. When tag_in_malloc = false and tag_in_free = true malloc needs to // retag to 0. - if ((flags()->tag_in_malloc || flags()->tag_in_free) && + if (InTaggableRegion(reinterpret_cast(user_ptr)) && + (flags()->tag_in_malloc || flags()->tag_in_free) && atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) { if (flags()->tag_in_malloc && malloc_bisect(stack, orig_size)) { tag_t tag = t ? t->GenerateRandomTag() : kFallbackAllocTag; @@ -175,6 +177,8 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, static bool PointerAndMemoryTagsMatch(void *tagged_ptr) { CHECK(tagged_ptr); uptr tagged_uptr = reinterpret_cast(tagged_ptr); + if (!InTaggableRegion(tagged_uptr)) + return true; tag_t mem_tag = *reinterpret_cast( MemToShadow(reinterpret_cast(UntagPtr(tagged_ptr)))); return PossiblyShortTagMatches(mem_tag, tagged_uptr, 1); @@ -187,7 +191,9 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { if (!PointerAndMemoryTagsMatch(tagged_ptr)) ReportInvalidFree(stack, reinterpret_cast(tagged_ptr)); - void *untagged_ptr = UntagPtr(tagged_ptr); + void *untagged_ptr = InTaggableRegion(reinterpret_cast(tagged_ptr)) + ? UntagPtr(tagged_ptr) + : tagged_ptr; void *aligned_ptr = reinterpret_cast( RoundDownTo(reinterpret_cast(untagged_ptr), kShadowAlignment)); Metadata *meta = @@ -219,10 +225,14 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { Min(TaggedSize(orig_size), (uptr)flags()->max_free_fill_size); internal_memset(aligned_ptr, flags()->free_fill_byte, fill_size); } - if (flags()->tag_in_free && malloc_bisect(stack, 0) && - atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) + if (InTaggableRegion(reinterpret_cast(tagged_ptr)) && + flags()->tag_in_free && malloc_bisect(stack, 0) && + atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) { + // Always store full 8-bit tags on free to maximize UAF detection. + tag_t tag = t ? t->GenerateRandomTag(/*num_bits=*/8) : kFallbackFreeTag; TagMemoryAligned(reinterpret_cast(aligned_ptr), TaggedSize(orig_size), - t ? t->GenerateRandomTag() : kFallbackFreeTag); + tag); + } if (t) { allocator.Deallocate(t->allocator_cache(), aligned_ptr); if (auto *ha = t->heap_allocations()) @@ -365,7 +375,7 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size, // OOM error is already taken care of by HwasanAllocate. return errno_ENOMEM; CHECK(IsAligned((uptr)ptr, alignment)); - *(void **)UntagPtr(memptr) = ptr; + *memptr = ptr; return 0; } diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h index 43670a6a3fb7..03bbcff3f0f2 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.h +++ b/compiler-rt/lib/hwasan/hwasan_allocator.h @@ -13,13 +13,15 @@ #ifndef HWASAN_ALLOCATOR_H #define HWASAN_ALLOCATOR_H +#include "hwasan.h" +#include "hwasan_interface_internal.h" +#include "hwasan_poisoning.h" #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator_checks.h" #include "sanitizer_common/sanitizer_allocator_interface.h" #include "sanitizer_common/sanitizer_allocator_report.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_ring_buffer.h" -#include "hwasan_poisoning.h" #if !defined(__aarch64__) && !defined(__x86_64__) #error Unsupported platform @@ -55,7 +57,12 @@ static const uptr kMaxAllowedMallocSize = 1UL << 40; // 1T struct AP64 { static const uptr kSpaceBeg = ~0ULL; + +#if defined(__x86_64__) + static const uptr kSpaceSize = 1ULL << kAddressTagShift; +#else static const uptr kSpaceSize = 0x2000000000ULL; +#endif static const uptr kMetadataSize = sizeof(Metadata); typedef __sanitizer::VeryDenseSizeClassMap SizeClassMap; using AddressSpaceView = LocalAddressSpaceView; @@ -102,6 +109,16 @@ typedef RingBuffer HeapAllocationsRingBuffer; void GetAllocatorStats(AllocatorStatCounters s); +inline bool InTaggableRegion(uptr addr) { +#if defined(__x86_64__) + // Aliases are mapped next to shadow so that the upper bits match the shadow + // base. + return (addr >> kTaggableRegionCheckShift) == + (__hwasan_shadow_memory_dynamic_address >> kTaggableRegionCheckShift); +#endif + return true; +} + } // namespace __hwasan #endif // HWASAN_ALLOCATOR_H diff --git a/compiler-rt/lib/hwasan/hwasan_checks.h b/compiler-rt/lib/hwasan/hwasan_checks.h index a8de0fef20f0..ab543ea88beb 100644 --- a/compiler-rt/lib/hwasan/hwasan_checks.h +++ b/compiler-rt/lib/hwasan/hwasan_checks.h @@ -13,6 +13,7 @@ #ifndef HWASAN_CHECKS_H #define HWASAN_CHECKS_H +#include "hwasan_allocator.h" #include "hwasan_mapping.h" #include "sanitizer_common/sanitizer_common.h" @@ -81,6 +82,8 @@ enum class AccessType { Load, Store }; template __attribute__((always_inline, nodebug)) static void CheckAddress(uptr p) { + if (!InTaggableRegion(p)) + return; uptr ptr_raw = p & ~kAddressTagMask; tag_t mem_tag = *(tag_t *)MemToShadow(ptr_raw); if (UNLIKELY(!PossiblyShortTagMatches(mem_tag, p, 1 << LogSize))) { @@ -94,7 +97,7 @@ __attribute__((always_inline, nodebug)) static void CheckAddress(uptr p) { template __attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p, uptr sz) { - if (sz == 0) + if (sz == 0 || !InTaggableRegion(p)) return; tag_t ptr_tag = GetTagFromPointer(p); uptr ptr_raw = p & ~kAddressTagMask; diff --git a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp index 12730b29bae3..f53276e330d3 100644 --- a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp +++ b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp @@ -12,15 +12,17 @@ /// //===----------------------------------------------------------------------===// -#include "hwasan.h" #include "hwasan_dynamic_shadow.h" -#include "hwasan_mapping.h" -#include "sanitizer_common/sanitizer_common.h" -#include "sanitizer_common/sanitizer_posix.h" #include #include +#include "hwasan.h" +#include "hwasan_mapping.h" +#include "hwasan_thread_list.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_posix.h" + // The code in this file needs to run in an unrelocated binary. It should not // access any external symbol, including its own non-hidden globals. @@ -117,6 +119,12 @@ namespace __hwasan { void InitShadowGOT() {} uptr FindDynamicShadowStart(uptr shadow_size_bytes) { +#if defined(__x86_64__) + constexpr uptr kAliasSize = 1ULL << kAddressTagShift; + constexpr uptr kNumAliases = 1ULL << kTagBits; + return MapDynamicShadowAndAliases(shadow_size_bytes, kAliasSize, kNumAliases, + RingBufferSize()); +#endif return MapDynamicShadow(shadow_size_bytes, kShadowScale, kShadowBaseAlignment, kHighMemEnd); } diff --git a/compiler-rt/lib/hwasan/hwasan_flags.h b/compiler-rt/lib/hwasan/hwasan_flags.h index 0a6998f675d6..b17750158d02 100644 --- a/compiler-rt/lib/hwasan/hwasan_flags.h +++ b/compiler-rt/lib/hwasan/hwasan_flags.h @@ -12,6 +12,8 @@ #ifndef HWASAN_FLAGS_H #define HWASAN_FLAGS_H +#include "sanitizer_common/sanitizer_internal_defs.h" + namespace __hwasan { struct Flags { diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp index 44e569ee6d72..ad67e2787d31 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -221,8 +221,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), ThreadStartArg *A = reinterpret_cast (MmapOrDie( GetPageSizeCached(), "pthread_create")); *A = {callback, param}; - int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr), - &HwasanThreadStartFunc, A); + int res = REAL(pthread_create)(th, attr, &HwasanThreadStartFunc, A); return res; } diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp index 354bfe3e55f9..8ce0ff7da956 100644 --- a/compiler-rt/lib/hwasan/hwasan_linux.cpp +++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp @@ -76,6 +76,8 @@ uptr kHighShadowEnd; uptr kHighMemStart; uptr kHighMemEnd; +uptr kAliasRegionStart; // Always 0 on non-x86. + static void PrintRange(uptr start, uptr end, const char *name) { Printf("|| [%p, %p] || %.*s ||\n", (void *)start, (void *)end, 10, name); } @@ -123,7 +125,7 @@ void InitPrctl() { if (internal_iserror(internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0), &local_errno) && local_errno == EINVAL) { -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || defined(__x86_64__) // Some older Android kernels have the tagged pointer ABI on // unconditionally, and hence don't have the tagged-addr prctl while still // allow the ABI. @@ -179,6 +181,18 @@ bool InitShadow() { // High memory starts where allocated shadow allows. kHighMemStart = ShadowToMem(kHighShadowStart); +#if defined(__x86_64__) + constexpr uptr kAliasRegionOffset = 1ULL << (kTaggableRegionCheckShift - 1); + kAliasRegionStart = + __hwasan_shadow_memory_dynamic_address + kAliasRegionOffset; + + CHECK_EQ(kAliasRegionStart >> kTaggableRegionCheckShift, + __hwasan_shadow_memory_dynamic_address >> kTaggableRegionCheckShift); + CHECK_EQ( + (kAliasRegionStart + kAliasRegionOffset - 1) >> kTaggableRegionCheckShift, + __hwasan_shadow_memory_dynamic_address >> kTaggableRegionCheckShift); +#endif + // Check the sanity of the defined memory ranges (there might be gaps). CHECK_EQ(kHighMemStart % GetMmapGranularity(), 0); CHECK_GT(kHighMemStart, kHighShadowEnd); @@ -222,7 +236,9 @@ void InitThreads() { } bool MemIsApp(uptr p) { +#if !defined(__x86_64__) // Memory outside the alias range has non-zero tags. CHECK(GetTagFromPointer(p) == 0); +#endif return p >= kHighMemStart || (p >= kLowMemStart && p <= kLowMemEnd); } diff --git a/compiler-rt/lib/hwasan/hwasan_mapping.h b/compiler-rt/lib/hwasan/hwasan_mapping.h index c149687bdfa6..8243d1ec7ed5 100644 --- a/compiler-rt/lib/hwasan/hwasan_mapping.h +++ b/compiler-rt/lib/hwasan/hwasan_mapping.h @@ -48,6 +48,8 @@ extern uptr kHighShadowEnd; extern uptr kHighMemStart; extern uptr kHighMemEnd; +extern uptr kAliasRegionStart; + inline uptr MemToShadow(uptr untagged_addr) { return (untagged_addr >> kShadowScale) + __hwasan_shadow_memory_dynamic_address; diff --git a/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp b/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp index e82d77a1bc16..fab017aae60b 100644 --- a/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp +++ b/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp @@ -24,7 +24,7 @@ using namespace __hwasan; void *__hwasan_memset(void *block, int c, uptr size) { CheckAddressSized( reinterpret_cast(block), size); - return memset(UntagPtr(block), c, size); + return memset(block, c, size); } void *__hwasan_memcpy(void *to, const void *from, uptr size) { @@ -32,7 +32,7 @@ void *__hwasan_memcpy(void *to, const void *from, uptr size) { reinterpret_cast(to), size); CheckAddressSized( reinterpret_cast(from), size); - return memcpy(UntagPtr(to), UntagPtr(from), size); + return memcpy(to, from, size); } void *__hwasan_memmove(void *to, const void *from, uptr size) { diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp index 4448d9243767..c02177993918 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -224,7 +224,7 @@ static void PrintStackAllocations(StackAllocationsRingBuffer *sa, // We didn't find any locals. Most likely we don't have symbols, so dump // the information that we have for offline analysis. - InternalScopedString frame_desc(GetPageSizeCached() * 2); + InternalScopedString frame_desc; Printf("Previously allocated frames:\n"); for (uptr i = 0; i < frames; i++) { const uptr *record_addr = &(*sa)[i]; @@ -459,7 +459,7 @@ static void PrintTagInfoAroundAddr(tag_t *tag_ptr, uptr num_rows, RoundDownTo(reinterpret_cast(tag_ptr), row_len)); tag_t *beg_row = center_row_beg - row_len * (num_rows / 2); tag_t *end_row = center_row_beg + row_len * ((num_rows + 1) / 2); - InternalScopedString s(GetPageSizeCached() * 8); + InternalScopedString s; for (tag_t *row = beg_row; row < end_row; row += row_len) { s.append("%s", row == center_row_beg ? "=>" : " "); s.append("%p:", row); @@ -547,7 +547,7 @@ void ReportTailOverwritten(StackTrace *stack, uptr tagged_addr, uptr orig_size, GetStackTraceFromId(chunk.GetAllocStackId()).Print(); } - InternalScopedString s(GetPageSizeCached() * 8); + InternalScopedString s; CHECK_GT(tail_size, 0U); CHECK_LT(tail_size, kShadowAlignment); u8 *tail = reinterpret_cast(untagged_addr + orig_size); diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp index b81a6350c05c..c1f0e013b49f 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -113,18 +113,21 @@ static u32 xorshift(u32 state) { } // Generate a (pseudo-)random non-zero tag. -tag_t Thread::GenerateRandomTag() { +tag_t Thread::GenerateRandomTag(uptr num_bits) { + DCHECK_GT(num_bits, 0); if (tagging_disabled_) return 0; tag_t tag; + const uptr tag_mask = (1ULL << num_bits) - 1; do { if (flags()->random_tags) { if (!random_buffer_) random_buffer_ = random_state_ = xorshift(random_state_); CHECK(random_buffer_); - tag = random_buffer_ & 0xFF; - random_buffer_ >>= 8; + tag = random_buffer_ & tag_mask; + random_buffer_ >>= num_bits; } else { - tag = random_state_ = (random_state_ + 1) & 0xFF; + random_state_ += 1; + tag = random_state_ & tag_mask; } } while (!tag); return tag; diff --git a/compiler-rt/lib/hwasan/hwasan_thread.h b/compiler-rt/lib/hwasan/hwasan_thread.h index 88958daf767c..1c71cab41c42 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.h +++ b/compiler-rt/lib/hwasan/hwasan_thread.h @@ -42,7 +42,7 @@ class Thread { HeapAllocationsRingBuffer *heap_allocations() { return heap_allocations_; } StackAllocationsRingBuffer *stack_allocations() { return stack_allocations_; } - tag_t GenerateRandomTag(); + tag_t GenerateRandomTag(uptr num_bits = kTagBits); void DisableTagging() { tagging_disabled_++; } void EnableTagging() { tagging_disabled_--; } diff --git a/compiler-rt/lib/lsan/lsan.cpp b/compiler-rt/lib/lsan/lsan.cpp index 2c0a3bf0787c..b264be0ba792 100644 --- a/compiler-rt/lib/lsan/lsan.cpp +++ b/compiler-rt/lib/lsan/lsan.cpp @@ -98,7 +98,6 @@ extern "C" void __lsan_init() { InitCommonLsan(); InitializeAllocator(); ReplaceSystemMalloc(); - InitTlsSize(); InitializeInterceptors(); InitializeThreadRegistry(); InstallDeadlySignalHandlers(LsanOnDeadlySignal); diff --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp index 70422957e6f3..91e34ebb3214 100644 --- a/compiler-rt/lib/lsan/lsan_allocator.cpp +++ b/compiler-rt/lib/lsan/lsan_allocator.cpp @@ -123,14 +123,18 @@ void Deallocate(void *p) { void *Reallocate(const StackTrace &stack, void *p, uptr new_size, uptr alignment) { - RegisterDeallocation(p); if (new_size > max_malloc_size) { - allocator.Deallocate(GetAllocatorCache(), p); - return ReportAllocationSizeTooBig(new_size, stack); + ReportAllocationSizeTooBig(new_size, stack); + return nullptr; } - p = allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment); - RegisterAllocation(stack, p, new_size); - return p; + RegisterDeallocation(p); + void *new_p = + allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment); + if (new_p) + RegisterAllocation(stack, new_p, new_size); + else if (new_size != 0) + RegisterAllocation(stack, p, new_size); + return new_p; } void GetAllocatorCacheRange(uptr *begin, uptr *end) { diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp index d5b4132b24d5..74400d2e8426 100644 --- a/compiler-rt/lib/lsan/lsan_common.cpp +++ b/compiler-rt/lib/lsan/lsan_common.cpp @@ -895,7 +895,7 @@ void LeakReport::PrintSummary() { bytes += leaks_[i].total_size; allocations += leaks_[i].hit_count; } - InternalScopedString summary(kMaxSummaryLength); + InternalScopedString summary; summary.append("%zu byte(s) leaked in %zu allocation(s).", bytes, allocations); ReportErrorSummary(summary.data()); diff --git a/compiler-rt/lib/memprof/memprof_descriptions.cpp b/compiler-rt/lib/memprof/memprof_descriptions.cpp index ebd81d6f2f23..aa7ac5d971f8 100644 --- a/compiler-rt/lib/memprof/memprof_descriptions.cpp +++ b/compiler-rt/lib/memprof/memprof_descriptions.cpp @@ -48,7 +48,7 @@ void DescribeThread(MemprofThreadContext *context) { return; } context->announced = true; - InternalScopedString str(1024); + InternalScopedString str; str.append("Thread %s", MemprofThreadIdAndName(context).c_str()); if (context->parent_tid == kInvalidTid) { str.append(" created by unknown thread\n"); diff --git a/compiler-rt/lib/memprof/memprof_rtl.cpp b/compiler-rt/lib/memprof/memprof_rtl.cpp index d6d606f666ee..05759e406f7a 100644 --- a/compiler-rt/lib/memprof/memprof_rtl.cpp +++ b/compiler-rt/lib/memprof/memprof_rtl.cpp @@ -214,9 +214,6 @@ static void MemprofInitInternal() { InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); - // interceptors - InitTlsSize(); - // Create main thread. MemprofThread *main_thread = CreateMainThread(); CHECK_EQ(0, main_thread->tid()); diff --git a/compiler-rt/lib/msan/msan.cpp b/compiler-rt/lib/msan/msan.cpp index 4be1630cd302..4ee7e2ec4dd6 100644 --- a/compiler-rt/lib/msan/msan.cpp +++ b/compiler-rt/lib/msan/msan.cpp @@ -436,7 +436,6 @@ void __msan_init() { InitializeInterceptors(); CheckASLR(); - InitTlsSize(); InstallDeadlySignalHandlers(MsanOnDeadlySignal); InstallAtExitHandler(); // Needs __cxa_atexit interceptor. diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c index 4293e8f7b5bf..649c73f9d361 100644 --- a/compiler-rt/lib/profile/GCDAProfiling.c +++ b/compiler-rt/lib/profile/GCDAProfiling.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -38,29 +39,6 @@ #include #endif -#if defined(__FreeBSD__) && defined(__i386__) -#define I386_FREEBSD 1 -#else -#define I386_FREEBSD 0 -#endif - -#if !defined(_MSC_VER) && !I386_FREEBSD -#include -#endif - -#if defined(_MSC_VER) -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -#elif I386_FREEBSD -/* System headers define 'size_t' incorrectly on x64 FreeBSD (prior to - * FreeBSD 10, r232261) when compiled in 32-bit mode. - */ -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -#endif - #include "InstrProfiling.h" #include "InstrProfilingUtil.h" diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h index 33f89d6d4992..eb836bc47876 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h @@ -35,9 +35,9 @@ class CombinedAllocator { secondary_.InitLinkerInitialized(); } - void Init(s32 release_to_os_interval_ms) { + void Init(s32 release_to_os_interval_ms, uptr heap_start = 0) { stats_.Init(); - primary_.Init(release_to_os_interval_ms); + primary_.Init(release_to_os_interval_ms, heap_start); secondary_.Init(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h index b90dabbf7769..fb5394cd39c4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -119,7 +119,8 @@ class SizeClassAllocator32 { typedef SizeClassAllocator32 ThisT; typedef SizeClassAllocator32LocalCache AllocatorCache; - void Init(s32 release_to_os_interval_ms) { + void Init(s32 release_to_os_interval_ms, uptr heap_start = 0) { + CHECK(!heap_start); possible_regions.Init(); internal_memset(size_class_info_array, 0, sizeof(size_class_info_array)); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h index 26753b6c8aeb..db30e138154a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -69,25 +69,45 @@ class SizeClassAllocator64 { return base + (static_cast(ptr32) << kCompactPtrScale); } - void Init(s32 release_to_os_interval_ms) { + // If heap_start is nonzero, assumes kSpaceSize bytes are already mapped R/W + // at heap_start and places the heap there. This mode requires kSpaceBeg == + // ~(uptr)0. + void Init(s32 release_to_os_interval_ms, uptr heap_start = 0) { uptr TotalSpaceSize = kSpaceSize + AdditionalSize(); - if (kUsingConstantSpaceBeg) { - CHECK(IsAligned(kSpaceBeg, SizeClassMap::kMaxSize)); - CHECK_EQ(kSpaceBeg, address_range.Init(TotalSpaceSize, - PrimaryAllocatorName, kSpaceBeg)); + PremappedHeap = heap_start != 0; + if (PremappedHeap) { + CHECK(!kUsingConstantSpaceBeg); + NonConstSpaceBeg = heap_start; + uptr RegionInfoSize = AdditionalSize(); + RegionInfoSpace = + address_range.Init(RegionInfoSize, PrimaryAllocatorName); + CHECK_NE(RegionInfoSpace, ~(uptr)0); + CHECK_EQ(RegionInfoSpace, + address_range.MapOrDie(RegionInfoSpace, RegionInfoSize, + "SizeClassAllocator: region info")); + MapUnmapCallback().OnMap(RegionInfoSpace, RegionInfoSize); } else { - // Combined allocator expects that an 2^N allocation is always aligned to - // 2^N. For this to work, the start of the space needs to be aligned as - // high as the largest size class (which also needs to be a power of 2). - NonConstSpaceBeg = address_range.InitAligned( - TotalSpaceSize, SizeClassMap::kMaxSize, PrimaryAllocatorName); - CHECK_NE(NonConstSpaceBeg, ~(uptr)0); + if (kUsingConstantSpaceBeg) { + CHECK(IsAligned(kSpaceBeg, SizeClassMap::kMaxSize)); + CHECK_EQ(kSpaceBeg, + address_range.Init(TotalSpaceSize, PrimaryAllocatorName, + kSpaceBeg)); + } else { + // Combined allocator expects that an 2^N allocation is always aligned + // to 2^N. For this to work, the start of the space needs to be aligned + // as high as the largest size class (which also needs to be a power of + // 2). + NonConstSpaceBeg = address_range.InitAligned( + TotalSpaceSize, SizeClassMap::kMaxSize, PrimaryAllocatorName); + CHECK_NE(NonConstSpaceBeg, ~(uptr)0); + } + RegionInfoSpace = SpaceEnd(); + MapWithCallbackOrDie(RegionInfoSpace, AdditionalSize(), + "SizeClassAllocator: region info"); } SetReleaseToOSIntervalMs(release_to_os_interval_ms); - MapWithCallbackOrDie(SpaceEnd(), AdditionalSize(), - "SizeClassAllocator: region info"); // Check that the RegionInfo array is aligned on the CacheLine size. - DCHECK_EQ(SpaceEnd() % kCacheLineSize, 0); + DCHECK_EQ(RegionInfoSpace % kCacheLineSize, 0); } s32 ReleaseToOSIntervalMs() const { @@ -596,6 +616,11 @@ class SizeClassAllocator64 { atomic_sint32_t release_to_os_interval_ms_; + uptr RegionInfoSpace; + + // True if the user has already mapped the entire heap R/W. + bool PremappedHeap; + struct Stats { uptr n_allocated; uptr n_freed; @@ -625,7 +650,7 @@ class SizeClassAllocator64 { RegionInfo *GetRegionInfo(uptr class_id) const { DCHECK_LT(class_id, kNumClasses); - RegionInfo *regions = reinterpret_cast(SpaceEnd()); + RegionInfo *regions = reinterpret_cast(RegionInfoSpace); return ®ions[class_id]; } @@ -650,6 +675,9 @@ class SizeClassAllocator64 { } bool MapWithCallback(uptr beg, uptr size, const char *name) { + if (PremappedHeap) + return beg >= NonConstSpaceBeg && + beg + size <= NonConstSpaceBeg + kSpaceSize; uptr mapped = address_range.Map(beg, size, name); if (UNLIKELY(!mapped)) return false; @@ -659,11 +687,18 @@ class SizeClassAllocator64 { } void MapWithCallbackOrDie(uptr beg, uptr size, const char *name) { + if (PremappedHeap) { + CHECK_GE(beg, NonConstSpaceBeg); + CHECK_LE(beg + size, NonConstSpaceBeg + kSpaceSize); + return; + } CHECK_EQ(beg, address_range.MapOrDie(beg, size, name)); MapUnmapCallback().OnMap(beg, size); } void UnmapWithCallbackOrDie(uptr beg, uptr size) { + if (PremappedHeap) + return; MapUnmapCallback().OnUnmap(beg, size); address_range.Unmap(beg, size); } @@ -832,6 +867,9 @@ class SizeClassAllocator64 { // Attempts to release RAM occupied by freed chunks back to OS. The region is // expected to be locked. + // + // TODO(morehouse): Support a callback on memory release so HWASan can release + // aliases as well. void MaybeReleaseToOS(uptr class_id, bool force) { RegionInfo *region = GetRegionInfo(class_id); const uptr chunk_size = ClassIdToSize(class_id); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp index 10b5c82f180b..33960d94a2f4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp @@ -87,7 +87,7 @@ const char *StripModuleName(const char *module) { void ReportErrorSummary(const char *error_message, const char *alt_tool_name) { if (!common_flags()->print_summary) return; - InternalScopedString buff(kMaxSummaryLength); + InternalScopedString buff; buff.append("SUMMARY: %s: %s", alt_tool_name ? alt_tool_name : SanitizerToolName, error_message); __sanitizer_report_error_summary(buff.data()); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 2fecc3b4bf7c..2b2629fc12dd 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -44,7 +44,7 @@ const uptr kMaxPathLength = 4096; const uptr kMaxThreadStackSize = 1 << 30; // 1Gb -static const uptr kErrorMessageBufferSize = 1 << 16; +const uptr kErrorMessageBufferSize = 1 << 16; // Denotes fake PC values that come from JIT/JAVA/etc. // For such PC values __tsan_symbolize_external_ex() will be called. @@ -135,6 +135,15 @@ void UnmapFromTo(uptr from, uptr to); uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale, uptr min_shadow_base_alignment, uptr &high_mem_end); +// Let S = max(shadow_size, num_aliases * alias_size, ring_buffer_size). +// Reserves 2*S bytes of address space to the right of the returned address and +// ring_buffer_size bytes to the left. The returned address is aligned to 2*S. +// Also creates num_aliases regions of accessible memory starting at offset S +// from the returned address. Each region has size alias_size and is backed by +// the same physical memory. +uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, + uptr num_aliases, uptr ring_buffer_size); + // Reserve memory range [beg, end]. If madvise_shadow is true then apply // madvise (e.g. hugepages, core dumping) requested by options. void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name, @@ -275,7 +284,6 @@ void SetSandboxingCallback(void (*f)()); void InitializeCoverage(bool enabled, const char *coverage_dir); -void InitTlsSize(); uptr GetTlsSize(); // Other @@ -344,8 +352,6 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid, void SetAlternateSignalStack(); void UnsetAlternateSignalStack(); -// We don't want a summary too long. -const int kMaxSummaryLength = 1024; // Construct a one-line string: // SUMMARY: SanitizerToolName: error_message // and pass it to __sanitizer_report_error_summary. @@ -442,8 +448,14 @@ inline uptr Log2(uptr x) { // Don't use std::min, std::max or std::swap, to minimize dependency // on libstdc++. -template T Min(T a, T b) { return a < b ? a : b; } -template T Max(T a, T b) { return a > b ? a : b; } +template +constexpr T Min(T a, T b) { + return a < b ? a : b; +} +template +constexpr T Max(T a, T b) { + return a > b ? a : b; +} template void Swap(T& a, T& b) { T tmp = a; a = b; @@ -592,21 +604,21 @@ class InternalMmapVector : public InternalMmapVectorNoCtor { InternalMmapVector &operator=(InternalMmapVector &&) = delete; }; -class InternalScopedString : public InternalMmapVector { +class InternalScopedString { public: - explicit InternalScopedString(uptr max_length) - : InternalMmapVector(max_length), length_(0) { - (*this)[0] = '\0'; - } - uptr length() { return length_; } + InternalScopedString() : buffer_(1) { buffer_[0] = '\0'; } + + uptr length() const { return buffer_.size() - 1; } void clear() { - (*this)[0] = '\0'; - length_ = 0; + buffer_.resize(1); + buffer_[0] = '\0'; } void append(const char *format, ...); + const char *data() const { return buffer_.data(); } + char *data() { return buffer_.data(); } private: - uptr length_; + InternalMmapVector buffer_; }; template diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S index 20f42f1ea94e..72e482754b62 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S @@ -1,6 +1,7 @@ #if defined(__aarch64__) && defined(__linux__) #include "sanitizer_common/sanitizer_asm.h" +#include "builtins/assembly.h" ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) @@ -9,6 +10,7 @@ ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) ASM_WRAPPER_NAME(vfork): // Save x30 in the off-stack spill area. + hint #25 // paciasp stp xzr, x30, [sp, #-16]! bl COMMON_INTERCEPTOR_SPILL_AREA ldp xzr, x30, [sp], 16 @@ -33,6 +35,7 @@ ASM_WRAPPER_NAME(vfork): bl COMMON_INTERCEPTOR_SPILL_AREA ldr x30, [x0] ldp x0, xzr, [sp], 16 + hint #29 // autiasp ret ASM_SIZE(vfork) @@ -40,4 +43,6 @@ ASM_SIZE(vfork) .weak vfork .set vfork, ASM_WRAPPER_NAME(vfork) +GNU_PROPERTY_BTI_PAC + #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp index 047c5a17ea6e..1037938f3d33 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp @@ -92,14 +92,13 @@ void *BackgroundThread(void *arg) { #endif void WriteToSyslog(const char *msg) { - InternalScopedString msg_copy(kErrorMessageBufferSize); + InternalScopedString msg_copy; msg_copy.append("%s", msg); - char *p = msg_copy.data(); - char *q; + const char *p = msg_copy.data(); // Print one line at a time. // syslog, at least on Android, has an implicit message length limit. - while ((q = internal_strchr(p, '\n'))) { + while (char* q = internal_strchr(p, '\n')) { *q = '\0'; WriteOneLineToSyslog(p); p = q + 1; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index 4f692f99c207..5d68ad8ee8e4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -103,7 +103,6 @@ void DisableCoreDumperIfNecessary() {} void InstallDeadlySignalHandlers(SignalHandlerType handler) {} void SetAlternateSignalStack() {} void UnsetAlternateSignalStack() {} -void InitTlsSize() {} bool SignalContext::IsStackOverflow() const { return false; } void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp index 9ea19bc21fa3..a65d3d896e33 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp @@ -38,7 +38,7 @@ void LibIgnore::AddIgnoredLibrary(const char *name_templ) { void LibIgnore::OnLibraryLoaded(const char *name) { BlockingMutexLock lock(&mutex_); // Try to match suppressions with symlink target. - InternalScopedString buf(kMaxPathLength); + InternalMmapVector buf(kMaxPathLength); if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 && buf[0]) { for (uptr i = 0; i < count_; i++) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 25c0751c9a38..b371477755fd 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -183,6 +183,14 @@ uptr internal_munmap(void *addr, uptr length) { return internal_syscall(SYSCALL(munmap), (uptr)addr, length); } +#if SANITIZER_LINUX +uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags, + void *new_address) { + return internal_syscall(SYSCALL(mremap), (uptr)old_address, old_size, + new_size, flags, (uptr)new_address); +} +#endif + int internal_mprotect(void *addr, uptr length, int prot) { return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot); } @@ -489,24 +497,24 @@ int TgKill(pid_t pid, tid_t tid, int sig) { } #endif -#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD +#if SANITIZER_GLIBC u64 NanoTime() { -#if SANITIZER_FREEBSD - timeval tv; -#else kernel_timeval tv; -#endif internal_memset(&tv, 0, sizeof(tv)); internal_syscall(SYSCALL(gettimeofday), &tv, 0); - return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000; + return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000; } -#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD - -#if SANITIZER_GLIBC +// Used by real_clock_gettime. uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { return internal_syscall(SYSCALL(clock_gettime), clk_id, tp); } -#endif // SANITIZER_GLIBC +#elif !SANITIZER_SOLARIS && !SANITIZER_NETBSD +u64 NanoTime() { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return (u64)ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; +} +#endif // Like getenv, but reads env directly from /proc (on Linux) or parses the // 'environ' array (on some others) and does not use libc. This function diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 41ae072d6cac..9a23fcfb3b93 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -98,7 +98,6 @@ class ThreadLister { // Exposed for testing. uptr ThreadDescriptorSize(); uptr ThreadSelf(); -uptr ThreadSelfOffset(); // Matches a library's file name against a base name (stripping path and version // information). diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 2fff501651a9..bd8f5d330b30 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,10 @@ #include #include #define pthread_getattr_np pthread_attr_get_np +// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before +// that, it was never implemented. So just define it to zero. +#undef MAP_NORESERVE +#define MAP_NORESERVE 0 #endif #if SANITIZER_NETBSD @@ -183,80 +188,8 @@ __attribute__((unused)) static bool GetLibcVersion(int *major, int *minor, #endif } -#if SANITIZER_GLIBC && !SANITIZER_GO -static uptr g_tls_size; - -#ifdef __i386__ -#define CHECK_GET_TLS_STATIC_INFO_VERSION (!__GLIBC_PREREQ(2, 27)) -#else -#define CHECK_GET_TLS_STATIC_INFO_VERSION 0 -#endif - -#if CHECK_GET_TLS_STATIC_INFO_VERSION -#define DL_INTERNAL_FUNCTION __attribute__((regparm(3), stdcall)) -#else -#define DL_INTERNAL_FUNCTION -#endif - -namespace { -struct GetTlsStaticInfoCall { - typedef void (*get_tls_func)(size_t*, size_t*); -}; -struct GetTlsStaticInfoRegparmCall { - typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION; -}; - -template -void CallGetTls(void* ptr, size_t* size, size_t* align) { - typename T::get_tls_func get_tls; - CHECK_EQ(sizeof(get_tls), sizeof(ptr)); - internal_memcpy(&get_tls, &ptr, sizeof(ptr)); - CHECK_NE(get_tls, 0); - get_tls(size, align); -} - -bool CmpLibcVersion(int major, int minor, int patch) { - int ma; - int mi; - int pa; - if (!GetLibcVersion(&ma, &mi, &pa)) - return false; - if (ma > major) - return true; - if (ma < major) - return false; - if (mi > minor) - return true; - if (mi < minor) - return false; - return pa >= patch; -} - -} // namespace - -void InitTlsSize() { - // all current supported platforms have 16 bytes stack alignment - const size_t kStackAlign = 16; - void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); - size_t tls_size = 0; - size_t tls_align = 0; - // On i?86, _dl_get_tls_static_info used to be internal_function, i.e. - // __attribute__((regparm(3), stdcall)) before glibc 2.27 and is normal - // function in 2.27 and later. - if (CHECK_GET_TLS_STATIC_INFO_VERSION && !CmpLibcVersion(2, 27, 0)) - CallGetTls(get_tls_static_info_ptr, - &tls_size, &tls_align); - else - CallGetTls(get_tls_static_info_ptr, - &tls_size, &tls_align); - if (tls_align < kStackAlign) - tls_align = kStackAlign; - g_tls_size = RoundUpTo(tls_size, tls_align); -} -#else -void InitTlsSize() { } -#endif // SANITIZER_GLIBC && !SANITIZER_GO - +// ThreadDescriptorSize() is only used by lsan to get the pointer to +// thread-specific data keys in the thread control block. #if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) || \ defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) || \ defined(__arm__) || SANITIZER_RISCV64) && \ @@ -329,13 +262,6 @@ uptr ThreadDescriptorSize() { return val; } -// The offset at which pointer to self is located in the thread descriptor. -const uptr kThreadSelfOffset = FIRST_32_SECOND_64(8, 16); - -uptr ThreadSelfOffset() { - return kThreadSelfOffset; -} - #if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 // TlsPreTcbSize includes size of struct pthread_descr and size of tcb // head structure. It lies before the static tls blocks. @@ -354,48 +280,63 @@ static uptr TlsPreTcbSize() { } #endif -uptr ThreadSelf() { - uptr descr_addr; -#if defined(__i386__) - asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset)); -#elif defined(__x86_64__) - asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset)); -#elif defined(__mips__) - // MIPS uses TLS variant I. The thread pointer (in hardware register $29) - // points to the end of the TCB + 0x7000. The pthread_descr structure is - // immediately in front of the TCB. TlsPreTcbSize() includes the size of the - // TCB and the size of pthread_descr. - const uptr kTlsTcbOffset = 0x7000; - uptr thread_pointer; - asm volatile(".set push;\ - .set mips64r2;\ - rdhwr %0,$29;\ - .set pop" : "=r" (thread_pointer)); - descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize(); -#elif defined(__aarch64__) || defined(__arm__) - descr_addr = reinterpret_cast(__builtin_thread_pointer()) - - ThreadDescriptorSize(); -#elif SANITIZER_RISCV64 - // https://github.com/riscv/riscv-elf-psabi-doc/issues/53 - uptr thread_pointer = reinterpret_cast(__builtin_thread_pointer()); - descr_addr = thread_pointer - TlsPreTcbSize(); -#elif defined(__s390__) - descr_addr = reinterpret_cast(__builtin_thread_pointer()); -#elif defined(__powerpc64__) - // PPC64LE uses TLS variant I. The thread pointer (in GPR 13) - // points to the end of the TCB + 0x7000. The pthread_descr structure is - // immediately in front of the TCB. TlsPreTcbSize() includes the size of the - // TCB and the size of pthread_descr. - const uptr kTlsTcbOffset = 0x7000; - uptr thread_pointer; - asm("addi %0,13,%1" : "=r"(thread_pointer) : "I"(-kTlsTcbOffset)); - descr_addr = thread_pointer - TlsPreTcbSize(); -#else -#error "unsupported CPU arch" -#endif - return descr_addr; +#if !SANITIZER_GO +namespace { +struct TlsRange { + uptr begin, end, align; + size_t tls_modid; + bool operator<(const TlsRange &rhs) const { return begin < rhs.begin; } +}; +} // namespace + +static int CollectStaticTlsRanges(struct dl_phdr_info *info, size_t size, + void *data) { + if (!info->dlpi_tls_data) + return 0; + const uptr begin = (uptr)info->dlpi_tls_data; + for (unsigned i = 0; i != info->dlpi_phnum; ++i) + if (info->dlpi_phdr[i].p_type == PT_TLS) { + static_cast *>(data)->push_back( + TlsRange{begin, begin + info->dlpi_phdr[i].p_memsz, + info->dlpi_phdr[i].p_align, info->dlpi_tls_modid}); + break; + } + return 0; } -#endif // (x86_64 || i386 || MIPS) && SANITIZER_LINUX + +static void GetStaticTlsRange(uptr *addr, uptr *size, uptr *align) { + InternalMmapVector ranges; + dl_iterate_phdr(CollectStaticTlsRanges, &ranges); + uptr len = ranges.size(); + Sort(ranges.begin(), len); + // Find the range with tls_modid=1. For glibc, because libc.so uses PT_TLS, + // this module is guaranteed to exist and is one of the initially loaded + // modules. + uptr one = 0; + while (one != len && ranges[one].tls_modid != 1) ++one; + if (one == len) { + // This may happen with musl if no module uses PT_TLS. + *addr = 0; + *size = 0; + *align = 1; + return; + } + // Find the maximum consecutive ranges. We consider two modules consecutive if + // the gap is smaller than the alignment. The dynamic loader places static TLS + // blocks this way not to waste space. + uptr l = one; + *align = ranges[l].align; + while (l != 0 && ranges[l].begin < ranges[l - 1].end + ranges[l - 1].align) + *align = Max(*align, ranges[--l].align); + uptr r = one + 1; + while (r != len && ranges[r].begin < ranges[r - 1].end + ranges[r - 1].align) + *align = Max(*align, ranges[r++].align); + *addr = ranges[l].begin; + *size = ranges[r - 1].end - ranges[l].begin; +} +#endif // !SANITIZER_GO +#endif // (x86_64 || i386 || mips || ...) && SANITIZER_LINUX && + // !SANITIZER_ANDROID #if SANITIZER_FREEBSD static void **ThreadSelfSegbase() { @@ -467,18 +408,54 @@ static void GetTls(uptr *addr, uptr *size) { *size = 0; } #elif SANITIZER_LINUX + uptr align; + GetStaticTlsRange(addr, size, &align); #if defined(__x86_64__) || defined(__i386__) || defined(__s390__) - *addr = ThreadSelf(); - *size = GetTlsSize(); - *addr -= *size; - *addr += ThreadDescriptorSize(); -#elif defined(__mips__) || defined(__aarch64__) || defined(__powerpc64__) || \ - defined(__arm__) || SANITIZER_RISCV64 - *addr = ThreadSelf(); - *size = GetTlsSize(); + if (SANITIZER_GLIBC) { +#if defined(__s390__) + align = Max(align, 16); #else - *addr = 0; - *size = 0; + align = Max(align, 64); +#endif + } + const uptr tp = RoundUpTo(*addr + *size, align); + + // lsan requires the range to additionally cover the static TLS surplus + // (elf/dl-tls.c defines 1664). Otherwise there may be false positives for + // allocations only referenced by tls in dynamically loaded modules. + if (SANITIZER_GLIBC) + *size += 1644; + + // Extend the range to include the thread control block. On glibc, lsan needs + // the range to include pthread::{specific_1stblock,specific} so that + // allocations only referenced by pthread_setspecific can be scanned. This may + // underestimate by at most TLS_TCB_ALIGN-1 bytes but it should be fine + // because the number of bytes after pthread::specific is larger. + *addr = tp - RoundUpTo(*size, align); + *size = tp - *addr + ThreadDescriptorSize(); +#else + if (SANITIZER_GLIBC) + *size += 1664; +#if defined(__powerpc64__) + // TODO Figure out why *addr may be zero and use TlsPreTcbSize. + void *ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); + uptr tls_size, tls_align; + ((void (*)(size_t *, size_t *))ptr)(&tls_size, &tls_align); + asm("addi %0,13,-0x7000" : "=r"(*addr)); + *addr -= TlsPreTcbSize(); + *size = RoundUpTo(tls_size + TlsPreTcbSize(), 16); +#elif defined(__mips__) || SANITIZER_RISCV64 + const uptr pre_tcb_size = TlsPreTcbSize(); + *addr -= pre_tcb_size; + *size += pre_tcb_size; +#else + // arm and aarch64 reserve two words at TP, so this underestimates the range. + // However, this is sufficient for the purpose of finding the pointers to + // thread-specific data keys. + const uptr tcb_size = ThreadDescriptorSize(); + *addr -= tcb_size; + *size += tcb_size; +#endif #endif #elif SANITIZER_FREEBSD void** segbase = ThreadSelfSegbase(); @@ -519,17 +496,11 @@ static void GetTls(uptr *addr, uptr *size) { #if !SANITIZER_GO uptr GetTlsSize() { -#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \ +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ SANITIZER_SOLARIS uptr addr, size; GetTls(&addr, &size); return size; -#elif SANITIZER_GLIBC -#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 - return RoundUpTo(g_tls_size + TlsPreTcbSize(), 16); -#else - return g_tls_size; -#endif #else return 0; #endif @@ -552,10 +523,9 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, if (!main) { // If stack and tls intersect, make them non-intersecting. if (*tls_addr > *stk_addr && *tls_addr < *stk_addr + *stk_size) { - CHECK_GT(*tls_addr + *tls_size, *stk_addr); - CHECK_LE(*tls_addr + *tls_size, *stk_addr + *stk_size); - *stk_size -= *tls_size; - *tls_addr = *stk_addr + *stk_size; + if (*stk_addr + *stk_size < *tls_addr + *tls_size) + *tls_size = *stk_addr + *stk_size - *tls_addr; + *stk_size = *tls_addr - *stk_addr; } } #endif @@ -574,20 +544,12 @@ struct DlIteratePhdrData { bool first; }; -static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { - DlIteratePhdrData *data = (DlIteratePhdrData*)arg; - InternalScopedString module_name(kMaxPathLength); - if (data->first) { - data->first = false; - // First module is the binary itself. - ReadBinaryNameCached(module_name.data(), module_name.size()); - } else if (info->dlpi_name) { - module_name.append("%s", info->dlpi_name); - } +static int AddModuleSegments(const char *module_name, dl_phdr_info *info, + InternalMmapVectorNoCtor *modules) { if (module_name[0] == '\0') return 0; LoadedModule cur_module; - cur_module.set(module_name.data(), info->dlpi_addr); + cur_module.set(module_name, info->dlpi_addr); for (int i = 0; i < (int)info->dlpi_phnum; i++) { const Elf_Phdr *phdr = &info->dlpi_phdr[i]; if (phdr->p_type == PT_LOAD) { @@ -599,7 +561,26 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { writable); } } - data->modules->push_back(cur_module); + modules->push_back(cur_module); + return 0; +} + +static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { + DlIteratePhdrData *data = (DlIteratePhdrData *)arg; + if (data->first) { + InternalMmapVector module_name(kMaxPathLength); + data->first = false; + // First module is the binary itself. + ReadBinaryNameCached(module_name.data(), module_name.size()); + return AddModuleSegments(module_name.data(), info, data->modules); + } + + if (info->dlpi_name) { + InternalScopedString module_name; + module_name.append("%s", info->dlpi_name); + return AddModuleSegments(module_name.data(), info, data->modules); + } + return 0; } @@ -829,13 +810,13 @@ u64 MonotonicNanoTime() { return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; } #else -// Non-Linux & Go always use the regular function. +// Non-glibc & Go always use the regular function. u64 MonotonicNanoTime() { timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; } -#endif // SANITIZER_LINUX && !SANITIZER_GO +#endif // SANITIZER_GLIBC && !SANITIZER_GO void ReExec() { const char *pathname = "/proc/self/exe"; @@ -904,6 +885,65 @@ uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale, return shadow_start; } +static uptr MmapSharedNoReserve(uptr addr, uptr size) { + return internal_mmap( + reinterpret_cast(addr), size, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); +} + +static uptr MremapCreateAlias(uptr base_addr, uptr alias_addr, + uptr alias_size) { +#if SANITIZER_LINUX + return internal_mremap(reinterpret_cast(base_addr), 0, alias_size, + MREMAP_MAYMOVE | MREMAP_FIXED, + reinterpret_cast(alias_addr)); +#else + CHECK(false && "mremap is not supported outside of Linux"); + return 0; +#endif +} + +static void CreateAliases(uptr start_addr, uptr alias_size, uptr num_aliases) { + uptr total_size = alias_size * num_aliases; + uptr mapped = MmapSharedNoReserve(start_addr, total_size); + CHECK_EQ(mapped, start_addr); + + for (uptr i = 1; i < num_aliases; ++i) { + uptr alias_addr = start_addr + i * alias_size; + CHECK_EQ(MremapCreateAlias(start_addr, alias_addr, alias_size), alias_addr); + } +} + +uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, + uptr num_aliases, uptr ring_buffer_size) { + CHECK_EQ(alias_size & (alias_size - 1), 0); + CHECK_EQ(num_aliases & (num_aliases - 1), 0); + CHECK_EQ(ring_buffer_size & (ring_buffer_size - 1), 0); + + const uptr granularity = GetMmapGranularity(); + shadow_size = RoundUpTo(shadow_size, granularity); + CHECK_EQ(shadow_size & (shadow_size - 1), 0); + + const uptr alias_region_size = alias_size * num_aliases; + const uptr alignment = + 2 * Max(Max(shadow_size, alias_region_size), ring_buffer_size); + const uptr left_padding = ring_buffer_size; + + const uptr right_size = alignment; + const uptr map_size = left_padding + 2 * alignment; + + const uptr map_start = reinterpret_cast(MmapNoAccess(map_size)); + CHECK_NE(map_start, static_cast(-1)); + const uptr right_start = RoundUpTo(map_start + left_padding, alignment); + + UnmapFromTo(map_start, right_start - left_padding); + UnmapFromTo(right_start + right_size, map_start + map_size); + + CreateAliases(right_start + right_size / 2, alias_size, num_aliases); + + return right_start; +} + void InitializePlatformCommonFlags(CommonFlags *cf) { #if SANITIZER_ANDROID if (&__libc_get_static_tls_bounds == nullptr) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index b0d7bcc645fa..5055df1ec29a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -142,6 +142,12 @@ uptr internal_munmap(void *addr, uptr length) { return munmap(addr, length); } +uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags, + void *new_address) { + CHECK(false && "internal_mremap is unimplemented on Mac"); + return 0; +} + int internal_mprotect(void *addr, uptr length, int prot) { return mprotect(addr, length, prot); } @@ -453,7 +459,7 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { // On OS X the executable path is saved to the stack by dyld. Reading it // from there is much faster than calling dladdr, especially for large // binaries with symbols. - InternalScopedString exe_path(kMaxPathLength); + InternalMmapVector exe_path(kMaxPathLength); uint32_t size = exe_path.size(); if (_NSGetExecutablePath(exe_path.data(), &size) == 0 && realpath(exe_path.data(), buf) != 0) { @@ -542,9 +548,6 @@ uptr GetTlsSize() { return 0; } -void InitTlsSize() { -} - uptr TlsBaseAddr() { uptr segbase = 0; #if defined(__x86_64__) @@ -1019,7 +1022,7 @@ void MaybeReexec() { if (DyldNeedsEnvVariable() && !lib_is_in_env) { // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime // library. - InternalScopedString program_name(1024); + InternalMmapVector program_name(1024); uint32_t buf_size = program_name.size(); _NSGetExecutablePath(program_name.data(), &buf_size); char *new_env = const_cast(info.dli_fname); @@ -1252,6 +1255,12 @@ uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale, return shadow_start; } +uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, + uptr num_aliases, uptr ring_buffer_size) { + CHECK(false && "HWASan aliasing is unimplemented on Mac"); + return 0; +} + uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, uptr *largest_gap_found, uptr *max_occupied_addr) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc b/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc index 647bcdfe105e..e3b664f68b61 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc @@ -120,11 +120,7 @@ INTERCEPTOR(int, malloc_make_nonpurgeable, void *ptr) { INTERCEPTOR(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name) { COMMON_MALLOC_ENTER(); - // Allocate |sizeof(COMMON_MALLOC_ZONE_NAME "-") + internal_strlen(name)| - // bytes. - size_t buflen = - sizeof(COMMON_MALLOC_ZONE_NAME "-") + (name ? internal_strlen(name) : 0); - InternalScopedString new_name(buflen); + InternalScopedString new_name; if (name && zone->introspect == sanitizer_zone.introspect) { new_name.append(COMMON_MALLOC_ZONE_NAME "-%s", name); name = new_name.data(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp index 98ac7365da05..ac20f915fefe 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp @@ -105,6 +105,12 @@ uptr internal_munmap(void *addr, uptr length) { return _REAL(munmap, addr, length); } +uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags, + void *new_address) { + CHECK(false && "internal_mremap is unimplemented on NetBSD"); + return 0; +} + int internal_mprotect(void *addr, uptr length, int prot) { DEFINE__REAL(int, mprotect, void *a, uptr b, int c); return _REAL(mprotect, addr, length, prot); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 3c9907f1bcb8..731df710df54 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -458,7 +458,7 @@ #define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD || SI_SOLARIS) #define SANITIZER_INTERCEPTOR_HOOKS \ - (SI_LINUX || SI_MAC || SI_WINDOWS || SI_NETBSD || SI_NETBSD || SI_SOLARIS) + (SI_LINUX || SI_MAC || SI_WINDOWS || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_RECV_RECVFROM SI_POSIX #define SANITIZER_INTERCEPT_SEND_SENDTO SI_POSIX #define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp index b1c15be58dea..b5a45ae72cd9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -35,7 +35,10 @@ #include #include #include +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-W#warnings" #include +#pragma clang diagnostic pop #include #include #include diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp index 2e080098283f..f8457a6aac41 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -275,8 +275,8 @@ void ReportFile::Write(const char *buffer, uptr length) { bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) { MemoryMappingLayout proc_maps(/*cache_enabled*/false); - InternalScopedString buff(kMaxPathLength); - MemoryMappedSegment segment(buff.data(), kMaxPathLength); + InternalMmapVector buff(kMaxPathLength); + MemoryMappedSegment segment(buff.data(), buff.size()); while (proc_maps.Next(&segment)) { if (segment.IsExecutable() && internal_strcmp(module, segment.filename) == 0) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h index e1a2b48e5cd8..b65dae644767 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h @@ -40,6 +40,10 @@ uptr internal_write(fd_t fd, const void *buf, uptr count); uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, u64 offset); uptr internal_munmap(void *addr, uptr length); +#if SANITIZER_LINUX +uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags, + void *new_address); +#endif int internal_mprotect(void *addr, uptr length, int prot); int internal_madvise(uptr addr, uptr length, int advice); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp index a032787114bb..5d16dfde6786 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp @@ -249,26 +249,21 @@ static void NOINLINE SharedPrintfCodeNoBuffer(bool append_pid, va_list args) { va_list args2; va_copy(args2, args); - const int kLen = 16 * 1024; - int needed_length; + InternalMmapVector v; + int needed_length = 0; char *buffer = local_buffer; // First try to print a message using a local buffer, and then fall back to // mmaped buffer. - for (int use_mmap = 0; use_mmap < 2; use_mmap++) { + for (int use_mmap = 0;; use_mmap++) { if (use_mmap) { va_end(args); va_copy(args, args2); - buffer = (char*)MmapOrDie(kLen, "Report"); - buffer_size = kLen; + v.resize(needed_length + 1); + buffer_size = v.capacity(); + v.resize(buffer_size); + buffer = &v[0]; } needed_length = 0; - // Check that data fits into the current buffer. -# define CHECK_NEEDED_LENGTH \ - if (needed_length >= buffer_size) { \ - if (!use_mmap) continue; \ - RAW_CHECK_MSG(needed_length < kLen, \ - "Buffer in Report is too short!\n"); \ - } // Fuchsia's logging infrastructure always keeps track of the logging // process, thread, and timestamp, so never prepend such information. if (!SANITIZER_FUCHSIA && append_pid) { @@ -277,18 +272,20 @@ static void NOINLINE SharedPrintfCodeNoBuffer(bool append_pid, if (common_flags()->log_exe_name && exe_name) { needed_length += internal_snprintf(buffer, buffer_size, "==%s", exe_name); - CHECK_NEEDED_LENGTH + if (needed_length >= buffer_size) + continue; } needed_length += internal_snprintf( buffer + needed_length, buffer_size - needed_length, "==%d==", pid); - CHECK_NEEDED_LENGTH + if (needed_length >= buffer_size) + continue; } needed_length += VSNPrintf(buffer + needed_length, buffer_size - needed_length, format, args); - CHECK_NEEDED_LENGTH + if (needed_length >= buffer_size) + continue; // If the message fit into the buffer, print it and exit. break; -# undef CHECK_NEEDED_LENGTH } RawWrite(buffer); @@ -297,9 +294,6 @@ static void NOINLINE SharedPrintfCodeNoBuffer(bool append_pid, CallPrintfAndReportCallback(buffer); LogMessageOnPrintf(buffer); - // If we had mapped any memory, clean up. - if (buffer != local_buffer) - UnmapOrDie((void *)buffer, buffer_size); va_end(args2); } @@ -346,13 +340,24 @@ int internal_snprintf(char *buffer, uptr length, const char *format, ...) { FORMAT(2, 3) void InternalScopedString::append(const char *format, ...) { - CHECK_LT(length_, size()); - va_list args; - va_start(args, format); - VSNPrintf(data() + length_, size() - length_, format, args); - va_end(args); - length_ += internal_strlen(data() + length_); - CHECK_LT(length_, size()); + uptr prev_len = length(); + + while (true) { + buffer_.resize(buffer_.capacity()); + + va_list args; + va_start(args, format); + uptr sz = VSNPrintf(buffer_.data() + prev_len, buffer_.size() - prev_len, + format, args); + va_end(args); + if (sz < buffer_.size() - prev_len) { + buffer_.resize(prev_len + sz + 1); + break; + } + + buffer_.reserve(buffer_.capacity() * 2); + } + CHECK_EQ(buffer_[length()], '\0'); } } // namespace __sanitizer diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp index f2cfcffaf476..1b7dd46d8de4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp @@ -120,7 +120,7 @@ void MemoryMappingLayout::LoadFromCache() { void MemoryMappingLayout::DumpListOfModules( InternalMmapVectorNoCtor *modules) { Reset(); - InternalScopedString module_name(kMaxPathLength); + InternalMmapVector module_name(kMaxPathLength); MemoryMappedSegment segment(module_name.data(), module_name.size()); for (uptr i = 0; Next(&segment); i++) { const char *cur_name = segment.filename; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp index d02afcfe87ae..1f53e3e46d8f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -354,8 +354,8 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { void MemoryMappingLayout::DumpListOfModules( InternalMmapVectorNoCtor *modules) { Reset(); - InternalScopedString module_name(kMaxPathLength); - MemoryMappedSegment segment(module_name.data(), kMaxPathLength); + InternalMmapVector module_name(kMaxPathLength); + MemoryMappedSegment segment(module_name.data(), module_name.size()); MemoryMappedSegmentData data; segment.data_ = &data; while (Next(&segment)) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h b/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h index a288068bf943..520035469485 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h @@ -11,6 +11,24 @@ #if __has_feature(ptrauth_calls) #include +#elif defined(__ARM_FEATURE_PAC_DEFAULT) && !defined(__APPLE__) +inline unsigned long ptrauth_strip(void* __value, unsigned int __key) { + // On the stack the link register is protected with Pointer + // Authentication Code when compiled with -mbranch-protection. + // Let's stripping the PAC unconditionally because xpaclri is in + // the NOP space so will do nothing when it is not enabled or not available. + unsigned long ret; + asm volatile( + "mov x30, %1\n\t" + "hint #7\n\t" // xpaclri + "mov %0, x30\n\t" + : "=r"(ret) + : "r"(__value) + : "x30"); + return ret; +} +#define ptrauth_auth_data(__value, __old_key, __old_data) __value +#define ptrauth_string_discriminator(__string) ((int)0) #else // Copied from #define ptrauth_strip(__value, __key) __value @@ -18,6 +36,6 @@ #define ptrauth_string_discriminator(__string) ((int)0) #endif -#define STRIP_PC(pc) ((uptr)ptrauth_strip(pc, 0)) +#define STRIP_PAC_PC(pc) ((uptr)ptrauth_strip(pc, 0)) #endif // SANITIZER_PTRAUTH_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp index d58bd08fb1a8..01554349cc04 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp @@ -106,7 +106,6 @@ void DisableCoreDumperIfNecessary() {} void InstallDeadlySignalHandlers(SignalHandlerType handler) {} void SetAlternateSignalStack() {} void UnsetAlternateSignalStack() {} -void InitTlsSize() {} void SignalContext::DumpAllRegisters(void *context) {} const char *DescribeSignalOrException(int signo) { UNIMPLEMENTED(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp index b0487d8987db..07e4409f4a5d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -15,6 +15,7 @@ #include "sanitizer_common.h" #include "sanitizer_flags.h" #include "sanitizer_platform.h" +#include "sanitizer_ptrauth.h" namespace __sanitizer { @@ -122,7 +123,7 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, // frame[-1] contains the return address uhwptr pc1 = frame[-1]; #else - uhwptr pc1 = frame[1]; + uhwptr pc1 = STRIP_PAC_PC((void *)frame[1]); #endif // Let's assume that any pointer in the 0th page (i.e. <0x1000 on i386 and // x86_64) is invalid and stop unwinding here. If we're adding support for diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp index 7808ba9b0f57..738633209f08 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -23,8 +23,8 @@ void StackTrace::Print() const { Printf(" \n\n"); return; } - InternalScopedString frame_desc(GetPageSizeCached() * 2); - InternalScopedString dedup_token(GetPageSizeCached()); + InternalScopedString frame_desc; + InternalScopedString dedup_token; int dedup_frames = common_flags()->dedup_token_length; bool symbolize = RenderNeedsSymbolization(common_flags()->stack_trace_format); uptr frame_num = 0; @@ -125,7 +125,7 @@ void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf, out_buf[out_buf_size - 1] = 0; return; } - InternalScopedString frame_desc(GetPageSizeCached()); + InternalScopedString frame_desc; uptr frame_num = 0; // Reserve one byte for the final 0. char *out_end = out_buf + out_buf_size - 1; @@ -156,7 +156,7 @@ void __sanitizer_symbolize_global(uptr data_addr, const char *fmt, out_buf[0] = 0; DataInfo DI; if (!Symbolizer::GetOrInit()->SymbolizeData(data_addr, &DI)) return; - InternalScopedString data_desc(GetPageSizeCached()); + InternalScopedString data_desc; RenderData(&data_desc, fmt, &DI, common_flags()->strip_path_prefix); internal_strncpy(out_buf, data_desc.data(), out_buf_size); out_buf[out_buf_size - 1] = 0; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp index 44c83a66c5fe..a674034b8e29 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp @@ -34,7 +34,7 @@ SuppressionContext::SuppressionContext(const char *suppression_types[], static bool GetPathAssumingFileIsRelativeToExec(const char *file_path, /*out*/char *new_file_path, uptr new_file_path_size) { - InternalScopedString exec(kMaxPathLength); + InternalMmapVector exec(kMaxPathLength); if (ReadBinaryNameCached(exec.data(), exec.size())) { const char *file_name_pos = StripModuleName(exec.data()); uptr path_to_exec_len = file_name_pos - exec.data(); @@ -69,7 +69,7 @@ void SuppressionContext::ParseFromFile(const char *filename) { if (filename[0] == '\0') return; - InternalScopedString new_file_path(kMaxPathLength); + InternalMmapVector new_file_path(kMaxPathLength); filename = FindFile(filename, new_file_path.data(), new_file_path.size()); // Read the file. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp index 76e1f2eeb929..4cd4b4636f0a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -408,10 +408,12 @@ static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) { } const char *binary_name = path ? StripModuleName(path) : ""; + static const char kLLVMSymbolizerPrefix[] = "llvm-symbolizer"; if (path && path[0] == '\0') { VReport(2, "External symbolizer is explicitly disabled.\n"); return nullptr; - } else if (!internal_strcmp(binary_name, "llvm-symbolizer")) { + } else if (!internal_strncmp(binary_name, kLLVMSymbolizerPrefix, + internal_strlen(kLLVMSymbolizerPrefix))) { VReport(2, "Using llvm-symbolizer at user-specified path: %s\n", path); return new(*allocator) LLVMSymbolizer(path, allocator); } else if (!internal_strcmp(binary_name, "atos")) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp index c99a6ceaa562..9287993e665f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -31,7 +31,7 @@ namespace __sanitizer { void ReportErrorSummary(const char *error_type, const AddressInfo &info, const char *alt_tool_name) { if (!common_flags()->print_summary) return; - InternalScopedString buff(kMaxSummaryLength); + InternalScopedString buff; buff.append("%s ", error_type); RenderFrame(&buff, "%L %F", 0, info.address, &info, common_flags()->symbolize_vs_style, @@ -150,7 +150,7 @@ static void PrintMemoryByte(InternalScopedString *str, const char *before, static void MaybeDumpInstructionBytes(uptr pc) { if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached())) return; - InternalScopedString str(1024); + InternalScopedString str; str.append("First 16 instruction bytes at pc: "); if (IsAccessibleMemoryRange(pc, 16)) { for (int i = 0; i < 16; ++i) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp index dc611a01a500..702d901353db 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp @@ -133,16 +133,13 @@ void InitializeDbgHelpIfNeeded() { } } -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wframe-larger-than=" -#endif bool WinSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *frame) { InitializeDbgHelpIfNeeded(); // See https://docs.microsoft.com/en-us/windows/win32/debug/retrieving-symbol-information-by-address - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; - PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; + InternalMmapVector buffer(sizeof(SYMBOL_INFO) + + MAX_SYM_NAME * sizeof(CHAR)); + PSYMBOL_INFO symbol = (PSYMBOL_INFO)&buffer[0]; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = MAX_SYM_NAME; DWORD64 offset = 0; @@ -166,9 +163,6 @@ bool WinSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *frame) { // Otherwise, try llvm-symbolizer. return got_fileline; } -#ifdef __clang__ -#pragma clang diagnostic pop -#endif const char *WinSymbolizerTool::Demangle(const char *name) { CHECK(is_dbghelp_initialized); @@ -230,7 +224,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() { // Compute the command line. Wrap double quotes around everything. const char *argv[kArgVMax]; GetArgV(path_, argv); - InternalScopedString command_line(kMaxPathLength * 3); + InternalScopedString command_line; for (int i = 0; argv[i]; i++) { const char *arg = argv[i]; int arglen = internal_strlen(arg); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index 99ecfd040c6a..d47ccad1764d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -390,6 +390,12 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, return 0; } +uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, + uptr num_aliases, uptr ring_buffer_size) { + CHECK(false && "HWASan aliasing is unimplemented on Windows"); + return 0; +} + bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { MEMORY_BASIC_INFORMATION mbi; CHECK(VirtualQuery((void *)range_start, &mbi, sizeof(mbi))); @@ -568,7 +574,7 @@ void Abort() { // load the image at this address. Therefore, we call it the preferred base. Any // addresses in the DWARF typically assume that the object has been loaded at // this address. -static uptr GetPreferredBase(const char *modname) { +static uptr GetPreferredBase(const char *modname, char *buf, size_t buf_size) { fd_t fd = OpenFile(modname, RdOnly, nullptr); if (fd == kInvalidFd) return 0; @@ -590,12 +596,10 @@ static uptr GetPreferredBase(const char *modname) { // IMAGE_FILE_HEADER // IMAGE_OPTIONAL_HEADER // Seek to e_lfanew and read all that data. - char buf[4 + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER)]; if (::SetFilePointer(fd, dos_header.e_lfanew, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER) return 0; - if (!ReadFromFile(fd, &buf[0], sizeof(buf), &bytes_read) || - bytes_read != sizeof(buf)) + if (!ReadFromFile(fd, buf, buf_size, &bytes_read) || bytes_read != buf_size) return 0; // Check for "PE\0\0" before the PE header. @@ -615,10 +619,6 @@ static uptr GetPreferredBase(const char *modname) { return (uptr)pe_header->ImageBase; } -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wframe-larger-than=" -#endif void ListOfModules::init() { clearOrInit(); HANDLE cur_process = GetCurrentProcess(); @@ -641,6 +641,10 @@ void ListOfModules::init() { } } + InternalMmapVector buf(4 + sizeof(IMAGE_FILE_HEADER) + + sizeof(IMAGE_OPTIONAL_HEADER)); + InternalMmapVector modname_utf16(kMaxPathLength); + InternalMmapVector module_name(kMaxPathLength); // |num_modules| is the number of modules actually present, size_t num_modules = bytes_required / sizeof(HMODULE); for (size_t i = 0; i < num_modules; ++i) { @@ -650,15 +654,13 @@ void ListOfModules::init() { continue; // Get the UTF-16 path and convert to UTF-8. - wchar_t modname_utf16[kMaxPathLength]; int modname_utf16_len = - GetModuleFileNameW(handle, modname_utf16, kMaxPathLength); + GetModuleFileNameW(handle, &modname_utf16[0], kMaxPathLength); if (modname_utf16_len == 0) modname_utf16[0] = '\0'; - char module_name[kMaxPathLength]; - int module_name_len = - ::WideCharToMultiByte(CP_UTF8, 0, modname_utf16, modname_utf16_len + 1, - &module_name[0], kMaxPathLength, NULL, NULL); + int module_name_len = ::WideCharToMultiByte( + CP_UTF8, 0, &modname_utf16[0], modname_utf16_len + 1, &module_name[0], + kMaxPathLength, NULL, NULL); module_name[module_name_len] = '\0'; uptr base_address = (uptr)mi.lpBaseOfDll; @@ -668,21 +670,19 @@ void ListOfModules::init() { // RVA when computing the module offset. This helps llvm-symbolizer find the // right DWARF CU. In the common case that the image is loaded at it's // preferred address, we will now print normal virtual addresses. - uptr preferred_base = GetPreferredBase(&module_name[0]); + uptr preferred_base = + GetPreferredBase(&module_name[0], &buf[0], buf.size()); uptr adjusted_base = base_address - preferred_base; - LoadedModule cur_module; - cur_module.set(module_name, adjusted_base); + modules_.push_back(LoadedModule()); + LoadedModule &cur_module = modules_.back(); + cur_module.set(&module_name[0], adjusted_base); // We add the whole module as one single address range. cur_module.addAddressRange(base_address, end_address, /*executable*/ true, /*writable*/ true); - modules_.push_back(cur_module); } UnmapOrDie(hmodules, modules_buffer_size); } -#ifdef __clang__ -#pragma clang diagnostic pop -#endif void ListOfModules::fallbackInit() { clear(); } @@ -846,9 +846,6 @@ uptr GetTlsSize() { return 0; } -void InitTlsSize() { -} - void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, uptr *tls_addr, uptr *tls_size) { #if SANITIZER_GO @@ -1057,15 +1054,16 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { return 0; // Get the UTF-16 path and convert to UTF-8. - wchar_t binname_utf16[kMaxPathLength]; + InternalMmapVector binname_utf16(kMaxPathLength); int binname_utf16_len = - GetModuleFileNameW(NULL, binname_utf16, ARRAY_SIZE(binname_utf16)); + GetModuleFileNameW(NULL, &binname_utf16[0], kMaxPathLength); if (binname_utf16_len == 0) { buf[0] = '\0'; return 0; } - int binary_name_len = ::WideCharToMultiByte( - CP_UTF8, 0, binname_utf16, binname_utf16_len, buf, buf_len, NULL, NULL); + int binary_name_len = + ::WideCharToMultiByte(CP_UTF8, 0, &binname_utf16[0], binname_utf16_len, + buf, buf_len, NULL, NULL); if ((unsigned)binary_name_len == buf_len) --binary_name_len; buf[binary_name_len] = '\0'; diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp index 590e477678ea..58f1ef404ba6 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp @@ -36,6 +36,17 @@ using namespace __sanitizer; #define SKIP_ON_SOLARIS_SPARCV9(x) x #endif +// On 64-bit systems with small virtual address spaces (e.g. 39-bit) we can't +// use size class maps with a large number of classes, as that will make the +// SizeClassAllocator64 region size too small (< 2^32). +#if SANITIZER_ANDROID && defined(__aarch64__) +#define ALLOCATOR64_SMALL_SIZE 1 +#elif SANITIZER_RISCV64 +#define ALLOCATOR64_SMALL_SIZE 1 +#else +#define ALLOCATOR64_SMALL_SIZE 0 +#endif + // Too slow for debug build #if !SANITIZER_DEBUG @@ -53,6 +64,11 @@ static const uptr kAllocatorSpace = 0x3000000000ULL; static const uptr kAllocatorSize = 0x2000000000ULL; static const u64 kAddressSpaceSize = 1ULL << 39; typedef VeryCompactSizeClassMap SizeClassMap; +#elif SANITIZER_RISCV64 +const uptr kAllocatorSpace = ~(uptr)0; +const uptr kAllocatorSize = 0x2000000000ULL; // 128G. +static const u64 kAddressSpaceSize = 1ULL << 38; +typedef VeryDenseSizeClassMap SizeClassMap; #else static const uptr kAllocatorSpace = 0x700000000000ULL; static const uptr kAllocatorSize = 0x010000000000ULL; // 1T. @@ -196,9 +212,9 @@ TEST(SanitizerCommon, DenseSizeClassMap) { } template -void TestSizeClassAllocator() { +void TestSizeClassAllocator(uptr premapped_heap = 0) { Allocator *a = new Allocator; - a->Init(kReleaseToOSIntervalNever); + a->Init(kReleaseToOSIntervalNever, premapped_heap); typename Allocator::AllocatorCache cache; memset(&cache, 0, sizeof(cache)); cache.Init(0); @@ -265,6 +281,25 @@ void TestSizeClassAllocator() { } #if SANITIZER_CAN_USE_ALLOCATOR64 + +// Allocates kAllocatorSize aligned bytes on construction and frees it on +// destruction. +class ScopedPremappedHeap { + public: + ScopedPremappedHeap() { + BasePtr = MmapNoReserveOrDie(2 * kAllocatorSize, "preallocated heap"); + AlignedAddr = RoundUpTo(reinterpret_cast(BasePtr), kAllocatorSize); + } + + ~ScopedPremappedHeap() { UnmapOrDie(BasePtr, kAllocatorSize); } + + uptr Addr() { return AlignedAddr; } + + private: + void *BasePtr; + uptr AlignedAddr; +}; + // These tests can fail on Windows if memory is somewhat full and lit happens // to run them all at the same time. FIXME: Make them not flaky and reenable. #if !SANITIZER_WINDOWS @@ -276,8 +311,14 @@ TEST(SanitizerCommon, SizeClassAllocator64Dynamic) { TestSizeClassAllocator(); } -#if !SANITIZER_ANDROID -//FIXME(kostyak): find values so that those work on Android as well. +#if !ALLOCATOR64_SMALL_SIZE +// Android only has 39-bit address space, so mapping 2 * kAllocatorSize +// sometimes fails. +TEST(SanitizerCommon, SizeClassAllocator64DynamicPremapped) { + ScopedPremappedHeap h; + TestSizeClassAllocator(h.Addr()); +} + TEST(SanitizerCommon, SizeClassAllocator64Compact) { TestSizeClassAllocator(); } @@ -320,9 +361,9 @@ TEST(SanitizerCommon, SizeClassAllocator32SeparateBatches) { } template -void SizeClassAllocatorMetadataStress() { +void SizeClassAllocatorMetadataStress(uptr premapped_heap = 0) { Allocator *a = new Allocator; - a->Init(kReleaseToOSIntervalNever); + a->Init(kReleaseToOSIntervalNever, premapped_heap); typename Allocator::AllocatorCache cache; memset(&cache, 0, sizeof(cache)); cache.Init(0); @@ -361,7 +402,12 @@ TEST(SanitizerCommon, SizeClassAllocator64DynamicMetadataStress) { SizeClassAllocatorMetadataStress(); } -#if !SANITIZER_ANDROID +#if !ALLOCATOR64_SMALL_SIZE +TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedMetadataStress) { + ScopedPremappedHeap h; + SizeClassAllocatorMetadataStress(h.Addr()); +} + TEST(SanitizerCommon, SizeClassAllocator64CompactMetadataStress) { SizeClassAllocatorMetadataStress(); } @@ -374,9 +420,10 @@ TEST(SanitizerCommon, SizeClassAllocator32CompactMetadataStress) { } template -void SizeClassAllocatorGetBlockBeginStress(u64 TotalSize) { +void SizeClassAllocatorGetBlockBeginStress(u64 TotalSize, + uptr premapped_heap = 0) { Allocator *a = new Allocator; - a->Init(kReleaseToOSIntervalNever); + a->Init(kReleaseToOSIntervalNever, premapped_heap); typename Allocator::AllocatorCache cache; memset(&cache, 0, sizeof(cache)); cache.Init(0); @@ -408,7 +455,12 @@ TEST(SanitizerCommon, SizeClassAllocator64DynamicGetBlockBegin) { SizeClassAllocatorGetBlockBeginStress( 1ULL << (SANITIZER_ANDROID ? 31 : 33)); } -#if !SANITIZER_ANDROID +#if !ALLOCATOR64_SMALL_SIZE +TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedGetBlockBegin) { + ScopedPremappedHeap h; + SizeClassAllocatorGetBlockBeginStress( + 1ULL << (SANITIZER_ANDROID ? 31 : 33), h.Addr()); +} TEST(SanitizerCommon, SizeClassAllocator64CompactGetBlockBegin) { SizeClassAllocatorGetBlockBeginStress(1ULL << 33); } @@ -520,7 +572,7 @@ TEST(SanitizerCommon, LargeMmapAllocatorMapUnmapCallback) { // Don't test OOM conditions on Win64 because it causes other tests on the same // machine to OOM. -#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID +#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 TEST(SanitizerCommon, SizeClassAllocator64Overflow) { Allocator64 a; a.Init(kReleaseToOSIntervalNever); @@ -534,7 +586,8 @@ TEST(SanitizerCommon, SizeClassAllocator64Overflow) { uint32_t chunks[kNumChunks]; bool allocation_failed = false; for (int i = 0; i < 1000000; i++) { - if (!a.GetFromAllocator(&stats, 52, chunks, kNumChunks)) { + uptr class_id = a.kNumClasses - 1; + if (!a.GetFromAllocator(&stats, class_id, chunks, kNumChunks)) { allocation_failed = true; break; } @@ -624,10 +677,10 @@ TEST(SanitizerCommon, LargeMmapAllocator) { } template -void TestCombinedAllocator() { +void TestCombinedAllocator(uptr premapped_heap = 0) { typedef CombinedAllocator Allocator; Allocator *a = new Allocator; - a->Init(kReleaseToOSIntervalNever); + a->Init(kReleaseToOSIntervalNever, premapped_heap); std::mt19937 r; typename Allocator::AllocatorCache cache; @@ -698,7 +751,15 @@ TEST(SanitizerCommon, CombinedAllocator64Dynamic) { TestCombinedAllocator(); } -#if !SANITIZER_ANDROID +#if !ALLOCATOR64_SMALL_SIZE +#if !SANITIZER_WINDOWS +// Windows fails to map 1TB, so disable this test. +TEST(SanitizerCommon, CombinedAllocator64DynamicPremapped) { + ScopedPremappedHeap h; + TestCombinedAllocator(h.Addr()); +} +#endif + TEST(SanitizerCommon, CombinedAllocator64Compact) { TestCombinedAllocator(); } @@ -714,12 +775,12 @@ TEST(SanitizerCommon, SKIP_ON_SOLARIS_SPARCV9(CombinedAllocator32Compact)) { } template -void TestSizeClassAllocatorLocalCache() { +void TestSizeClassAllocatorLocalCache(uptr premapped_heap = 0) { using AllocatorCache = typename Allocator::AllocatorCache; AllocatorCache cache; Allocator *a = new Allocator(); - a->Init(kReleaseToOSIntervalNever); + a->Init(kReleaseToOSIntervalNever, premapped_heap); memset(&cache, 0, sizeof(cache)); cache.Init(0); @@ -759,7 +820,12 @@ TEST(SanitizerCommon, SizeClassAllocator64DynamicLocalCache) { TestSizeClassAllocatorLocalCache(); } -#if !SANITIZER_ANDROID +#if !ALLOCATOR64_SMALL_SIZE +TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedLocalCache) { + ScopedPremappedHeap h; + TestSizeClassAllocatorLocalCache(h.Addr()); +} + TEST(SanitizerCommon, SizeClassAllocator64CompactLocalCache) { TestSizeClassAllocatorLocalCache(); } @@ -891,9 +957,9 @@ void IterationTestCallback(uptr chunk, void *arg) { } template -void TestSizeClassAllocatorIteration() { +void TestSizeClassAllocatorIteration(uptr premapped_heap = 0) { Allocator *a = new Allocator; - a->Init(kReleaseToOSIntervalNever); + a->Init(kReleaseToOSIntervalNever, premapped_heap); typename Allocator::AllocatorCache cache; memset(&cache, 0, sizeof(cache)); cache.Init(0); @@ -942,6 +1008,12 @@ TEST(SanitizerCommon, SizeClassAllocator64Iteration) { TEST(SanitizerCommon, SizeClassAllocator64DynamicIteration) { TestSizeClassAllocatorIteration(); } +#if !ALLOCATOR64_SMALL_SIZE +TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedIteration) { + ScopedPremappedHeap h; + TestSizeClassAllocatorIteration(h.Addr()); +} +#endif #endif #endif @@ -1016,8 +1088,8 @@ TEST(SanitizerCommon, LargeMmapAllocatorBlockBegin) { // Don't test OOM conditions on Win64 because it causes other tests on the same // machine to OOM. -#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID -typedef __sanitizer::SizeClassMap<3, 4, 8, 38, 128, 16> SpecialSizeClassMap; +#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 +typedef __sanitizer::SizeClassMap<2, 22, 22, 34, 128, 16> SpecialSizeClassMap; template struct AP64_SpecialSizeClassMap { static const uptr kSpaceBeg = kAllocatorSpace; @@ -1044,7 +1116,7 @@ TEST(SanitizerCommon, SizeClassAllocator64PopulateFreeListOOM) { // ...one man is on a mission to overflow a region with a series of // successive allocations. - const uptr kClassID = 107; + const uptr kClassID = ALLOCATOR64_SMALL_SIZE ? 18 : 24; const uptr kAllocationSize = SpecialSizeClassMap::Size(kClassID); ASSERT_LT(2 * kAllocationSize, kRegionSize); ASSERT_GT(3 * kAllocationSize, kRegionSize); @@ -1052,7 +1124,7 @@ TEST(SanitizerCommon, SizeClassAllocator64PopulateFreeListOOM) { EXPECT_NE(cache.Allocate(a, kClassID), nullptr); EXPECT_EQ(cache.Allocate(a, kClassID), nullptr); - const uptr Class2 = 100; + const uptr Class2 = ALLOCATOR64_SMALL_SIZE ? 15 : 21; const uptr Size2 = SpecialSizeClassMap::Size(Class2); ASSERT_EQ(Size2 * 8, kRegionSize); char *p[7]; @@ -1338,7 +1410,7 @@ TEST(SanitizerCommon, SizeClassAllocator64ReleaseFreeMemoryToOS) { TestReleaseFreeMemoryToOS(); } -#if !SANITIZER_ANDROID +#if !ALLOCATOR64_SMALL_SIZE TEST(SanitizerCommon, SizeClassAllocator64CompactReleaseFreeMemoryToOS) { TestReleaseFreeMemoryToOS(); } @@ -1346,7 +1418,7 @@ TEST(SanitizerCommon, SizeClassAllocator64CompactReleaseFreeMemoryToOS) { TEST(SanitizerCommon, SizeClassAllocator64VeryCompactReleaseFreeMemoryToOS) { TestReleaseFreeMemoryToOS(); } -#endif // !SANITIZER_ANDROID +#endif // !ALLOCATOR64_SMALL_SIZE #endif // SANITIZER_CAN_USE_ALLOCATOR64 diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp index fcf8b14aeba5..21c6b036b956 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp @@ -210,12 +210,10 @@ static void *WorkerThread(void *arg) { } TEST(SanitizerCommon, ThreadStackTlsMain) { - InitTlsSize(); TestThreadInfo(true); } TEST(SanitizerCommon, ThreadStackTlsWorker) { - InitTlsSize(); pthread_t t; PTHREAD_CREATE(&t, 0, WorkerThread, 0); PTHREAD_JOIN(t, 0); @@ -350,7 +348,7 @@ TEST(SanitizerCommon, RemoveANSIEscapeSequencesFromString) { } TEST(SanitizerCommon, InternalScopedString) { - InternalScopedString str(10); + InternalScopedString str; EXPECT_EQ(0U, str.length()); EXPECT_STREQ("", str.data()); @@ -364,20 +362,37 @@ TEST(SanitizerCommon, InternalScopedString) { EXPECT_STREQ("foo1234", str.data()); str.append("%d", x); - EXPECT_EQ(9U, str.length()); - EXPECT_STREQ("foo123412", str.data()); + EXPECT_EQ(11U, str.length()); + EXPECT_STREQ("foo12341234", str.data()); str.clear(); EXPECT_EQ(0U, str.length()); EXPECT_STREQ("", str.data()); +} - str.append("0123456789"); - EXPECT_EQ(9U, str.length()); - EXPECT_STREQ("012345678", str.data()); +TEST(SanitizerCommon, InternalScopedStringLarge) { + InternalScopedString str; + std::string expected; + for (int i = 0; i < 1000; ++i) { + std::string append(i, 'a' + i % 26); + expected += append; + str.append(append.c_str()); + EXPECT_EQ(expected, str.data()); + } +} + +TEST(SanitizerCommon, InternalScopedStringLargeFormat) { + InternalScopedString str; + std::string expected; + for (int i = 0; i < 1000; ++i) { + std::string append(i, 'a' + i % 26); + expected += append; + str.append("%s", append.c_str()); + EXPECT_EQ(expected, str.data()); + } } -#if SANITIZER_LINUX || SANITIZER_FREEBSD || \ - SANITIZER_MAC || SANITIZER_IOS +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_IOS TEST(SanitizerCommon, GetRandom) { u8 buffer_1[32], buffer_2[32]; for (bool blocking : { false, true }) { diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp index cb6c0724ac88..025cba922d2d 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp @@ -188,24 +188,9 @@ TEST(SanitizerCommon, SetEnvTest) { } #if (defined(__x86_64__) || defined(__i386__)) && !SANITIZER_ANDROID -void *thread_self_offset_test_func(void *arg) { - bool result = - *(uptr *)((char *)ThreadSelf() + ThreadSelfOffset()) == ThreadSelf(); - return (void *)result; -} - -TEST(SanitizerLinux, ThreadSelfOffset) { - EXPECT_TRUE((bool)thread_self_offset_test_func(0)); - pthread_t tid; - void *result; - ASSERT_EQ(0, pthread_create(&tid, 0, thread_self_offset_test_func, 0)); - ASSERT_EQ(0, pthread_join(tid, &result)); - EXPECT_TRUE((bool)result); -} - // libpthread puts the thread descriptor at the end of stack space. void *thread_descriptor_size_test_func(void *arg) { - uptr descr_addr = ThreadSelf(); + uptr descr_addr = (uptr)pthread_self(); pthread_attr_t attr; pthread_getattr_np(pthread_self(), &attr); void *stackaddr; diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp index a98e47ab6c53..4b379ba3d592 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp @@ -16,7 +16,7 @@ namespace __sanitizer { TEST(SanitizerStacktracePrinter, RenderSourceLocation) { - InternalScopedString str(128); + InternalScopedString str; RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, ""); EXPECT_STREQ("/dir/file.cc:10:5", str.data()); @@ -50,7 +50,7 @@ TEST(SanitizerStacktracePrinter, RenderSourceLocation) { } TEST(SanitizerStacktracePrinter, RenderModuleLocation) { - InternalScopedString str(128); + InternalScopedString str; RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, ""); EXPECT_STREQ("(/dir/exe+0x123)", str.data()); @@ -76,7 +76,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) { info.file = internal_strdup("/path/to/my/source"); info.line = 10; info.column = 5; - InternalScopedString str(256); + InternalScopedString str; // Dump all the AddressInfo fields. RenderFrame(&str, diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp index af19da0c5b6c..58f92fcf9eea 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp @@ -175,4 +175,11 @@ TEST(SlowUnwindTest, ShortStackTrace) { EXPECT_EQ(bp, stack.top_frame_bp); } +// Dummy implementation. This should never be called, but is required to link +// non-optimized builds of this test. +void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, + bool request_fast, u32 max_depth) { + UNIMPLEMENTED(); +} + } // namespace __sanitizer diff --git a/compiler-rt/lib/scudo/standalone/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/CMakeLists.txt index ef19c96e0e25..1dbe8c76ff68 100644 --- a/compiler-rt/lib/scudo/standalone/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/CMakeLists.txt @@ -10,15 +10,16 @@ set(SCUDO_CFLAGS) list(APPEND SCUDO_CFLAGS -Werror=conversion -Wall + -g -nostdinc++) # Remove -stdlib= which is unused when passing -nostdinc++. string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) -append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding SCUDO_CFLAGS) - append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SCUDO_CFLAGS) +append_list_if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions SCUDO_CFLAGS) + append_list_if(COMPILER_RT_HAS_WNO_PEDANTIC -Wno-pedantic SCUDO_CFLAGS) # FIXME: find cleaner way to agree with GWPAsan flags @@ -41,7 +42,10 @@ set(SCUDO_LINK_FLAGS) list(APPEND SCUDO_LINK_FLAGS -Wl,-z,defs,-z,now,-z,relro) -append_list_if(COMPILER_RT_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs SCUDO_LINK_FLAGS) +list(APPEND SCUDO_LINK_FLAGS -ffunction-sections -fdata-sections -Wl,--gc-sections) + +# We don't use the C++ standard library, so avoid including it by mistake. +append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ SCUDO_LINK_FLAGS) if(ANDROID) list(APPEND SCUDO_CFLAGS -fno-emulated-tls) @@ -58,13 +62,14 @@ set(SCUDO_HEADERS checksum.h chunk.h combined.h - flags.h flags_parser.h + flags.h fuchsia.h internal_defs.h linux.h list.h local_cache.h + memtag.h mutex.h platform.h primary32.h @@ -76,9 +81,9 @@ set(SCUDO_HEADERS size_class_map.h stats.h string_utils.h - tsd.h tsd_exclusive.h tsd_shared.h + tsd.h vector.h wrappers_c_checks.h wrappers_c.h @@ -88,10 +93,10 @@ set(SCUDO_HEADERS set(SCUDO_SOURCES checksum.cpp - crc32_hw.cpp common.cpp - flags.cpp + crc32_hw.cpp flags_parser.cpp + flags.cpp fuchsia.cpp linux.cpp release.cpp @@ -126,6 +131,12 @@ if (COMPILER_RT_HAS_GWP_ASAN) list(APPEND SCUDO_CFLAGS -DGWP_ASAN_HOOKS) endif() +set(SCUDO_LINK_LIBS) + +append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SCUDO_LINK_FLAGS) + +append_list_if(FUCHSIA zircon SCUDO_LINK_LIBS) + if(COMPILER_RT_HAS_SCUDO_STANDALONE) add_compiler_rt_object_libraries(RTScudoStandalone ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH} @@ -160,6 +171,17 @@ if(COMPILER_RT_HAS_SCUDO_STANDALONE) OBJECT_LIBS ${SCUDO_OBJECT_LIBS} PARENT_TARGET scudo_standalone) + add_compiler_rt_runtime(clang_rt.scudo_standalone + SHARED + ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH} + SOURCES ${SCUDO_SOURCES} ${SCUDO_SOURCES_C_WRAPPERS} ${SCUDO_SOURCES_CXX_WRAPPERS} + ADDITIONAL_HEADERS ${SCUDO_HEADERS} + CFLAGS ${SCUDO_CFLAGS} + OBJECT_LIBS ${SCUDO_OBJECT_LIBS} + LINK_FLAGS ${SCUDO_LINK_FLAGS} + LINK_LIBS ${SCUDO_LINK_LIBS} + PARENT_TARGET scudo_standalone) + add_subdirectory(benchmarks) if(COMPILER_RT_INCLUDE_TESTS) add_subdirectory(tests) diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 3b112d8ed1f2..7cd3867435b0 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -447,7 +447,7 @@ class Allocator { computeOddEvenMaskForPointerMaybe(Options, BlockUptr, BlockSize); TaggedPtr = prepareTaggedChunk(Ptr, Size, OddEvenMask, BlockEnd); } - storeAllocationStackMaybe(Options, Ptr); + storePrimaryAllocationStackMaybe(Options, Ptr); } else { Block = addHeaderTag(Block); Ptr = addHeaderTag(Ptr); @@ -461,8 +461,10 @@ class Allocator { } else { Block = addHeaderTag(Block); Ptr = addHeaderTag(Ptr); - if (UNLIKELY(useMemoryTagging(Options))) + if (UNLIKELY(useMemoryTagging(Options))) { storeTags(reinterpret_cast(Block), reinterpret_cast(Ptr)); + storeSecondaryAllocationStackMaybe(Options, Ptr, Size); + } } Chunk::UnpackedHeader Header = {}; @@ -616,11 +618,15 @@ class Allocator { (reinterpret_cast(OldTaggedPtr) + NewSize)) & Chunk::SizeOrUnusedBytesMask; Chunk::compareExchangeHeader(Cookie, OldPtr, &NewHeader, &OldHeader); - if (UNLIKELY(ClassId && useMemoryTagging(Options))) { - resizeTaggedChunk(reinterpret_cast(OldTaggedPtr) + OldSize, - reinterpret_cast(OldTaggedPtr) + NewSize, - BlockEnd); - storeAllocationStackMaybe(Options, OldPtr); + if (UNLIKELY(useMemoryTagging(Options))) { + if (ClassId) { + resizeTaggedChunk(reinterpret_cast(OldTaggedPtr) + OldSize, + reinterpret_cast(OldTaggedPtr) + NewSize, + BlockEnd); + storePrimaryAllocationStackMaybe(Options, OldPtr); + } else { + storeSecondaryAllocationStackMaybe(Options, OldPtr, NewSize); + } } return OldTaggedPtr; } @@ -871,116 +877,41 @@ class Allocator { return PrimaryT::getRegionInfoArraySize(); } + const char *getRingBufferAddress() const { + return reinterpret_cast(&RingBuffer); + } + + static uptr getRingBufferSize() { return sizeof(RingBuffer); } + + static const uptr MaxTraceSize = 64; + + static void collectTraceMaybe(const StackDepot *Depot, + uintptr_t (&Trace)[MaxTraceSize], u32 Hash) { + uptr RingPos, Size; + if (!Depot->find(Hash, &RingPos, &Size)) + return; + for (unsigned I = 0; I != Size && I != MaxTraceSize; ++I) + Trace[I] = (*Depot)[RingPos + I]; + } + static void getErrorInfo(struct scudo_error_info *ErrorInfo, uintptr_t FaultAddr, const char *DepotPtr, - const char *RegionInfoPtr, const char *Memory, - const char *MemoryTags, uintptr_t MemoryAddr, - size_t MemorySize) { + const char *RegionInfoPtr, const char *RingBufferPtr, + const char *Memory, const char *MemoryTags, + uintptr_t MemoryAddr, size_t MemorySize) { *ErrorInfo = {}; if (!allocatorSupportsMemoryTagging() || MemoryAddr + MemorySize < MemoryAddr) return; - uptr UntaggedFaultAddr = untagPointer(FaultAddr); - u8 FaultAddrTag = extractTag(FaultAddr); - BlockInfo Info = - PrimaryT::findNearestBlock(RegionInfoPtr, UntaggedFaultAddr); - - auto GetGranule = [&](uptr Addr, const char **Data, uint8_t *Tag) -> bool { - if (Addr < MemoryAddr || Addr + archMemoryTagGranuleSize() < Addr || - Addr + archMemoryTagGranuleSize() > MemoryAddr + MemorySize) - return false; - *Data = &Memory[Addr - MemoryAddr]; - *Tag = static_cast( - MemoryTags[(Addr - MemoryAddr) / archMemoryTagGranuleSize()]); - return true; - }; - - auto ReadBlock = [&](uptr Addr, uptr *ChunkAddr, - Chunk::UnpackedHeader *Header, const u32 **Data, - u8 *Tag) { - const char *BlockBegin; - u8 BlockBeginTag; - if (!GetGranule(Addr, &BlockBegin, &BlockBeginTag)) - return false; - uptr ChunkOffset = getChunkOffsetFromBlock(BlockBegin); - *ChunkAddr = Addr + ChunkOffset; - - const char *ChunkBegin; - if (!GetGranule(*ChunkAddr, &ChunkBegin, Tag)) - return false; - *Header = *reinterpret_cast( - ChunkBegin - Chunk::getHeaderSize()); - *Data = reinterpret_cast(ChunkBegin); - return true; - }; - auto *Depot = reinterpret_cast(DepotPtr); - - auto MaybeCollectTrace = [&](uintptr_t(&Trace)[MaxTraceSize], u32 Hash) { - uptr RingPos, Size; - if (!Depot->find(Hash, &RingPos, &Size)) - return; - for (unsigned I = 0; I != Size && I != MaxTraceSize; ++I) - Trace[I] = (*Depot)[RingPos + I]; - }; - size_t NextErrorReport = 0; - - // First, check for UAF. - { - uptr ChunkAddr; - Chunk::UnpackedHeader Header; - const u32 *Data; - uint8_t Tag; - if (ReadBlock(Info.BlockBegin, &ChunkAddr, &Header, &Data, &Tag) && - Header.State != Chunk::State::Allocated && - Data[MemTagPrevTagIndex] == FaultAddrTag) { - auto *R = &ErrorInfo->reports[NextErrorReport++]; - R->error_type = USE_AFTER_FREE; - R->allocation_address = ChunkAddr; - R->allocation_size = Header.SizeOrUnusedBytes; - MaybeCollectTrace(R->allocation_trace, - Data[MemTagAllocationTraceIndex]); - R->allocation_tid = Data[MemTagAllocationTidIndex]; - MaybeCollectTrace(R->deallocation_trace, - Data[MemTagDeallocationTraceIndex]); - R->deallocation_tid = Data[MemTagDeallocationTidIndex]; - } - } - - auto CheckOOB = [&](uptr BlockAddr) { - if (BlockAddr < Info.RegionBegin || BlockAddr >= Info.RegionEnd) - return false; - - uptr ChunkAddr; - Chunk::UnpackedHeader Header; - const u32 *Data; - uint8_t Tag; - if (!ReadBlock(BlockAddr, &ChunkAddr, &Header, &Data, &Tag) || - Header.State != Chunk::State::Allocated || Tag != FaultAddrTag) - return false; - - auto *R = &ErrorInfo->reports[NextErrorReport++]; - R->error_type = - UntaggedFaultAddr < ChunkAddr ? BUFFER_UNDERFLOW : BUFFER_OVERFLOW; - R->allocation_address = ChunkAddr; - R->allocation_size = Header.SizeOrUnusedBytes; - MaybeCollectTrace(R->allocation_trace, Data[MemTagAllocationTraceIndex]); - R->allocation_tid = Data[MemTagAllocationTidIndex]; - return NextErrorReport == - sizeof(ErrorInfo->reports) / sizeof(ErrorInfo->reports[0]); - }; - - if (CheckOOB(Info.BlockBegin)) - return; - - // Check for OOB in the 30 surrounding blocks. Beyond that we are likely to - // hit false positives. - for (int I = 1; I != 16; ++I) - if (CheckOOB(Info.BlockBegin + I * Info.BlockSize) || - CheckOOB(Info.BlockBegin - I * Info.BlockSize)) - return; + if (extractTag(FaultAddr) != 0) + getInlineErrorInfo(ErrorInfo, NextErrorReport, FaultAddr, Depot, + RegionInfoPtr, Memory, MemoryTags, MemoryAddr, + MemorySize); + getRingBufferErrorInfo(ErrorInfo, NextErrorReport, FaultAddr, Depot, + RingBufferPtr); } private: @@ -1004,23 +935,13 @@ class Allocator { // These are indexes into an "array" of 32-bit values that store information // inline with a chunk that is relevant to diagnosing memory tag faults, where - // 0 corresponds to the address of the user memory. This means that negative - // indexes may be used to store information about allocations, while positive - // indexes may only be used to store information about deallocations, because - // the user memory is in use until it has been deallocated. The smallest index - // that may be used is -2, which corresponds to 8 bytes before the user - // memory, because the chunk header size is 8 bytes and in allocators that - // support memory tagging the minimum alignment is at least the tag granule - // size (16 on aarch64), and the largest index that may be used is 3 because - // we are only guaranteed to have at least a granule's worth of space in the - // user memory. + // 0 corresponds to the address of the user memory. This means that only + // negative indexes may be used. The smallest index that may be used is -2, + // which corresponds to 8 bytes before the user memory, because the chunk + // header size is 8 bytes and in allocators that support memory tagging the + // minimum alignment is at least the tag granule size (16 on aarch64). static const sptr MemTagAllocationTraceIndex = -2; static const sptr MemTagAllocationTidIndex = -1; - static const sptr MemTagDeallocationTraceIndex = 0; - static const sptr MemTagDeallocationTidIndex = 1; - static const sptr MemTagPrevTagIndex = 2; - - static const uptr MaxTraceSize = 64; u32 Cookie; u32 QuarantineMaxChunkSize; @@ -1037,6 +958,26 @@ class Allocator { StackDepot Depot; + struct AllocationRingBuffer { + struct Entry { + atomic_uptr Ptr; + atomic_uptr AllocationSize; + atomic_u32 AllocationTrace; + atomic_u32 AllocationTid; + atomic_u32 DeallocationTrace; + atomic_u32 DeallocationTid; + }; + + atomic_uptr Pos; +#ifdef SCUDO_FUZZ + static const uptr NumEntries = 2; +#else + static const uptr NumEntries = 32768; +#endif + Entry Entries[NumEntries]; + }; + AllocationRingBuffer RingBuffer; + // The following might get optimized out by the compiler. NOINLINE void performSanityChecks() { // Verify that the header offset field can hold the maximum offset. In the @@ -1093,20 +1034,23 @@ class Allocator { void quarantineOrDeallocateChunk(Options Options, void *Ptr, Chunk::UnpackedHeader *Header, uptr Size) { Chunk::UnpackedHeader NewHeader = *Header; - if (UNLIKELY(NewHeader.ClassId && useMemoryTagging(Options))) { - u8 PrevTag = extractTag(loadTag(reinterpret_cast(Ptr))); - if (!TSDRegistry.getDisableMemInit()) { - uptr TaggedBegin, TaggedEnd; - const uptr OddEvenMask = computeOddEvenMaskForPointerMaybe( - Options, reinterpret_cast(getBlockBegin(Ptr, &NewHeader)), - SizeClassMap::getSizeByClassId(NewHeader.ClassId)); - // Exclude the previous tag so that immediate use after free is detected - // 100% of the time. - setRandomTag(Ptr, Size, OddEvenMask | (1UL << PrevTag), &TaggedBegin, - &TaggedEnd); + if (UNLIKELY(useMemoryTagging(Options))) { + u8 PrevTag = 0; + if (NewHeader.ClassId) { + PrevTag = extractTag(loadTag(reinterpret_cast(Ptr))); + if (!TSDRegistry.getDisableMemInit()) { + uptr TaggedBegin, TaggedEnd; + const uptr OddEvenMask = computeOddEvenMaskForPointerMaybe( + Options, reinterpret_cast(getBlockBegin(Ptr, &NewHeader)), + SizeClassMap::getSizeByClassId(NewHeader.ClassId)); + // Exclude the previous tag so that immediate use after free is + // detected 100% of the time. + setRandomTag(Ptr, Size, OddEvenMask | (1UL << PrevTag), &TaggedBegin, + &TaggedEnd); + } + NewHeader.OriginOrWasZeroed = !TSDRegistry.getDisableMemInit(); } - NewHeader.OriginOrWasZeroed = !TSDRegistry.getDisableMemInit(); - storeDeallocationStackMaybe(Options, Ptr, PrevTag); + storeDeallocationStackMaybe(Options, Ptr, PrevTag, Size); } // If the quarantine is disabled, the actual size of a chunk is 0 or larger // than the maximum allowed, we return a chunk directly to the backend. @@ -1159,7 +1103,7 @@ class Allocator { return Offset + Chunk::getHeaderSize(); } - void storeAllocationStackMaybe(Options Options, void *Ptr) { + void storePrimaryAllocationStackMaybe(Options Options, void *Ptr) { if (!UNLIKELY(Options.get(OptionBit::TrackAllocationStacks))) return; auto *Ptr32 = reinterpret_cast(Ptr); @@ -1167,18 +1111,199 @@ class Allocator { Ptr32[MemTagAllocationTidIndex] = getThreadID(); } - void storeDeallocationStackMaybe(Options Options, void *Ptr, - uint8_t PrevTag) { + void storeRingBufferEntry(void *Ptr, u32 AllocationTrace, u32 AllocationTid, + uptr AllocationSize, u32 DeallocationTrace, + u32 DeallocationTid) { + uptr Pos = atomic_fetch_add(&RingBuffer.Pos, 1, memory_order_relaxed); + typename AllocationRingBuffer::Entry *Entry = + &RingBuffer.Entries[Pos % AllocationRingBuffer::NumEntries]; + + // First invalidate our entry so that we don't attempt to interpret a + // partially written state in getSecondaryErrorInfo(). The fences below + // ensure that the compiler does not move the stores to Ptr in between the + // stores to the other fields. + atomic_store_relaxed(&Entry->Ptr, 0); + + __atomic_signal_fence(__ATOMIC_SEQ_CST); + atomic_store_relaxed(&Entry->AllocationTrace, AllocationTrace); + atomic_store_relaxed(&Entry->AllocationTid, AllocationTid); + atomic_store_relaxed(&Entry->AllocationSize, AllocationSize); + atomic_store_relaxed(&Entry->DeallocationTrace, DeallocationTrace); + atomic_store_relaxed(&Entry->DeallocationTid, DeallocationTid); + __atomic_signal_fence(__ATOMIC_SEQ_CST); + + atomic_store_relaxed(&Entry->Ptr, reinterpret_cast(Ptr)); + } + + void storeSecondaryAllocationStackMaybe(Options Options, void *Ptr, + uptr Size) { if (!UNLIKELY(Options.get(OptionBit::TrackAllocationStacks))) return; - // Disable tag checks here so that we don't need to worry about zero sized - // allocations. - ScopedDisableMemoryTagChecks x; + u32 Trace = collectStackTrace(); + u32 Tid = getThreadID(); + auto *Ptr32 = reinterpret_cast(Ptr); - Ptr32[MemTagDeallocationTraceIndex] = collectStackTrace(); - Ptr32[MemTagDeallocationTidIndex] = getThreadID(); - Ptr32[MemTagPrevTagIndex] = PrevTag; + Ptr32[MemTagAllocationTraceIndex] = Trace; + Ptr32[MemTagAllocationTidIndex] = Tid; + + storeRingBufferEntry(untagPointer(Ptr), Trace, Tid, Size, 0, 0); + } + + void storeDeallocationStackMaybe(Options Options, void *Ptr, u8 PrevTag, + uptr Size) { + if (!UNLIKELY(Options.get(OptionBit::TrackAllocationStacks))) + return; + + auto *Ptr32 = reinterpret_cast(Ptr); + u32 AllocationTrace = Ptr32[MemTagAllocationTraceIndex]; + u32 AllocationTid = Ptr32[MemTagAllocationTidIndex]; + + u32 DeallocationTrace = collectStackTrace(); + u32 DeallocationTid = getThreadID(); + + storeRingBufferEntry(addFixedTag(untagPointer(Ptr), PrevTag), + AllocationTrace, AllocationTid, Size, + DeallocationTrace, DeallocationTid); + } + + static const size_t NumErrorReports = + sizeof(((scudo_error_info *)0)->reports) / + sizeof(((scudo_error_info *)0)->reports[0]); + + static void getInlineErrorInfo(struct scudo_error_info *ErrorInfo, + size_t &NextErrorReport, uintptr_t FaultAddr, + const StackDepot *Depot, + const char *RegionInfoPtr, const char *Memory, + const char *MemoryTags, uintptr_t MemoryAddr, + size_t MemorySize) { + uptr UntaggedFaultAddr = untagPointer(FaultAddr); + u8 FaultAddrTag = extractTag(FaultAddr); + BlockInfo Info = + PrimaryT::findNearestBlock(RegionInfoPtr, UntaggedFaultAddr); + + auto GetGranule = [&](uptr Addr, const char **Data, uint8_t *Tag) -> bool { + if (Addr < MemoryAddr || Addr + archMemoryTagGranuleSize() < Addr || + Addr + archMemoryTagGranuleSize() > MemoryAddr + MemorySize) + return false; + *Data = &Memory[Addr - MemoryAddr]; + *Tag = static_cast( + MemoryTags[(Addr - MemoryAddr) / archMemoryTagGranuleSize()]); + return true; + }; + + auto ReadBlock = [&](uptr Addr, uptr *ChunkAddr, + Chunk::UnpackedHeader *Header, const u32 **Data, + u8 *Tag) { + const char *BlockBegin; + u8 BlockBeginTag; + if (!GetGranule(Addr, &BlockBegin, &BlockBeginTag)) + return false; + uptr ChunkOffset = getChunkOffsetFromBlock(BlockBegin); + *ChunkAddr = Addr + ChunkOffset; + + const char *ChunkBegin; + if (!GetGranule(*ChunkAddr, &ChunkBegin, Tag)) + return false; + *Header = *reinterpret_cast( + ChunkBegin - Chunk::getHeaderSize()); + *Data = reinterpret_cast(ChunkBegin); + return true; + }; + + if (NextErrorReport == NumErrorReports) + return; + + auto CheckOOB = [&](uptr BlockAddr) { + if (BlockAddr < Info.RegionBegin || BlockAddr >= Info.RegionEnd) + return false; + + uptr ChunkAddr; + Chunk::UnpackedHeader Header; + const u32 *Data; + uint8_t Tag; + if (!ReadBlock(BlockAddr, &ChunkAddr, &Header, &Data, &Tag) || + Header.State != Chunk::State::Allocated || Tag != FaultAddrTag) + return false; + + auto *R = &ErrorInfo->reports[NextErrorReport++]; + R->error_type = + UntaggedFaultAddr < ChunkAddr ? BUFFER_UNDERFLOW : BUFFER_OVERFLOW; + R->allocation_address = ChunkAddr; + R->allocation_size = Header.SizeOrUnusedBytes; + collectTraceMaybe(Depot, R->allocation_trace, + Data[MemTagAllocationTraceIndex]); + R->allocation_tid = Data[MemTagAllocationTidIndex]; + return NextErrorReport == NumErrorReports; + }; + + if (CheckOOB(Info.BlockBegin)) + return; + + // Check for OOB in the 30 surrounding blocks. Beyond that we are likely to + // hit false positives. + for (int I = 1; I != 16; ++I) + if (CheckOOB(Info.BlockBegin + I * Info.BlockSize) || + CheckOOB(Info.BlockBegin - I * Info.BlockSize)) + return; + } + + static void getRingBufferErrorInfo(struct scudo_error_info *ErrorInfo, + size_t &NextErrorReport, + uintptr_t FaultAddr, + const StackDepot *Depot, + const char *RingBufferPtr) { + auto *RingBuffer = + reinterpret_cast(RingBufferPtr); + uptr Pos = atomic_load_relaxed(&RingBuffer->Pos); + + for (uptr I = Pos - 1; I != Pos - 1 - AllocationRingBuffer::NumEntries && + NextErrorReport != NumErrorReports; + --I) { + auto *Entry = &RingBuffer->Entries[I % AllocationRingBuffer::NumEntries]; + uptr EntryPtr = atomic_load_relaxed(&Entry->Ptr); + uptr UntaggedEntryPtr = untagPointer(EntryPtr); + uptr EntrySize = atomic_load_relaxed(&Entry->AllocationSize); + if (!EntryPtr || FaultAddr < EntryPtr - getPageSizeCached() || + FaultAddr >= EntryPtr + EntrySize + getPageSizeCached()) + continue; + + u32 AllocationTrace = atomic_load_relaxed(&Entry->AllocationTrace); + u32 AllocationTid = atomic_load_relaxed(&Entry->AllocationTid); + u32 DeallocationTrace = atomic_load_relaxed(&Entry->DeallocationTrace); + u32 DeallocationTid = atomic_load_relaxed(&Entry->DeallocationTid); + + // For UAF the ring buffer will contain two entries, one for the + // allocation and another for the deallocation. Don't report buffer + // overflow/underflow using the allocation entry if we have already + // collected a report from the deallocation entry. + if (!DeallocationTrace) { + bool Found = false; + for (uptr J = 0; J != NextErrorReport; ++J) { + if (ErrorInfo->reports[J].allocation_address == UntaggedEntryPtr) { + Found = true; + break; + } + } + if (Found) + continue; + } + + auto *R = &ErrorInfo->reports[NextErrorReport++]; + if (DeallocationTid) + R->error_type = USE_AFTER_FREE; + else if (FaultAddr < EntryPtr) + R->error_type = BUFFER_UNDERFLOW; + else + R->error_type = BUFFER_OVERFLOW; + + R->allocation_address = UntaggedEntryPtr; + R->allocation_size = EntrySize; + collectTraceMaybe(Depot, R->allocation_trace, AllocationTrace); + R->allocation_tid = AllocationTid; + collectTraceMaybe(Depot, R->deallocation_trace, DeallocationTrace); + R->deallocation_tid = DeallocationTid; + } } uptr getStats(ScopedString *Str) { diff --git a/compiler-rt/lib/scudo/standalone/fuzz/get_error_info_fuzzer.cpp b/compiler-rt/lib/scudo/standalone/fuzz/get_error_info_fuzzer.cpp index f20a8a84a010..078e44b0dfc8 100644 --- a/compiler-rt/lib/scudo/standalone/fuzz/get_error_info_fuzzer.cpp +++ b/compiler-rt/lib/scudo/standalone/fuzz/get_error_info_fuzzer.cpp @@ -37,16 +37,24 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t *Data, size_t Size) { StackDepot[i] = StackDepotBytes[i]; } - std::string RegionInfoBytes = FDP.ConsumeRemainingBytesAsString(); + std::string RegionInfoBytes = + FDP.ConsumeRandomLengthString(FDP.remaining_bytes()); std::vector RegionInfo(AllocatorT::getRegionInfoArraySize(), 0); for (size_t i = 0; i < RegionInfoBytes.length() && i < RegionInfo.size(); ++i) { RegionInfo[i] = RegionInfoBytes[i]; } + std::string RingBufferBytes = FDP.ConsumeRemainingBytesAsString(); + std::vector RingBuffer(AllocatorT::getRingBufferSize(), 0); + for (size_t i = 0; i < RingBufferBytes.length() && i < RingBuffer.size(); + ++i) { + RingBuffer[i] = RingBufferBytes[i]; + } + scudo_error_info ErrorInfo; AllocatorT::getErrorInfo(&ErrorInfo, FaultAddr, StackDepot.data(), - RegionInfo.data(), Memory, MemoryTags, MemoryAddr, - MemorySize); + RegionInfo.data(), RingBuffer.data(), Memory, + MemoryTags, MemoryAddr, MemorySize); return 0; } diff --git a/compiler-rt/lib/scudo/standalone/include/scudo/interface.h b/compiler-rt/lib/scudo/standalone/include/scudo/interface.h index 68029e4857a3..0e6cf3d4e254 100644 --- a/compiler-rt/lib/scudo/standalone/include/scudo/interface.h +++ b/compiler-rt/lib/scudo/standalone/include/scudo/interface.h @@ -73,9 +73,9 @@ typedef void (*iterate_callback)(uintptr_t base, size_t size, void *arg); // pointer. void __scudo_get_error_info(struct scudo_error_info *error_info, uintptr_t fault_addr, const char *stack_depot, - const char *region_info, const char *memory, - const char *memory_tags, uintptr_t memory_addr, - size_t memory_size); + const char *region_info, const char *ring_buffer, + const char *memory, const char *memory_tags, + uintptr_t memory_addr, size_t memory_size); enum scudo_error_type { UNKNOWN, @@ -107,6 +107,9 @@ size_t __scudo_get_stack_depot_size(); const char *__scudo_get_region_info_addr(); size_t __scudo_get_region_info_size(); +const char *__scudo_get_ring_buffer_addr(); +size_t __scudo_get_ring_buffer_size(); + #ifndef M_DECAY_TIME #define M_DECAY_TIME -100 #endif diff --git a/compiler-rt/lib/scudo/standalone/memtag.h b/compiler-rt/lib/scudo/standalone/memtag.h index c8f9281100c9..0a8a0b52173a 100644 --- a/compiler-rt/lib/scudo/standalone/memtag.h +++ b/compiler-rt/lib/scudo/standalone/memtag.h @@ -26,7 +26,7 @@ void setRandomTag(void *Ptr, uptr Size, uptr ExcludeMask, uptr *TaggedBegin, // We assume that Top-Byte Ignore is enabled if the architecture supports memory // tagging. Not all operating systems enable TBI, so we only claim architectural // support for memory tagging if the operating system enables TBI. -#if SCUDO_LINUX +#if SCUDO_LINUX && !defined(SCUDO_DISABLE_TBI) inline constexpr bool archSupportsMemoryTagging() { return true; } #else inline constexpr bool archSupportsMemoryTagging() { return false; } @@ -300,6 +300,15 @@ inline void *untagPointer(void *Ptr) { return reinterpret_cast(untagPointer(reinterpret_cast(Ptr))); } +inline void *loadTag(void *Ptr) { + return reinterpret_cast(loadTag(reinterpret_cast(Ptr))); +} + +inline void *addFixedTag(void *Ptr, uptr Tag) { + return reinterpret_cast( + addFixedTag(reinterpret_cast(Ptr), Tag)); +} + template inline constexpr bool allocatorSupportsMemoryTagging() { return archSupportsMemoryTagging() && Config::MaySupportMemoryTagging; diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h index 366e0b1faea0..da96eb0ea56b 100644 --- a/compiler-rt/lib/scudo/standalone/secondary.h +++ b/compiler-rt/lib/scudo/standalone/secondary.h @@ -86,6 +86,25 @@ class MapAllocatorNoCache { static const uptr MaxUnusedCachePages = 4U; +template +void mapSecondary(Options Options, uptr CommitBase, uptr CommitSize, + uptr AllocPos, uptr Flags, MapPlatformData *Data) { + const uptr MaxUnusedCacheBytes = MaxUnusedCachePages * getPageSizeCached(); + if (useMemoryTagging(Options) && CommitSize > MaxUnusedCacheBytes) { + const uptr UntaggedPos = Max(AllocPos, CommitBase + MaxUnusedCacheBytes); + map(reinterpret_cast(CommitBase), UntaggedPos - CommitBase, + "scudo:secondary", MAP_RESIZABLE | MAP_MEMTAG | Flags, Data); + map(reinterpret_cast(UntaggedPos), + CommitBase + CommitSize - UntaggedPos, "scudo:secondary", + MAP_RESIZABLE | Flags, Data); + } else { + map(reinterpret_cast(CommitBase), CommitSize, "scudo:secondary", + MAP_RESIZABLE | (useMemoryTagging(Options) ? MAP_MEMTAG : 0) | + Flags, + Data); + } +} + template class MapAllocatorCache { public: // Ensure the default maximum specified fits the array. @@ -129,9 +148,8 @@ template class MapAllocatorCache { // Fuchsia does not support replacing mappings by creating a new mapping // on top so we just do the two syscalls there. Entry.Time = 0; - map(reinterpret_cast(Entry.CommitBase), Entry.CommitSize, - "scudo:secondary", MAP_RESIZABLE | MAP_NOACCESS | MAP_MEMTAG, - &Entry.Data); + mapSecondary(Options, Entry.CommitBase, Entry.CommitSize, + Entry.CommitBase, MAP_NOACCESS, &Entry.Data); } else { setMemoryPermission(Entry.CommitBase, Entry.CommitSize, MAP_NOACCESS, &Entry.Data); @@ -530,19 +548,7 @@ void *MapAllocator::allocate(Options Options, uptr Size, uptr Alignment, const uptr CommitSize = MapEnd - PageSize - CommitBase; const uptr AllocPos = roundDownTo(CommitBase + CommitSize - Size, Alignment); - const uptr MaxUnusedCacheBytes = MaxUnusedCachePages * getPageSizeCached(); - if (useMemoryTagging(Options) && CommitSize > MaxUnusedCacheBytes) { - const uptr UntaggedPos = Max(AllocPos, CommitBase + MaxUnusedCacheBytes); - map(reinterpret_cast(CommitBase), UntaggedPos - CommitBase, - "scudo:secondary", MAP_RESIZABLE | MAP_MEMTAG, &Data); - map(reinterpret_cast(UntaggedPos), - CommitBase + CommitSize - UntaggedPos, "scudo:secondary", MAP_RESIZABLE, - &Data); - } else { - map(reinterpret_cast(CommitBase), CommitSize, "scudo:secondary", - MAP_RESIZABLE | (useMemoryTagging(Options) ? MAP_MEMTAG : 0), - &Data); - } + mapSecondary(Options, CommitBase, CommitSize, AllocPos, 0, &Data); const uptr HeaderPos = AllocPos - Chunk::getHeaderSize() - LargeBlock::getHeaderSize(); LargeBlock::Header *H = reinterpret_cast( diff --git a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt index 78c297ae7e80..88b7227f4fcb 100644 --- a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt @@ -13,6 +13,7 @@ set(SCUDO_UNITTEST_CFLAGS -I${COMPILER_RT_SOURCE_DIR}/lib/scudo/standalone/include -DGTEST_HAS_RTTI=0 -DSCUDO_DEBUG=1 + -g # Extra flags for the C++ tests # TODO(kostyak): find a way to make -fsized-deallocation work -Wno-mismatched-new-delete) diff --git a/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp b/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp index 4298e69b5774..75ef22a16e17 100644 --- a/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp +++ b/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp @@ -48,12 +48,15 @@ static scudo::Allocatorframes; for (int i = 0; frame && frame->info.address; frame = frame->next, i++) { - InternalScopedString res(2 * GetPageSizeCached()); + InternalScopedString res; RenderFrame(&res, common_flags()->stack_trace_format, i, frame->info.address, &frame->info, common_flags()->symbolize_vs_style, diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index 4dda62054d8d..ed6cc83450d9 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -11,17 +11,19 @@ // Main file (entry points) for the TSan run-time. //===----------------------------------------------------------------------===// +#include "tsan_rtl.h" + #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_libc.h" -#include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_placement_new.h" +#include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_symbolizer.h" #include "tsan_defs.h" -#include "tsan_platform.h" -#include "tsan_rtl.h" +#include "tsan_interface.h" #include "tsan_mman.h" +#include "tsan_platform.h" #include "tsan_suppressions.h" #include "tsan_symbolize.h" #include "ubsan/ubsan_init.h" @@ -56,12 +58,23 @@ Context *ctx; bool OnFinalize(bool failed); void OnInitialize(); #else +#include SANITIZER_WEAK_CXX_DEFAULT_IMPL bool OnFinalize(bool failed) { +#if !SANITIZER_GO + if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_finalize")) + return reinterpret_cast(ptr)(failed); +#endif return failed; } SANITIZER_WEAK_CXX_DEFAULT_IMPL -void OnInitialize() {} +void OnInitialize() { +#if !SANITIZER_GO + if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_initialize")) { + return reinterpret_cast(ptr)(); + } +#endif +} #endif static char thread_registry_placeholder[sizeof(ThreadRegistry)]; @@ -167,12 +180,12 @@ static void *BackgroundThread(void *arg) { } else if (internal_strcmp(flags()->profile_memory, "stderr") == 0) { mprof_fd = 2; } else { - InternalScopedString filename(kMaxPathLength); + InternalScopedString filename; filename.append("%s.%d", flags()->profile_memory, (int)internal_getpid()); fd_t fd = OpenFile(filename.data(), WrOnly); if (fd == kInvalidFd) { Printf("ThreadSanitizer: failed to open memory profile file '%s'\n", - &filename[0]); + filename.data()); } else { mprof_fd = fd; } diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cpp b/compiler-rt/lib/ubsan/ubsan_diag.cpp index c081ed169811..ef2e495cac8e 100644 --- a/compiler-rt/lib/ubsan/ubsan_diag.cpp +++ b/compiler-rt/lib/ubsan/ubsan_diag.cpp @@ -278,7 +278,7 @@ static void PrintMemorySnippet(const Decorator &Decor, MemoryLocation Loc, } // Emit data. - InternalScopedString Buffer(1024); + InternalScopedString Buffer; for (uptr P = Min; P != Max; ++P) { unsigned char C = *reinterpret_cast(P); Buffer.append("%s%02x", (P % 8 == 0) ? " " : " ", C); @@ -346,7 +346,7 @@ Diag::~Diag() { // All diagnostics should be printed under report mutex. ScopedReport::CheckLocked(); Decorator Decor; - InternalScopedString Buffer(1024); + InternalScopedString Buffer; // Prepare a report that a monitor process can inspect. if (Level == DL_Error) { diff --git a/compiler-rt/lib/ubsan/ubsan_monitor.cpp b/compiler-rt/lib/ubsan/ubsan_monitor.cpp index d064e95f76f7..69dd986f9bdf 100644 --- a/compiler-rt/lib/ubsan/ubsan_monitor.cpp +++ b/compiler-rt/lib/ubsan/ubsan_monitor.cpp @@ -17,7 +17,7 @@ using namespace __ubsan; UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind, Location &Loc, InternalScopedString &Msg) - : IssueKind(IssueKind), Loc(Loc), Buffer(Msg.length() + 1) { + : IssueKind(IssueKind), Loc(Loc) { // We have the common sanitizer reporting lock, so it's safe to register a // new UB report. RegisterUndefinedBehaviorReport(this); @@ -52,9 +52,9 @@ void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind, // Ensure that the first character of the diagnostic text can't start with a // lowercase letter. - char FirstChar = Buf.data()[0]; + char FirstChar = *Buf.data(); if (FirstChar >= 'a' && FirstChar <= 'z') - Buf.data()[0] = FirstChar - 'a' + 'A'; + *Buf.data() += 'A' - 'a'; *OutIssueKind = CurrentUBR->IssueKind; *OutMessage = Buf.data(); diff --git a/compiler-rt/test/asan/TestCases/Posix/asan-sigbus.cpp b/compiler-rt/test/asan/TestCases/Posix/asan-sigbus.cpp index baf1e4266866..1418dc446289 100644 --- a/compiler-rt/test/asan/TestCases/Posix/asan-sigbus.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/asan-sigbus.cpp @@ -5,8 +5,6 @@ // RUN: %env_asan_opts=handle_sigbus=0 not --crash %run %t 2>&1 | FileCheck %s // UNSUPPORTED: ios -// Instead of getting a SIGBUS error, we get a SIGSEGV -// XFAIL: freebsd #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/no-fd.cpp b/compiler-rt/test/asan/TestCases/Posix/no-fd.cpp index 6f8b2f4e15b0..3130eda2e426 100644 --- a/compiler-rt/test/asan/TestCases/Posix/no-fd.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/no-fd.cpp @@ -1,6 +1,11 @@ // RUN: %clangxx_asan -std=c++11 -O0 %s -o %t -// RUN: %run %t 2>&1 | FileCheck %s -// RUN: %env_asan_opts=debug=1,verbosity=2 %run %t 2>&1 | FileCheck %s + +// MallocNanoZone=0 disables initialization of the Nano MallocZone on Darwin. +// Initialization of this zone can interfere with this test because the zone +// might log which opens another file descriptor, +// e.g. failing to setup the zone due to ASan taking the memory region it wants. +// RUN: env MallocNanoZone=0 %run %t 2>&1 | FileCheck %s +// RUN: env MallocNanoZone=0 %env_asan_opts=debug=1,verbosity=2 %run %t 2>&1 | FileCheck %s // Test ASan initialization diff --git a/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp b/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp index 19f8073e0509..f6b54373af6f 100644 --- a/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp +++ b/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %clangxx_asan -O0 %s --std=c++14 -o %t // RUN: not %run %t 10 0 2>&1 | FileCheck %s --check-prefixes=CHECK,T0 // RUN: not %run %t 10000000 0 2>&1 | FileCheck %s --check-prefixes=CHECK,T0 diff --git a/compiler-rt/test/asan/TestCases/large_func_test.cpp b/compiler-rt/test/asan/TestCases/large_func_test.cpp index 9c8e28b9ebef..6ab76d960626 100644 --- a/compiler-rt/test/asan/TestCases/large_func_test.cpp +++ b/compiler-rt/test/asan/TestCases/large_func_test.cpp @@ -27,7 +27,8 @@ static void LargeFunction(int *x, int zero) { // CHECK-Linux: {{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-3]] // CHECK-SunOS: {{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-4]] // CHECK-Windows:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-5]] - // CHECK-Darwin: {{#0 0x.* in .*LargeFunction.*large_func_test.cpp}}:[[@LINE-6]] + // CHECK-FreeBSD:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-6]] + // CHECK-Darwin: {{#0 0x.* in .*LargeFunction.*large_func_test.cpp}}:[[@LINE-7]] x[10]++; x[11]++; @@ -50,7 +51,8 @@ int main(int argc, char **argv) { // CHECK-Linux: {{ #0 0x.* in operator new}} // CHECK-SunOS: {{ #0 0x.* in operator new}} // CHECK-Windows:{{ #0 0x.* in operator new}} + // CHECK-FreeBSD:{{ #0 0x.* in operator new}} // CHECK-Darwin: {{ #0 0x.* in .*_Zna}} - // CHECK: {{ #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-9]] + // CHECK-NEXT: {{ #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-10]] delete[] x; } diff --git a/compiler-rt/test/asan/TestCases/lsan_crash.cpp b/compiler-rt/test/asan/TestCases/lsan_crash.cpp index 23c2569a0b73..8ea9e74c8cb2 100644 --- a/compiler-rt/test/asan/TestCases/lsan_crash.cpp +++ b/compiler-rt/test/asan/TestCases/lsan_crash.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -O2 %s -o %t && %run %t +// RUN: %clangxx_asan -O2 %s --std=c++14 -o %t && %run %t #include #include diff --git a/compiler-rt/test/asan/TestCases/use-after-delete.cpp b/compiler-rt/test/asan/TestCases/use-after-delete.cpp index 14b14256c1df..4d0c055368bb 100644 --- a/compiler-rt/test/asan/TestCases/use-after-delete.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-delete.cpp @@ -19,15 +19,17 @@ int main() { // CHECK-Linux: {{ #0 0x.* in operator delete\[\]}} // CHECK-SunOS: {{ #0 0x.* in operator delete\[\]}} // CHECK-Windows:{{ #0 0x.* in operator delete\[\]}} + // CHECK-FreeBSD:{{ #0 0x.* in operator delete\[\]}} // CHECK-Darwin: {{ #0 0x.* in .*_Zda}} - // CHECK: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-13]] + // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-14]] // CHECK: {{previously allocated by thread T0 here:}} // CHECK-Linux: {{ #0 0x.* in operator new\[\]}} // CHECK-SunOS: {{ #0 0x.* in operator new\[\]}} // CHECK-Windows:{{ #0 0x.* in operator new\[\]}} + // CHECK-FreeBSD:{{ #0 0x.* in operator new\[\]}} // CHECK-Darwin: {{ #0 0x.* in .*_Zna}} - // CHECK: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-21]] + // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-23]] // CHECK: Shadow byte legend (one shadow byte represents {{[0-9]+}} application bytes): diff --git a/compiler-rt/test/asan/TestCases/wild_pointer.cpp b/compiler-rt/test/asan/TestCases/wild_pointer.cpp new file mode 100644 index 000000000000..8969a285e565 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/wild_pointer.cpp @@ -0,0 +1,32 @@ +// RUN: %clangxx_asan %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// REQUIRES: asan-64-bits + +#include +#include +#include +#include +#include + +int main() { + char *p = new char; + char *dest = new char; + const size_t offset = 0x4567890123456789; + + // The output here needs to match the output from the sanitizer runtime, + // which includes 0x and prints hex in lower case. + // + // On Windows, %p omits %0x and prints hex characters in upper case, + // so we use PRIxPTR instead of %p. + fprintf(stderr, "Expected bad addr: %#" PRIxPTR "\n", + reinterpret_cast(p + offset)); + // Flush it so the output came out before the asan report. + fflush(stderr); + + memmove(dest, p, offset); + return 0; +} + +// CHECK: Expected bad addr: [[ADDR:0x[0-9,a-f]+]] +// CHECK: AddressSanitizer: unknown-crash on address [[ADDR]] +// CHECK: Address [[ADDR]] is a wild pointer inside of access range of size 0x4567890123456789 diff --git a/compiler-rt/test/cfi/lit.cfg.py b/compiler-rt/test/cfi/lit.cfg.py index cbffe6ea8a65..2f2d1ddcaa79 100644 --- a/compiler-rt/test/cfi/lit.cfg.py +++ b/compiler-rt/test/cfi/lit.cfg.py @@ -13,7 +13,11 @@ def build_invocation(compile_flags): config.substitutions.append((r"%clang ", clang + ' ')) config.substitutions.append((r"%clangxx ", clangxx + ' ')) -if config.lto_supported: + +if 'darwin' in config.available_features: + # -fsanitize=cfi is not supported on Darwin hosts + config.unsupported = True +elif config.lto_supported: clang_cfi = clang + '-fsanitize=cfi ' if config.cfi_lit_test_mode == "Devirt": diff --git a/compiler-rt/test/dfsan/atomic.cpp b/compiler-rt/test/dfsan/atomic.cpp index 7d4dc04cb536..459bf31075e5 100644 --- a/compiler-rt/test/dfsan/atomic.cpp +++ b/compiler-rt/test/dfsan/atomic.cpp @@ -1,4 +1,7 @@ // RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true %s -fno-exceptions -o %t && %run %t +// RUN: %clangxx_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -fno-exceptions -o %t && %run %t +// +// REQUIRES: x86_64-target-arch // // Use -fno-exceptions to turn off exceptions to avoid instrumenting // __cxa_begin_catch, std::terminate and __gxx_personality_v0. @@ -14,31 +17,45 @@ std::atomic atomic_i{0}; +struct arg_struct { + size_t index; + dfsan_origin origin; +}; + static void *ThreadFn(void *arg) { - if ((size_t)arg % 2) { + if (((arg_struct *)arg)->index % 2) { int i = 10; dfsan_set_label(8, (void *)&i, sizeof(i)); atomic_i.store(i, std::memory_order_relaxed); - return 0; } int j = atomic_i.load(); assert(dfsan_get_label(j) == 0 || dfsan_get_label(j) == 2); - +#ifdef ORIGIN_TRACKING + if (dfsan_get_label(j) == 2) + assert(dfsan_get_init_origin(&j) == ((arg_struct *)arg)->origin); +#endif return 0; } int main(void) { int i = 10; dfsan_set_label(2, (void *)&i, sizeof(i)); +#ifdef ORIGIN_TRACKING + dfsan_origin origin = dfsan_get_origin(i); +#endif atomic_i.store(i, std::memory_order_relaxed); const int kNumThreads = 24; pthread_t t[kNumThreads]; + arg_struct args[kNumThreads]; for (int i = 0; i < kNumThreads; ++i) { - pthread_create(&t[i], 0, ThreadFn, (void *)i); + args[i].index = i; +#ifdef ORIGIN_TRACKING + args[i].origin = origin; +#endif + pthread_create(&t[i], 0, ThreadFn, (void *)(args + i)); } - for (int i = 0; i < kNumThreads; ++i) { + for (int i = 0; i < kNumThreads; ++i) pthread_join(t[i], 0); - } return 0; } diff --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp index 4676c91bed0f..63fa4389e6ea 100644 --- a/compiler-rt/test/dfsan/custom.cpp +++ b/compiler-rt/test/dfsan/custom.cpp @@ -3,8 +3,12 @@ // RUN: %clang_dfsan -DFAST_16_LABELS -mllvm -dfsan-fast-16-labels %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t // RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t // RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi %s -o %t && %run %t - +// RUN: %clang_dfsan -DFAST_16_LABELS -DORIGIN_TRACKING -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t +// RUN: %clang_dfsan -DFAST_16_LABELS -DORIGIN_TRACKING -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t +// // Tests custom implementations of various glibc functions. +// +// REQUIRES: x86_64-target-arch #include @@ -35,6 +39,8 @@ dfsan_label i_label = 0; dfsan_label j_label = 0; dfsan_label k_label = 0; +dfsan_label m_label = 0; +dfsan_label n_label = 0; dfsan_label i_j_label = 0; #define ASSERT_ZERO_LABEL(data) \ @@ -49,18 +55,130 @@ dfsan_label i_j_label = 0; #define ASSERT_READ_LABEL(ptr, size, label) \ assert(label == dfsan_read_label(ptr, size)) +#ifdef ORIGIN_TRACKING +#define ASSERT_ZERO_ORIGIN(data) \ + assert(0 == dfsan_get_origin((long)(data))) +#else +#define ASSERT_ZERO_ORIGIN(data) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_ZERO_ORIGINS(ptr, size) \ + for (int i = 0; i < size; ++i) { \ + assert(0 == dfsan_get_origin((long)(((char *)ptr)[i]))); \ + } +#else +#define ASSERT_ZERO_ORIGINS(ptr, size) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_ORIGIN(data, origin) \ + assert(origin == dfsan_get_origin((long)(data))) +#else +#define ASSERT_ORIGIN(data, origin) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_ORIGINS(ptr, size, origin) \ + for (int i = 0; i < size; ++i) { \ + assert(origin == dfsan_get_origin((long)(((char *)ptr)[i]))); \ + } +#else +#define ASSERT_ORIGINS(ptr, size, origin) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_INIT_ORIGIN(ptr, origin) \ + assert(origin == dfsan_get_init_origin(ptr)) +#else +#define ASSERT_INIT_ORIGIN(ptr, origin) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data) \ + assert(dfsan_get_origin((long)(data)) == dfsan_get_init_origin(ptr)) +#else +#define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_INIT_ORIGINS(ptr, size, origin) \ + for (int i = 0; i < size; ++i) { \ + assert(origin == dfsan_get_init_origin(&((char *)ptr)[i])); \ + } +#else +#define ASSERT_INIT_ORIGINS(ptr, size, origin) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_EQ_ORIGIN(data1, data2) \ + assert(dfsan_get_origin((long)(data1)) == dfsan_get_origin((long)(data2))) +#else +#define ASSERT_EQ_ORIGIN(data1, data2) +#endif + +#ifdef ORIGIN_TRACKING +#define DEFINE_AND_SAVE_ORIGINS(val) \ + dfsan_origin val##_o[sizeof(val)]; \ + for (int i = 0; i < sizeof(val); ++i) \ + val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i])); +#else +#define DEFINE_AND_SAVE_ORIGINS(val) +#endif + +#ifdef ORIGIN_TRACKING +#define SAVE_ORIGINS(val) \ + for (int i = 0; i < sizeof(val); ++i) \ + val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i])); +#else +#define SAVE_ORIGINS(val) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_SAVED_ORIGINS(val) \ + for (int i = 0; i < sizeof(val); ++i) \ + ASSERT_ORIGIN(((char *)(&val))[i], val##_o[i]); +#else +#define ASSERT_SAVED_ORIGINS(val) +#endif + +#ifdef ORIGIN_TRACKING +#define DEFINE_AND_SAVE_N_ORIGINS(val, n) \ + dfsan_origin val##_o[n]; \ + for (int i = 0; i < n; ++i) \ + val##_o[i] = dfsan_get_origin((long)(val[i])); +#else +#define DEFINE_AND_SAVE_N_ORIGINS(val, n) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_SAVED_N_ORIGINS(val, n) \ + for (int i = 0; i < n; ++i) \ + ASSERT_ORIGIN(val[i], val##_o[i]); +#else +#define ASSERT_SAVED_N_ORIGINS(val, n) +#endif + void test_stat() { int i = 1; dfsan_set_label(i_label, &i, sizeof(i)); struct stat s; s.st_dev = i; - assert(0 == stat("/", &s)); + DEFINE_AND_SAVE_ORIGINS(s) + int ret = stat("/", &s); + assert(0 == ret); + ASSERT_ZERO_LABEL(ret); ASSERT_ZERO_LABEL(s.st_dev); + ASSERT_SAVED_ORIGINS(s) s.st_dev = i; - assert(-1 == stat("/nonexistent", &s)); + SAVE_ORIGINS(s) + ret = stat("/nonexistent", &s); + assert(-1 == ret); + ASSERT_ZERO_LABEL(ret); ASSERT_LABEL(s.st_dev, i_label); + ASSERT_SAVED_ORIGINS(s) } void test_fstat() { @@ -70,9 +188,12 @@ void test_fstat() { struct stat s; int fd = open("/dev/zero", O_RDONLY); s.st_dev = i; + DEFINE_AND_SAVE_ORIGINS(s) int rv = fstat(fd, &s); assert(0 == rv); + ASSERT_ZERO_LABEL(rv); ASSERT_ZERO_LABEL(s.st_dev); + ASSERT_SAVED_ORIGINS(s) } void test_memcmp() { @@ -86,7 +207,12 @@ void test_memcmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_j_label); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif + + rv = memcmp(str1, str2, sizeof(str1) - 2); + assert(rv == 0); + ASSERT_ZERO_LABEL(rv); } void test_bcmp() { @@ -100,6 +226,7 @@ void test_bcmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_j_label); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif rv = bcmp(str1, str2, sizeof(str1) - 2); @@ -112,31 +239,60 @@ void test_memcpy() { char str2[sizeof(str1)]; dfsan_set_label(i_label, &str1[3], 1); - ASSERT_ZERO_LABEL(memcpy(str2, str1, sizeof(str1))); + DEFINE_AND_SAVE_ORIGINS(str1) + + char *ptr2 = str2; + dfsan_set_label(j_label, &ptr2, sizeof(ptr2)); + + void *r = memcpy(ptr2, str1, sizeof(str1)); + ASSERT_LABEL(r, j_label); + ASSERT_EQ_ORIGIN(r, ptr2); assert(0 == memcmp(str2, str1, sizeof(str1))); ASSERT_ZERO_LABEL(str2[0]); ASSERT_LABEL(str2[3], i_label); + + for (int i = 0; i < sizeof(str2); ++i) { + if (!dfsan_get_label(str2[i])) + continue; + ASSERT_INIT_ORIGIN(&(str2[i]), str1_o[i]); + } } void test_memmove() { char str[] = "str1xx"; dfsan_set_label(i_label, &str[3], 1); - ASSERT_ZERO_LABEL(memmove(str + 2, str, 4)); + DEFINE_AND_SAVE_ORIGINS(str) + + char *ptr = str + 2; + dfsan_set_label(j_label, &ptr, sizeof(ptr)); + + void *r = memmove(ptr, str, 4); + ASSERT_LABEL(r, j_label); + ASSERT_EQ_ORIGIN(r, ptr); assert(0 == memcmp(str + 2, "str1", 4)); - for (int i = 0; i <= 4; ++i) - ASSERT_ZERO_LABEL(str[i]); + ASSERT_ZERO_LABEL(str[4]); ASSERT_LABEL(str[5], i_label); + + for (int i = 0; i < 4; ++i) { + if (!dfsan_get_label(ptr[i])) + continue; + ASSERT_INIT_ORIGIN(&(ptr[i]), str_o[i]); + } } void test_memset() { char buf[8]; int j = 'a'; + char *ptr = buf; dfsan_set_label(j_label, &j, sizeof(j)); - - ASSERT_ZERO_LABEL(memset(&buf, j, sizeof(buf))); + dfsan_set_label(k_label, &ptr, sizeof(ptr)); + void *ret = memset(ptr, j, sizeof(buf)); + ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, ptr); for (int i = 0; i < 8; ++i) { ASSERT_LABEL(buf[i], j_label); + ASSERT_EQ_ORIGIN(buf[i], j); assert(buf[i] == 'a'); } } @@ -152,20 +308,48 @@ void test_strcmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_j_label); + ASSERT_EQ_ORIGIN(rv, str1[3]); +#endif + + rv = strcmp(str1, str1); + assert(rv == 0); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); + ASSERT_ZERO_ORIGIN(rv); +#else + ASSERT_LABEL(rv, i_label); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif } void test_strcat() { char src[] = "world"; + int volatile x = 0; // buffer to ensure src and dst do not share origins char dst[] = "hello \0 "; + int volatile y = 0; // buffer to ensure dst and p do not share origins char *p = dst; dfsan_set_label(k_label, &p, sizeof(p)); dfsan_set_label(i_label, src, sizeof(src)); dfsan_set_label(j_label, dst, sizeof(dst)); + dfsan_origin dst_o = dfsan_get_origin((long)dst[0]); char *ret = strcat(p, src); ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, p); assert(ret == dst); assert(strcmp(src, dst + 6) == 0); + // Origins are assigned for every 4 contiguous 4-aligned bytes. After + // appending src to dst, origins of src can overwrite origins of dst if their + // application adddresses are within [start_aligned_down, end_aligned_up). + // Other origins are not changed. + char *start_aligned_down = (char *)(((size_t)(dst + 6)) & ~3UL); + char *end_aligned_up = (char *)(((size_t)(dst + 11 + 4)) & ~3UL); + for (int i = 0; i < 12; ++i) { + if (dst + i < start_aligned_down || dst + i >= end_aligned_up) { + ASSERT_INIT_ORIGIN(&dst[i], dst_o); + } else { + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst[i], src[0]); + } + } for (int i = 0; i < 6; ++i) { ASSERT_LABEL(dst[i], j_label); } @@ -186,16 +370,26 @@ void test_strlen() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_label); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif } void test_strdup() { char str1[] = "str1"; dfsan_set_label(i_label, &str1[3], 1); + DEFINE_AND_SAVE_ORIGINS(str1) char *strd = strdup(str1); + ASSERT_ZERO_LABEL(strd); ASSERT_ZERO_LABEL(strd[0]); ASSERT_LABEL(strd[3], i_label); + + for (int i = 0; i < strlen(strd); ++i) { + if (!dfsan_get_label(strd[i])) + continue; + ASSERT_INIT_ORIGIN(&(strd[i]), str1_o[i]); + } + free(strd); } @@ -212,14 +406,28 @@ void test_strncpy() { ASSERT_ZERO_LABEL(strd[1]); ASSERT_ZERO_LABEL(strd[2]); ASSERT_LABEL(strd[3], i_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&(strd[3]), str1[3]); - strd = strncpy(str2, str1, 3); + char *p2 = str2; + dfsan_set_label(j_label, &p2, sizeof(p2)); + strd = strncpy(p2, str1, 3); assert(strd == str2); assert(strncmp(str1, str2, 3) == 0); - ASSERT_ZERO_LABEL(strd); + ASSERT_LABEL(strd, j_label); + ASSERT_EQ_ORIGIN(strd, p2); + // When -dfsan-combine-pointer-labels-on-load is on, strd's label propagates + // to strd[i]'s label. When ORIGIN_TRACKING is defined, + // -dfsan-combine-pointer-labels-on-load is always off, otherwise the flag + // is on by default. +#if defined(ORIGIN_TRACKING) ASSERT_ZERO_LABEL(strd[0]); ASSERT_ZERO_LABEL(strd[1]); ASSERT_ZERO_LABEL(strd[2]); +#else + ASSERT_LABEL(strd[0], j_label); + ASSERT_LABEL(strd[1], j_label); + ASSERT_LABEL(strd[2], j_label); +#endif } void test_strncmp() { @@ -233,11 +441,25 @@ void test_strncmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif + rv = strncmp(str1, str2, 0); + assert(rv == 0); + ASSERT_ZERO_LABEL(rv); + rv = strncmp(str1, str2, 3); assert(rv == 0); ASSERT_ZERO_LABEL(rv); + + rv = strncmp(str1, str1, 4); + assert(rv == 0); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, i_label); + ASSERT_EQ_ORIGIN(rv, str1[3]); +#endif } void test_strcasecmp() { @@ -252,6 +474,7 @@ void test_strcasecmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif rv = strcasecmp(str1, str3); @@ -260,6 +483,7 @@ void test_strcasecmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif char s1[] = "AbZ"; @@ -273,6 +497,7 @@ void test_strcasecmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); + ASSERT_EQ_ORIGIN(rv, s1[2]); #endif } @@ -287,6 +512,7 @@ void test_strncasecmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); + ASSERT_EQ_ORIGIN(rv, str1[3]); #endif rv = strncasecmp(str1, str2, 3); @@ -316,6 +542,7 @@ void test_strncasecmp() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); + ASSERT_EQ_ORIGIN(rv, s1[2]); #endif } @@ -323,35 +550,56 @@ void test_strchr() { char str1[] = "str1"; dfsan_set_label(i_label, &str1[3], 1); - char *crv = strchr(str1, 'r'); + char *p1 = str1; + char c = 'r'; + dfsan_set_label(k_label, &c, sizeof(c)); + + char *crv = strchr(p1, c); assert(crv == &str1[2]); +#ifdef STRICT_DATA_DEPENDENCIES ASSERT_ZERO_LABEL(crv); +#else + ASSERT_LABEL(crv, k_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, c); +#endif - crv = strchr(str1, '1'); + dfsan_set_label(j_label, &p1, sizeof(p1)); + crv = strchr(p1, 'r'); + assert(crv == &str1[2]); + ASSERT_LABEL(crv, j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1); + + crv = strchr(p1, '1'); assert(crv == &str1[3]); #ifdef STRICT_DATA_DEPENDENCIES - ASSERT_ZERO_LABEL(crv); + ASSERT_LABEL(crv, j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1); #else - ASSERT_LABEL(crv, i_label); + ASSERT_LABEL(crv, i_j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]); #endif - crv = strchr(str1, 'x'); + crv = strchr(p1, 'x'); assert(!crv); #ifdef STRICT_DATA_DEPENDENCIES - ASSERT_ZERO_LABEL(crv); + ASSERT_LABEL(crv, j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1); #else - ASSERT_LABEL(crv, i_label); + ASSERT_LABEL(crv, i_j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]); #endif // `man strchr` says: // The terminating null byte is considered part of the string, so that if c // is specified as '\0', these functions return a pointer to the terminator. - crv = strchr(str1, '\0'); + crv = strchr(p1, '\0'); assert(crv == &str1[4]); #ifdef STRICT_DATA_DEPENDENCIES - ASSERT_ZERO_LABEL(crv); + ASSERT_LABEL(crv, j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1); #else - ASSERT_LABEL(crv, i_label); + ASSERT_LABEL(crv, i_j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]); #endif } @@ -406,6 +654,9 @@ void test_recvmmsg() { dfsan_set_label(i_label, &rmmsg[1].msg_len, sizeof(rmmsg[1].msg_len)); dfsan_set_label(i_label, &timeout, sizeof(timeout)); + dfsan_origin msg_len0_o = dfsan_get_origin((long)(rmmsg[0].msg_len)); + dfsan_origin msg_len1_o = dfsan_get_origin((long)(rmmsg[1].msg_len)); + // Receive messages and check labels. int received_msgs = recvmmsg(sockfds[1], rmmsg, 2, 0, &timeout); assert(received_msgs == sent_msgs); @@ -423,6 +674,9 @@ void test_recvmmsg() { ASSERT_LABEL(timeout.tv_sec, i_label); ASSERT_LABEL(timeout.tv_nsec, i_label); + ASSERT_ORIGIN((long)(rmmsg[0].msg_len), msg_len0_o); + ASSERT_ORIGIN((long)(rmmsg[1].msg_len), msg_len1_o); + close(sockfds[0]); close(sockfds[1]); } @@ -450,6 +704,8 @@ void test_recvmsg() { dfsan_set_label(i_label, rbuf, sizeof(rbuf)); dfsan_set_label(i_label, &rmsg, sizeof(rmsg)); + DEFINE_AND_SAVE_ORIGINS(rmsg) + ssize_t received = recvmsg(sockfds[1], &rmsg, 0); assert(received == sent); assert(memcmp(sbuf, rbuf, 8) == 0); @@ -458,6 +714,8 @@ void test_recvmsg() { ASSERT_READ_ZERO_LABEL(&rbuf[0], 8); ASSERT_READ_LABEL(&rbuf[8], 1, i_label); + ASSERT_SAVED_ORIGINS(rmsg) + close(sockfds[0]); close(sockfds[1]); } @@ -467,6 +725,7 @@ void test_read() { dfsan_set_label(i_label, buf, 1); dfsan_set_label(j_label, buf + 15, 1); + DEFINE_AND_SAVE_ORIGINS(buf) ASSERT_LABEL(buf[0], i_label); ASSERT_LABEL(buf[15], j_label); @@ -476,6 +735,7 @@ void test_read() { ASSERT_ZERO_LABEL(rv); ASSERT_ZERO_LABEL(buf[0]); ASSERT_ZERO_LABEL(buf[15]); + ASSERT_SAVED_ORIGINS(buf) close(fd); } @@ -484,6 +744,7 @@ void test_pread() { dfsan_set_label(i_label, buf, 1); dfsan_set_label(j_label, buf + 15, 1); + DEFINE_AND_SAVE_ORIGINS(buf) ASSERT_LABEL(buf[0], i_label); ASSERT_LABEL(buf[15], j_label); @@ -493,6 +754,7 @@ void test_pread() { ASSERT_ZERO_LABEL(rv); ASSERT_ZERO_LABEL(buf[0]); ASSERT_ZERO_LABEL(buf[15]); + ASSERT_SAVED_ORIGINS(buf) close(fd); } @@ -509,31 +771,44 @@ void test_dlopen() { void test_clock_gettime() { struct timespec tp; dfsan_set_label(j_label, ((char *)&tp) + 3, 1); + dfsan_origin origin = dfsan_get_origin((long)(((char *)&tp)[3])); int t = clock_gettime(CLOCK_REALTIME, &tp); assert(t == 0); ASSERT_ZERO_LABEL(t); ASSERT_ZERO_LABEL(((char *)&tp)[3]); + ASSERT_ORIGIN(((char *)&tp)[3], origin); } void test_ctime_r() { char *buf = (char*) malloc(64); time_t t = 0; + DEFINE_AND_SAVE_ORIGINS(buf) + dfsan_origin t_o = dfsan_get_origin((long)t); + char *ret = ctime_r(&t, buf); ASSERT_ZERO_LABEL(ret); assert(buf == ret); ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1); + ASSERT_SAVED_ORIGINS(buf) dfsan_set_label(i_label, &t, sizeof(t)); + t_o = dfsan_get_origin((long)t); ret = ctime_r(&t, buf); ASSERT_ZERO_LABEL(ret); ASSERT_READ_LABEL(buf, strlen(buf) + 1, i_label); + for (int i = 0; i < strlen(buf) + 1; ++i) + ASSERT_ORIGIN(buf[i], t_o); t = 0; dfsan_set_label(j_label, &buf, sizeof(&buf)); + dfsan_origin buf_ptr_o = dfsan_get_origin((long)buf); ret = ctime_r(&t, buf); ASSERT_LABEL(ret, j_label); + ASSERT_ORIGIN(ret, buf_ptr_o); ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1); + for (int i = 0; i < strlen(buf) + 1; ++i) + ASSERT_ORIGIN(buf[i], t_o); } static int write_callback_count = 0; @@ -559,6 +834,8 @@ void test_dfsan_set_write_callback() { write_callback_count = 0; + DEFINE_AND_SAVE_ORIGINS(buf) + // Callback should be invoked on every call to write(). int res = write(fd, buf, buf_len); assert(write_callback_count == 1); @@ -567,12 +844,21 @@ void test_dfsan_set_write_callback() { ASSERT_READ_ZERO_LABEL(last_buf, sizeof(last_buf)); ASSERT_READ_ZERO_LABEL(&last_count, sizeof(last_count)); + for (int i = 0; i < buf_len; ++i) + ASSERT_ORIGIN(last_buf[i], buf_o[i]); + + ASSERT_ZERO_ORIGINS(&last_count, sizeof(last_count)); + // Add a label to write() arguments. Check that the labels are readable from // the values passed to the callback. dfsan_set_label(i_label, &fd, sizeof(fd)); dfsan_set_label(j_label, &(buf[3]), 1); dfsan_set_label(k_label, &buf_len, sizeof(buf_len)); + dfsan_origin fd_o = dfsan_get_origin((long)fd); + dfsan_origin buf3_o = dfsan_get_origin((long)(buf[3])); + dfsan_origin buf_len_o = dfsan_get_origin((long)buf_len); + res = write(fd, buf, buf_len); assert(write_callback_count == 2); ASSERT_READ_ZERO_LABEL(&res, sizeof(res)); @@ -580,6 +866,22 @@ void test_dfsan_set_write_callback() { ASSERT_READ_LABEL(&last_buf[3], sizeof(last_buf[3]), j_label); ASSERT_READ_LABEL(last_buf, sizeof(last_buf), j_label); ASSERT_READ_LABEL(&last_count, sizeof(last_count), k_label); + ASSERT_ZERO_ORIGINS(&res, sizeof(res)); + ASSERT_INIT_ORIGINS(&last_fd, sizeof(last_fd), fd_o); + ASSERT_INIT_ORIGINS(&last_buf[3], sizeof(last_buf[3]), buf3_o); + + // Origins are assigned for every 4 contiguous 4-aligned bytes. After + // appending src to dst, origins of src can overwrite origins of dst if their + // application adddresses are within an aligned range. Other origins are not + // changed. + for (int i = 0; i < buf_len; ++i) { + size_t i_addr = size_t(&last_buf[i]); + if (((size_t(&last_buf[3]) & ~3UL) > i_addr) || + (((size_t(&last_buf[3]) + 4) & ~3UL) <= i_addr)) + ASSERT_ORIGIN(last_buf[i], buf_o[i]); + } + + ASSERT_INIT_ORIGINS(&last_count, sizeof(last_count), buf_len_o); dfsan_set_write_callback(NULL); } @@ -588,27 +890,44 @@ void test_fgets() { char *buf = (char*) malloc(128); FILE *f = fopen("/etc/passwd", "r"); dfsan_set_label(j_label, buf, 1); + DEFINE_AND_SAVE_N_ORIGINS(buf, 128) + char *ret = fgets(buf, sizeof(buf), f); assert(ret == buf); ASSERT_ZERO_LABEL(ret); + ASSERT_EQ_ORIGIN(ret, buf); ASSERT_READ_ZERO_LABEL(buf, 128); + ASSERT_SAVED_N_ORIGINS(buf, 128) + dfsan_set_label(j_label, &buf, sizeof(&buf)); ret = fgets(buf, sizeof(buf), f); ASSERT_LABEL(ret, j_label); + ASSERT_EQ_ORIGIN(ret, buf); + ASSERT_SAVED_N_ORIGINS(buf, 128) + fclose(f); + free(buf); } void test_getcwd() { char buf[1024]; char *ptr = buf; dfsan_set_label(i_label, buf + 2, 2); + DEFINE_AND_SAVE_ORIGINS(buf) + char* ret = getcwd(buf, sizeof(buf)); assert(ret == buf); assert(ret[0] == '/'); + ASSERT_ZERO_LABEL(ret); + ASSERT_EQ_ORIGIN(ret, buf); ASSERT_READ_ZERO_LABEL(buf + 2, 2); + ASSERT_SAVED_ORIGINS(buf) + dfsan_set_label(i_label, &ptr, sizeof(ptr)); ret = getcwd(ptr, sizeof(buf)); ASSERT_LABEL(ret, i_label); + ASSERT_EQ_ORIGIN(ret, ptr); + ASSERT_SAVED_ORIGINS(buf) } void test_get_current_dir_name() { @@ -616,43 +935,62 @@ void test_get_current_dir_name() { assert(ret); assert(ret[0] == '/'); ASSERT_READ_ZERO_LABEL(ret, strlen(ret) + 1); + ASSERT_ZERO_LABEL(ret); } void test_gethostname() { char buf[1024]; dfsan_set_label(i_label, buf + 2, 2); - assert(gethostname(buf, sizeof(buf)) == 0); + DEFINE_AND_SAVE_ORIGINS(buf) + int ret = gethostname(buf, sizeof(buf)); + assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(buf + 2, 2); + ASSERT_SAVED_ORIGINS(buf) } void test_getrlimit() { struct rlimit rlim; dfsan_set_label(i_label, &rlim, sizeof(rlim)); - assert(getrlimit(RLIMIT_CPU, &rlim) == 0); + DEFINE_AND_SAVE_ORIGINS(rlim); + int ret = getrlimit(RLIMIT_CPU, &rlim); + assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&rlim, sizeof(rlim)); + ASSERT_SAVED_ORIGINS(rlim) } void test_getrusage() { struct rusage usage; dfsan_set_label(i_label, &usage, sizeof(usage)); - assert(getrusage(RUSAGE_SELF, &usage) == 0); + DEFINE_AND_SAVE_ORIGINS(usage); + int ret = getrusage(RUSAGE_SELF, &usage); + assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&usage, sizeof(usage)); + ASSERT_SAVED_ORIGINS(usage) } void test_strcpy() { char src[] = "hello world"; char dst[sizeof(src) + 2]; + char *p_dst = dst; dfsan_set_label(0, src, sizeof(src)); dfsan_set_label(0, dst, sizeof(dst)); + dfsan_set_label(k_label, &p_dst, sizeof(p_dst)); dfsan_set_label(i_label, src + 2, 1); dfsan_set_label(j_label, src + 3, 1); dfsan_set_label(j_label, dst + 4, 1); dfsan_set_label(i_label, dst + 12, 1); - char *ret = strcpy(dst, src); + char *ret = strcpy(p_dst, src); assert(ret == dst); assert(strcmp(src, dst) == 0); + ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, p_dst); for (int i = 0; i < strlen(src) + 1; ++i) { assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i])); + if (dfsan_get_label(dst[i])) + assert(dfsan_get_init_origin(&dst[i]) == dfsan_get_origin(src[i])); } // Note: if strlen(src) + 1 were used instead to compute the first untouched // byte of dest, the label would be I|J. This is because strlen() might @@ -662,67 +1000,137 @@ void test_strcpy() { } void test_strtol() { - char buf[] = "1234578910"; + char non_number_buf[] = "ab "; char *endptr = NULL; + long int ret = strtol(non_number_buf, &endptr, 10); + assert(ret == 0); + assert(endptr == non_number_buf); + ASSERT_ZERO_LABEL(ret); + + char buf[] = "1234578910"; + int base = 10; + dfsan_set_label(k_label, &base, sizeof(base)); + ret = strtol(buf, &endptr, base); + assert(ret == 1234578910); + assert(endptr == buf + 10); + ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, base); + dfsan_set_label(i_label, buf + 1, 1); dfsan_set_label(j_label, buf + 10, 1); - long int ret = strtol(buf, &endptr, 10); + ret = strtol(buf, &endptr, 10); assert(ret == 1234578910); assert(endptr == buf + 10); ASSERT_LABEL(ret, i_j_label); + ASSERT_EQ_ORIGIN(ret, buf[1]); } void test_strtoll() { - char buf[] = "1234578910 "; + char non_number_buf[] = "ab "; char *endptr = NULL; + long long int ret = strtoll(non_number_buf, &endptr, 10); + assert(ret == 0); + assert(endptr == non_number_buf); + ASSERT_ZERO_LABEL(ret); + + char buf[] = "1234578910 "; + int base = 10; + dfsan_set_label(k_label, &base, sizeof(base)); + ret = strtoll(buf, &endptr, base); + assert(ret == 1234578910); + assert(endptr == buf + 10); + ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, base); + dfsan_set_label(i_label, buf + 1, 1); dfsan_set_label(j_label, buf + 2, 1); - long long int ret = strtoll(buf, &endptr, 10); + ret = strtoll(buf, &endptr, 10); assert(ret == 1234578910); assert(endptr == buf + 10); ASSERT_LABEL(ret, i_j_label); + ASSERT_EQ_ORIGIN(ret, buf[1]); } void test_strtoul() { - char buf[] = "ffffffffffffaa"; + char non_number_buf[] = "xy "; char *endptr = NULL; + long unsigned int ret = strtoul(non_number_buf, &endptr, 16); + assert(ret == 0); + assert(endptr == non_number_buf); + ASSERT_ZERO_LABEL(ret); + + char buf[] = "ffffffffffffaa"; + int base = 16; + dfsan_set_label(k_label, &base, sizeof(base)); + ret = strtoul(buf, &endptr, base); + assert(ret == 72057594037927850); + assert(endptr == buf + 14); + ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, base); + dfsan_set_label(i_label, buf + 1, 1); dfsan_set_label(j_label, buf + 2, 1); - long unsigned int ret = strtol(buf, &endptr, 16); + ret = strtoul(buf, &endptr, 16); assert(ret == 72057594037927850); assert(endptr == buf + 14); ASSERT_LABEL(ret, i_j_label); + ASSERT_EQ_ORIGIN(ret, buf[1]); } void test_strtoull() { - char buf[] = "ffffffffffffffaa"; + char non_number_buf[] = "xy "; char *endptr = NULL; + long long unsigned int ret = strtoull(non_number_buf, &endptr, 16); + assert(ret == 0); + assert(endptr == non_number_buf); + ASSERT_ZERO_LABEL(ret); + + char buf[] = "ffffffffffffffaa"; + int base = 16; + dfsan_set_label(k_label, &base, sizeof(base)); + ret = strtoull(buf, &endptr, base); + assert(ret == 0xffffffffffffffaa); + assert(endptr == buf + 16); + ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, base); + dfsan_set_label(i_label, buf + 1, 1); dfsan_set_label(j_label, buf + 2, 1); - long long unsigned int ret = strtoull(buf, &endptr, 16); + ret = strtoull(buf, &endptr, 16); assert(ret == 0xffffffffffffffaa); assert(endptr == buf + 16); ASSERT_LABEL(ret, i_j_label); + ASSERT_EQ_ORIGIN(ret, buf[1]); } void test_strtod() { - char buf[] = "12345.76 foo"; + char non_number_buf[] = "ab "; char *endptr = NULL; + double ret = strtod(non_number_buf, &endptr); + assert(ret == 0); + assert(endptr == non_number_buf); + ASSERT_ZERO_LABEL(ret); + + char buf[] = "12345.76 foo"; dfsan_set_label(i_label, buf + 1, 1); dfsan_set_label(j_label, buf + 6, 1); - double ret = strtod(buf, &endptr); + ret = strtod(buf, &endptr); assert(ret == 12345.76); assert(endptr == buf + 8); ASSERT_LABEL(ret, i_j_label); + ASSERT_EQ_ORIGIN(ret, buf[1]); } void test_time() { time_t t = 0; dfsan_set_label(i_label, &t, 1); + DEFINE_AND_SAVE_ORIGINS(t) time_t ret = time(&t); assert(ret == t); assert(ret > 0); + ASSERT_ZERO_LABEL(ret); ASSERT_ZERO_LABEL(t); + ASSERT_SAVED_ORIGINS(t) } void test_inet_pton() { @@ -731,7 +1139,9 @@ void test_inet_pton() { struct in_addr in4; int ret4 = inet_pton(AF_INET, addr4, &in4); assert(ret4 == 1); + ASSERT_ZERO_LABEL(ret4); ASSERT_READ_LABEL(&in4, sizeof(in4), i_label); + ASSERT_ORIGINS(&in4, sizeof(in4), dfsan_get_origin((long)(addr4[3]))) assert(in4.s_addr == htonl(0x7f000001)); char addr6[] = "::1"; @@ -739,17 +1149,27 @@ void test_inet_pton() { struct in6_addr in6; int ret6 = inet_pton(AF_INET6, addr6, &in6); assert(ret6 == 1); + ASSERT_ZERO_LABEL(ret6); ASSERT_READ_LABEL(((char *) &in6) + sizeof(in6) - 1, 1, j_label); + ASSERT_ORIGINS(&in6, sizeof(in6), dfsan_get_origin((long)(addr6[3]))) } void test_localtime_r() { time_t t0 = 1384800998; struct tm t1; dfsan_set_label(i_label, &t0, sizeof(t0)); - struct tm* ret = localtime_r(&t0, &t1); + dfsan_origin t0_o = dfsan_get_origin((long)t0); + struct tm *pt1 = &t1; + dfsan_set_label(j_label, &pt1, sizeof(pt1)); + dfsan_origin pt1_o = dfsan_get_origin((long)pt1); + struct tm *ret = localtime_r(&t0, pt1); assert(ret == &t1); assert(t1.tm_min == 56); + ASSERT_LABEL(ret, j_label); + ASSERT_INIT_ORIGIN(&ret, pt1_o); + ASSERT_READ_LABEL(&ret, sizeof(ret), j_label); ASSERT_LABEL(t1.tm_mon, i_label); + ASSERT_ORIGIN(t1.tm_mon, t0_o); } void test_getpwuid_r() { @@ -758,11 +1178,16 @@ void test_getpwuid_r() { struct passwd *result; dfsan_set_label(i_label, &pwd, 4); + DEFINE_AND_SAVE_ORIGINS(pwd) + DEFINE_AND_SAVE_ORIGINS(buf) int ret = getpwuid_r(0, &pwd, buf, sizeof(buf), &result); assert(ret == 0); assert(strcmp(pwd.pw_name, "root") == 0); assert(result == &pwd); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&pwd, 4); + ASSERT_SAVED_ORIGINS(pwd) + ASSERT_SAVED_ORIGINS(buf) } void test_epoll_wait() { @@ -783,12 +1208,14 @@ void test_epoll_wait() { // Test epoll_wait when no events have occurred. event = {}; dfsan_set_label(i_label, &event, sizeof(event)); + DEFINE_AND_SAVE_ORIGINS(event) ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0); assert(ret == 0); assert(event.events == 0); assert(event.data.fd == 0); ASSERT_ZERO_LABEL(ret); ASSERT_READ_LABEL(&event, sizeof(event), i_label); + ASSERT_SAVED_ORIGINS(event) // Test epoll_wait when an event occurs. write(pipe_fds[1], "x", 1); @@ -798,6 +1225,7 @@ void test_epoll_wait() { assert(event.data.fd == pipe_fds[0]); ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&event, sizeof(event)); + ASSERT_SAVED_ORIGINS(event) // Clean up. close(epfd); @@ -810,8 +1238,11 @@ void test_poll() { fd.fd = 0; fd.events = POLLIN; dfsan_set_label(i_label, &fd.revents, sizeof(fd.revents)); + DEFINE_AND_SAVE_ORIGINS(fd) int ret = poll(&fd, 1, 1); + ASSERT_ZERO_LABEL(ret); ASSERT_ZERO_LABEL(fd.revents); + ASSERT_SAVED_ORIGINS(fd) assert(ret >= 0); } @@ -822,26 +1253,37 @@ void test_select() { FD_SET(0, &fds); dfsan_set_label(i_label, &fds, sizeof(fds)); dfsan_set_label(j_label, &t, sizeof(t)); + DEFINE_AND_SAVE_ORIGINS(fds) + DEFINE_AND_SAVE_ORIGINS(t) int ret = select(1, &fds, NULL, NULL, &t); assert(ret >= 0); + ASSERT_ZERO_LABEL(ret); ASSERT_ZERO_LABEL(t.tv_sec); ASSERT_READ_ZERO_LABEL(&fds, sizeof(fds)); + ASSERT_SAVED_ORIGINS(fds) + ASSERT_SAVED_ORIGINS(t) } void test_sched_getaffinity() { cpu_set_t mask; dfsan_set_label(j_label, &mask, 1); + DEFINE_AND_SAVE_ORIGINS(mask) int ret = sched_getaffinity(0, sizeof(mask), &mask); assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&mask, sizeof(mask)); + ASSERT_SAVED_ORIGINS(mask) } void test_sigemptyset() { sigset_t set; dfsan_set_label(j_label, &set, 1); + DEFINE_AND_SAVE_ORIGINS(set) int ret = sigemptyset(&set); assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&set, sizeof(set)); + ASSERT_SAVED_ORIGINS(set) } static void SignalHandler(int signo) {} @@ -856,10 +1298,12 @@ void test_sigaction() { // Set sigaction to be SignalAction, save the last one into origin_act struct sigaction origin_act; dfsan_set_label(j_label, &origin_act, 1); + DEFINE_AND_SAVE_ORIGINS(origin_act) int ret = sigaction(SIGUSR1, &newact_with_sigaction, &origin_act); assert(ret == 0); ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&origin_act, sizeof(origin_act)); + ASSERT_SAVED_ORIGINS(origin_act) struct sigaction newact_with_sighandler = {}; newact_with_sighandler.sa_handler = SignalHandler; @@ -904,10 +1348,12 @@ void test_signal() { void test_sigaltstack() { stack_t old_altstack = {}; dfsan_set_label(j_label, &old_altstack, sizeof(old_altstack)); + DEFINE_AND_SAVE_ORIGINS(old_altstack) int ret = sigaltstack(NULL, &old_altstack); assert(ret == 0); ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&old_altstack, sizeof(old_altstack)); + ASSERT_SAVED_ORIGINS(old_altstack) } void test_gettimeofday() { @@ -915,10 +1361,14 @@ void test_gettimeofday() { struct timezone tz; dfsan_set_label(i_label, &tv, sizeof(tv)); dfsan_set_label(j_label, &tz, sizeof(tz)); + DEFINE_AND_SAVE_ORIGINS(tv) + DEFINE_AND_SAVE_ORIGINS(tz) int ret = gettimeofday(&tv, &tz); assert(ret == 0); ASSERT_READ_ZERO_LABEL(&tv, sizeof(tv)); ASSERT_READ_ZERO_LABEL(&tz, sizeof(tz)); + ASSERT_SAVED_ORIGINS(tv) + ASSERT_SAVED_ORIGINS(tz) } void *pthread_create_test_cb(void *p) { @@ -929,14 +1379,18 @@ void *pthread_create_test_cb(void *p) { void test_pthread_create() { pthread_t pt; - pthread_create(&pt, 0, pthread_create_test_cb, (void *)1); + int create_ret = pthread_create(&pt, 0, pthread_create_test_cb, (void *)1); + assert(create_ret == 0); + ASSERT_ZERO_LABEL(create_ret); void *cbrv; dfsan_set_label(i_label, &cbrv, sizeof(cbrv)); - int ret = pthread_join(pt, &cbrv); - assert(ret == 0); + DEFINE_AND_SAVE_ORIGINS(cbrv) + int joint_ret = pthread_join(pt, &cbrv); + assert(joint_ret == 0); assert(cbrv == (void *)2); - ASSERT_ZERO_LABEL(ret); + ASSERT_ZERO_LABEL(joint_ret); ASSERT_ZERO_LABEL(cbrv); + ASSERT_SAVED_ORIGINS(cbrv); } // Tested by test_pthread_create(). This empty function is here to appease the @@ -967,35 +1421,91 @@ void test__dl_get_tls_static_info() { size_t sizep = 0, alignp = 0; dfsan_set_label(i_label, &sizep, sizeof(sizep)); dfsan_set_label(i_label, &alignp, sizeof(alignp)); + dfsan_origin sizep_o = dfsan_get_origin(sizep); + dfsan_origin alignp_o = dfsan_get_origin(alignp); _dl_get_tls_static_info(&sizep, &alignp); ASSERT_ZERO_LABEL(sizep); ASSERT_ZERO_LABEL(alignp); + ASSERT_ORIGIN(sizep, sizep_o); + ASSERT_ORIGIN(alignp, alignp_o); } void test_strrchr() { char str1[] = "str1str1"; + + char *p = str1; + dfsan_set_label(j_label, &p, sizeof(p)); + + char *rv = strrchr(p, 'r'); + assert(rv == &str1[6]); + ASSERT_LABEL(rv, j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p); + + char c = 'r'; + dfsan_set_label(k_label, &c, sizeof(c)); + rv = strrchr(str1, c); + assert(rv == &str1[6]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, k_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, c); +#endif + dfsan_set_label(i_label, &str1[7], 1); - char *rv = strrchr(str1, 'r'); + rv = strrchr(str1, 'r'); assert(rv == &str1[6]); #ifdef STRICT_DATA_DEPENDENCIES ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[7]); #endif } void test_strstr() { char str1[] = "str1str1"; + + char *p1 = str1; + dfsan_set_label(k_label, &p1, sizeof(p1)); + char *rv = strstr(p1, "1s"); + assert(rv == &str1[3]); + ASSERT_LABEL(rv, k_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p1); + + char str2[] = "1s"; + char *p2 = str2; + dfsan_set_label(m_label, &p2, sizeof(p2)); + rv = strstr(str1, p2); + assert(rv == &str1[3]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, m_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p2); +#endif + + dfsan_set_label(n_label, &str2[0], 1); + rv = strstr(str1, str2); + assert(rv == &str1[3]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, n_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str2[0]); +#endif + dfsan_set_label(i_label, &str1[3], 1); dfsan_set_label(j_label, &str1[5], 1); - char *rv = strstr(str1, "1s"); + rv = strstr(str1, "1s"); assert(rv == &str1[3]); #ifdef STRICT_DATA_DEPENDENCIES ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]); #endif rv = strstr(str1, "2s"); @@ -1004,21 +1514,50 @@ void test_strstr() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]); #endif } void test_strpbrk() { char s[] = "abcdefg"; char accept[] = "123fd"; + + char *p_s = s; + char *p_accept = accept; + + dfsan_set_label(n_label, &p_accept, sizeof(p_accept)); + + char *rv = strpbrk(p_s, p_accept); + assert(rv == &s[3]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, n_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_accept); +#endif + + dfsan_set_label(m_label, &p_s, sizeof(p_s)); + + rv = strpbrk(p_s, p_accept); + assert(rv == &s[3]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_LABEL(rv, m_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s); +#else + ASSERT_LABEL(rv, dfsan_union(m_label, n_label)); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s); +#endif + dfsan_set_label(i_label, &s[5], 1); dfsan_set_label(j_label, &accept[1], 1); - char *rv = strpbrk(s, accept); + rv = strpbrk(s, accept); assert(rv == &s[3]); #ifdef STRICT_DATA_DEPENDENCIES ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, accept[1]); #endif char *ps = s; @@ -1030,6 +1569,7 @@ void test_strpbrk() { ASSERT_LABEL(rv, j_label); #else ASSERT_LABEL(rv, i_j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]); #endif rv = strpbrk(ps, "123"); @@ -1038,6 +1578,7 @@ void test_strpbrk() { ASSERT_ZERO_LABEL(rv); #else ASSERT_LABEL(rv, i_j_label); + ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]); #endif } @@ -1050,12 +1591,31 @@ void test_memchr() { assert(crv == &str1[2]); ASSERT_ZERO_LABEL(crv); + char c = 'r'; + dfsan_set_label(k_label, &c, sizeof(c)); + crv = (char *)memchr(str1, c, sizeof(str1)); + assert(crv == &str1[2]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(crv); +#else + ASSERT_LABEL(crv, k_label); + ASSERT_EQ_ORIGIN(crv, c); +#endif + + char *ptr = str1; + dfsan_set_label(k_label, &ptr, sizeof(ptr)); + crv = (char *)memchr(ptr, 'r', sizeof(str1)); + assert(crv == &str1[2]); + ASSERT_LABEL(crv, k_label); + ASSERT_EQ_ORIGIN(crv, ptr); + crv = (char *) memchr(str1, '1', sizeof(str1)); assert(crv == &str1[3]); #ifdef STRICT_DATA_DEPENDENCIES ASSERT_ZERO_LABEL(crv); #else ASSERT_LABEL(crv, i_label); + ASSERT_EQ_ORIGIN(crv, str1[3]); #endif crv = (char *) memchr(str1, 'x', sizeof(str1)); @@ -1064,6 +1624,7 @@ void test_memchr() { ASSERT_ZERO_LABEL(crv); #else ASSERT_LABEL(crv, i_j_label); + ASSERT_EQ_ORIGIN(crv, str1[3]); #endif } @@ -1076,12 +1637,14 @@ void test_nanosleep() { req.tv_sec = 1; req.tv_nsec = 0; dfsan_set_label(i_label, &rem, sizeof(rem)); + DEFINE_AND_SAVE_ORIGINS(rem) // non interrupted int rv = nanosleep(&req, &rem); assert(rv == 0); ASSERT_ZERO_LABEL(rv); ASSERT_READ_LABEL(&rem, 1, i_label); + ASSERT_SAVED_ORIGINS(rem) // interrupted by an alarm signal(SIGALRM, alarm_handler); @@ -1091,16 +1654,22 @@ void test_nanosleep() { assert(rv == -1); ASSERT_ZERO_LABEL(rv); ASSERT_READ_ZERO_LABEL(&rem, sizeof(rem)); + ASSERT_SAVED_ORIGINS(rem) } void test_socketpair() { int fd[2]; + dfsan_origin fd_o[2]; dfsan_set_label(i_label, fd, sizeof(fd)); + fd_o[0] = dfsan_get_origin((long)(fd[0])); + fd_o[1] = dfsan_get_origin((long)(fd[1])); int rv = socketpair(PF_LOCAL, SOCK_STREAM, 0, fd); assert(rv == 0); ASSERT_ZERO_LABEL(rv); ASSERT_READ_ZERO_LABEL(fd, sizeof(fd)); + ASSERT_ORIGIN(fd[0], fd_o[0]); + ASSERT_ORIGIN(fd[1], fd_o[1]); } void test_getpeername() { @@ -1112,6 +1681,8 @@ void test_getpeername() { socklen_t addrlen = sizeof(addr); dfsan_set_label(i_label, &addr, addrlen); dfsan_set_label(i_label, &addrlen, sizeof(addrlen)); + DEFINE_AND_SAVE_ORIGINS(addr) + DEFINE_AND_SAVE_ORIGINS(addrlen) ret = getpeername(sockfds[0], &addr, &addrlen); assert(ret != -1); @@ -1120,6 +1691,8 @@ void test_getpeername() { assert(addrlen < sizeof(addr)); ASSERT_READ_ZERO_LABEL(&addr, addrlen); ASSERT_READ_LABEL(((char *)&addr) + addrlen, 1, i_label); + ASSERT_SAVED_ORIGINS(addr) + ASSERT_SAVED_ORIGINS(addrlen) close(sockfds[0]); close(sockfds[1]); @@ -1133,7 +1706,8 @@ void test_getsockname() { socklen_t addrlen = sizeof(addr); dfsan_set_label(i_label, &addr, addrlen); dfsan_set_label(i_label, &addrlen, sizeof(addrlen)); - + DEFINE_AND_SAVE_ORIGINS(addr) + DEFINE_AND_SAVE_ORIGINS(addrlen) int ret = getsockname(sockfd, &addr, &addrlen); assert(ret != -1); ASSERT_ZERO_LABEL(ret); @@ -1141,6 +1715,8 @@ void test_getsockname() { assert(addrlen < sizeof(addr)); ASSERT_READ_ZERO_LABEL(&addr, addrlen); ASSERT_READ_LABEL(((char *)&addr) + addrlen, 1, i_label); + ASSERT_SAVED_ORIGINS(addr) + ASSERT_SAVED_ORIGINS(addrlen) close(sockfd); } @@ -1153,6 +1729,8 @@ void test_getsockopt() { socklen_t optlen = sizeof(optval); dfsan_set_label(i_label, &optval, sizeof(optval)); dfsan_set_label(i_label, &optlen, sizeof(optlen)); + DEFINE_AND_SAVE_ORIGINS(optval) + DEFINE_AND_SAVE_ORIGINS(optlen) int ret = getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen); assert(ret != -1); assert(optlen == sizeof(int)); @@ -1162,6 +1740,8 @@ void test_getsockopt() { ASSERT_ZERO_LABEL(optlen); ASSERT_ZERO_LABEL(optval[0]); ASSERT_LABEL(optval[1], i_label); + ASSERT_SAVED_ORIGINS(optval) + ASSERT_SAVED_ORIGINS(optlen) close(sockfd); } @@ -1212,10 +1792,12 @@ void test_sprintf_chunk(const char* expected, const char* format, T arg) { // Labelled arg. dfsan_set_label(i_label, &arg, sizeof(arg)); + dfsan_origin a_o = dfsan_get_origin((long)(arg)); assert(sprintf(buf, padded_format, arg) == strlen(padded_expected)); assert(strcmp(buf, padded_expected) == 0); ASSERT_READ_LABEL(buf, 4, 0); ASSERT_READ_LABEL(buf + 4, strlen(padded_expected) - 8, i_label); + ASSERT_INIT_ORIGINS(buf + 4, strlen(padded_expected) - 8, a_o); ASSERT_READ_LABEL(buf + (strlen(padded_expected) - 4), 4, 0); } @@ -1239,8 +1821,11 @@ void test_sprintf() { int m = 8; int d = 27; dfsan_set_label(k_label, (void *) (s + 1), 2); + dfsan_origin s_o = dfsan_get_origin((long)(s[1])); dfsan_set_label(i_label, &m, sizeof(m)); + dfsan_origin m_o = dfsan_get_origin((long)m); dfsan_set_label(j_label, &d, sizeof(d)); + dfsan_origin d_o = dfsan_get_origin((long)d); int n; int r = sprintf(buf, "hello %s, %-d/%d/%d %f %% %n%d", s, 2014, m, d, 12345.6781234, &n, 1000); @@ -1248,10 +1833,13 @@ void test_sprintf() { assert(strcmp(buf, "hello world, 2014/8/27 12345.678123 % 1000") == 0); ASSERT_READ_LABEL(buf, 7, 0); ASSERT_READ_LABEL(buf + 7, 2, k_label); + ASSERT_INIT_ORIGINS(buf + 7, 2, s_o); ASSERT_READ_LABEL(buf + 9, 9, 0); ASSERT_READ_LABEL(buf + 18, 1, i_label); + ASSERT_INIT_ORIGINS(buf + 18, 1, m_o); ASSERT_READ_LABEL(buf + 19, 1, 0); ASSERT_READ_LABEL(buf + 20, 2, j_label); + ASSERT_INIT_ORIGINS(buf + 20, 2, d_o); ASSERT_READ_LABEL(buf + 22, 15, 0); ASSERT_LABEL(r, 0); assert(n == 38); @@ -1301,31 +1889,44 @@ void test_snprintf() { int m = 8; int d = 27; dfsan_set_label(k_label, (void *) (s + 1), 2); + dfsan_origin s_o = dfsan_get_origin((long)(s[1])); dfsan_set_label(i_label, &y, sizeof(y)); + dfsan_origin y_o = dfsan_get_origin((long)y); dfsan_set_label(j_label, &m, sizeof(m)); - int r = snprintf(buf, 19, "hello %s, %-d/%d/%d %f", s, y, m, d, + dfsan_origin m_o = dfsan_get_origin((long)m); + int r = snprintf(buf, 19, "hello %s, %-d/ %d/%d %f", s, y, m, d, 12345.6781234); // The return value is the number of bytes that would have been written to // the final string if enough space had been available. - assert(r == 35); + assert(r == 38); assert(memcmp(buf, "hello world, 2014/", 19) == 0); ASSERT_READ_LABEL(buf, 7, 0); ASSERT_READ_LABEL(buf + 7, 2, k_label); + ASSERT_INIT_ORIGINS(buf + 7, 2, s_o); ASSERT_READ_LABEL(buf + 9, 4, 0); ASSERT_READ_LABEL(buf + 13, 4, i_label); + ASSERT_INIT_ORIGINS(buf + 13, 4, y_o); ASSERT_READ_LABEL(buf + 17, 2, 0); ASSERT_LABEL(r, 0); } +// Tested by a seperate source file. This empty function is here to appease the +// check-wrappers script. +void test_fork() {} + int main(void) { #ifdef FAST_16_LABELS i_label = 1; j_label = 2; k_label = 4; + m_label = 8; + n_label = 16; #else i_label = dfsan_create_label("i", 0); j_label = dfsan_create_label("j", 0); k_label = dfsan_create_label("k", 0); + m_label = dfsan_create_label("m", 0); + n_label = dfsan_create_label("n", 0); #endif i_j_label = dfsan_union(i_label, j_label); assert(i_j_label != i_label); @@ -1342,6 +1943,7 @@ int main(void) { test_dlopen(); test_epoll_wait(); test_fgets(); + test_fork(); test_fstat(); test_get_current_dir_name(); test_getcwd(); diff --git a/compiler-rt/test/dfsan/flush.c b/compiler-rt/test/dfsan/flush.c index a6d5fe696258..3986eb26a622 100644 --- a/compiler-rt/test/dfsan/flush.c +++ b/compiler-rt/test/dfsan/flush.c @@ -1,5 +1,9 @@ // Tests dfsan_flush(). // RUN: %clang_dfsan %s -o %t && %run %t +// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t +// +// REQUIRES: x86_64-target-arch + #include #include #include @@ -17,12 +21,20 @@ int main() { assert(dfsan_get_label(global) == 10); assert(dfsan_get_label(local) == 20); assert(dfsan_get_label(*heap) == 30); +#ifdef ORIGIN_TRACKING + assert(dfsan_get_origin(global)); + assert(dfsan_get_origin(local)); + assert(dfsan_get_origin(*heap)); +#endif dfsan_flush(); assert(dfsan_get_label(global) == 0); assert(dfsan_get_label(local) == 0); assert(dfsan_get_label(*heap) == 0); + assert(dfsan_get_origin(global) == 0); + assert(dfsan_get_origin(local) == 0); + assert(dfsan_get_origin(*heap) == 0); free(heap); } diff --git a/compiler-rt/test/dfsan/fork.cpp b/compiler-rt/test/dfsan/fork.cpp new file mode 100644 index 000000000000..cd9b641eefc3 --- /dev/null +++ b/compiler-rt/test/dfsan/fork.cpp @@ -0,0 +1,107 @@ +// Test that chained origins are fork-safe. +// Run a number of threads that create new chained origins, then fork +// and verify that origin reads do not deadlock in the child process. +// +// RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s +// +// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t +// RUN: DFSAN_OPTIONS=store_context_size=1000,origin_history_size=0,origin_history_per_stack_limit=0 %run %t 2>&1 | FileCheck %s +// +// REQUIRES: x86_64-target-arch + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int done; + +void copy_labels_thread2() { + volatile int x = 0; + volatile int v = 0; + dfsan_set_label(8, (void *)&x, sizeof(x)); + while (true) { + v = x; + x = v; + if (__atomic_load_n(&done, __ATOMIC_RELAXED)) + return; + } +} + +void copy_labels_thread1(int level) { + if (!level) + copy_labels_thread2(); + else + copy_labels_thread1(level - 1); +} + +void *copy_labels_thread(void *id) { + copy_labels_thread1((long)id); + return 0; +} + +// Run through stackdepot in the child process. +// If any of the hash table cells are locked, this may deadlock. +void child() { + volatile int x = 0; + volatile int v = 0; + dfsan_set_label(16, (void *)&x, sizeof(x)); + for (int i = 0; i < 10000; ++i) { + v = x; + x = v; + } + write(2, "done\n", 5); +} + +void test() { + const int kThreads = 10; + pthread_t t[kThreads]; + for (int i = 0; i < kThreads; ++i) + pthread_create(&t[i], NULL, copy_labels_thread, (void *)(long)i); + usleep(100000); + pid_t pid = fork(); + if (pid) { + // parent + __atomic_store_n(&done, 1, __ATOMIC_RELAXED); + pid_t p; + while ((p = wait(NULL)) == -1) { + } + } else { + // child + child(); + } +} + +int main() { + const int kChildren = 20; + for (int i = 0; i < kChildren; ++i) { + pid_t pid = fork(); + assert(dfsan_get_label(pid) == 0); + if (pid) { + // parent + } else { + test(); + exit(0); + } + } + + for (int i = 0; i < kChildren; ++i) { + pid_t p; + while ((p = wait(NULL)) == -1) { + } + } + + return 0; +} + +// Expect 20 (== kChildren) "done" messages. +// CHECK-COUNT-20: done diff --git a/compiler-rt/test/dfsan/origin_add_label.c b/compiler-rt/test/dfsan/origin_add_label.c index 0d1920a7ce12..baf40edc9a77 100644 --- a/compiler-rt/test/dfsan/origin_add_label.c +++ b/compiler-rt/test/dfsan/origin_add_label.c @@ -1,10 +1,12 @@ // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out - +// // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_branch.c b/compiler-rt/test/dfsan/origin_branch.c new file mode 100644 index 000000000000..3c7e5b62e3ba --- /dev/null +++ b/compiler-rt/test/dfsan/origin_branch.c @@ -0,0 +1,29 @@ +// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK < %t.out +// +// REQUIRES: x86_64-target-arch + +#include + +__attribute__((noinline)) uint64_t foo(uint64_t x, uint64_t y) { return x + y; } + +int main(int argc, char *argv[]) { + uint64_t a = 10; + uint64_t b = 20; + dfsan_set_label(8, &a, sizeof(a)); + uint64_t c = foo(a, b); + for (int i = 0; i < argc; ++i) + c += foo(c, b); + dfsan_print_origin_trace(&c, NULL); +} + +// CHECK: Taint value 0x8 {{.*}} origin tracking () +// CHECK: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK: #0 {{.*}} in main {{.*}}origin_branch.c:[[@LINE-6]] + +// CHECK: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK: #0 {{.*}} in main {{.*}}origin_branch.c:[[@LINE-11]] + +// CHECK: Origin value: {{.*}}, Taint value was created at +// CHECK: #0 {{.*}} in main {{.*}}origin_branch.c:[[@LINE-15]] diff --git a/compiler-rt/test/dfsan/origin_disabled.c b/compiler-rt/test/dfsan/origin_disabled.c index e1a8b48ce063..44c5e663d4a4 100644 --- a/compiler-rt/test/dfsan/origin_disabled.c +++ b/compiler-rt/test/dfsan/origin_disabled.c @@ -1,6 +1,8 @@ // RUN: %clang_dfsan -gmlt -mllvm -dfsan-fast-16-labels=true %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_invalid.c b/compiler-rt/test/dfsan/origin_invalid.c index fac015f54df0..d391e92560f1 100644 --- a/compiler-rt/test/dfsan/origin_invalid.c +++ b/compiler-rt/test/dfsan/origin_invalid.c @@ -1,6 +1,8 @@ // RUN: %clang_dfsan -gmlt -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-track-origins=1 %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_ld_lost.c b/compiler-rt/test/dfsan/origin_ld_lost.c index 384cbad782dd..37fcd6c1c1a4 100644 --- a/compiler-rt/test/dfsan/origin_ld_lost.c +++ b/compiler-rt/test/dfsan/origin_ld_lost.c @@ -2,6 +2,8 @@ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out // +// REQUIRES: x86_64-target-arch +// // Test origin tracking can lost origins at 2-byte load with addr % 4 == 3. #include diff --git a/compiler-rt/test/dfsan/origin_ldst.c b/compiler-rt/test/dfsan/origin_ldst.c index 6cf4d8545850..2e4eca18596d 100644 --- a/compiler-rt/test/dfsan/origin_ldst.c +++ b/compiler-rt/test/dfsan/origin_ldst.c @@ -22,6 +22,8 @@ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out // +// REQUIRES: x86_64-target-arch +// // Test origin tracking is accurate in terms of partial store/load, and // different aligments. Do not test alignments that are not power of 2. // Compilers do not always allow this. diff --git a/compiler-rt/test/dfsan/origin_limit.c b/compiler-rt/test/dfsan/origin_limit.c index 4f14363df957..71920d878e47 100644 --- a/compiler-rt/test/dfsan/origin_limit.c +++ b/compiler-rt/test/dfsan/origin_limit.c @@ -8,6 +8,8 @@ // // RUN: DFSAN_OPTIONS=origin_history_size=0 %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK0 < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_memcpy.c b/compiler-rt/test/dfsan/origin_memcpy.c new file mode 100644 index 000000000000..34edf9d4554a --- /dev/null +++ b/compiler-rt/test/dfsan/origin_memcpy.c @@ -0,0 +1,69 @@ +// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK0 < %t.out +// +// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK10 < %t.out +// +// REQUIRES: x86_64-target-arch + +#include + +#include + +int xx[10000]; +int yy[10000]; +volatile int idx = 30; + +__attribute__((noinline)) +void fn_g(int a, int b) { + xx[idx] = a; xx[idx + 10] = b; +} + +__attribute__((noinline)) +void fn_f(int a, int b) { + fn_g(a, b); +} + +__attribute__((noinline)) +void fn_h() { + memcpy(&yy, &xx, sizeof(xx)); +} + +int main(int argc, char *argv[]) { + int volatile z1 = 0; + int volatile z2 = 0; + dfsan_set_label(8, (void *)&z1, sizeof(z1)); + dfsan_set_label(16, (void *)&z2, sizeof(z2)); + fn_f(z1, z2); + fn_h(); + dfsan_print_origin_trace(&yy[idx + OFFSET], NULL); + return 0; +} + +// CHECK0: Taint value 0x8 {{.*}} origin tracking () +// CHECK0: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK0: #0 {{.*}} in dfs$fn_h {{.*}}origin_memcpy.c:[[@LINE-16]] +// CHECK0: #1 {{.*}} in main {{.*}}origin_memcpy.c:[[@LINE-8]] + +// CHECK0: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK0: #0 {{.*}} in dfs$fn_g {{.*}}origin_memcpy.c:[[@LINE-30]] +// CHECK0: #1 {{.*}} in dfs$fn_f {{.*}}origin_memcpy.c:[[@LINE-26]] +// CHECK0: #2 {{.*}} in main {{.*}}origin_memcpy.c:[[@LINE-14]] + +// CHECK0: Origin value: {{.*}}, Taint value was created at +// CHECK0: #0 {{.*}} in main {{.*}}origin_memcpy.c:[[@LINE-19]] + +// CHECK10: Taint value 0x10 {{.*}} origin tracking () +// CHECK10: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK10: #0 {{.*}} in dfs$fn_h {{.*}}origin_memcpy.c:[[@LINE-29]] +// CHECK10: #1 {{.*}} in main {{.*}}origin_memcpy.c:[[@LINE-21]] + +// CHECK10: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK10: #0 {{.*}} in dfs$fn_g {{.*}}origin_memcpy.c:[[@LINE-43]] +// CHECK10: #1 {{.*}} in dfs$fn_f {{.*}}origin_memcpy.c:[[@LINE-39]] +// CHECK10: #2 {{.*}} in main {{.*}}origin_memcpy.c:[[@LINE-27]] + +// CHECK10: Origin value: {{.*}}, Taint value was created at +// CHECK10: #0 {{.*}} in main {{.*}}origin_memcpy.c:[[@LINE-31]] diff --git a/compiler-rt/test/dfsan/origin_memmove.c b/compiler-rt/test/dfsan/origin_memmove.c new file mode 100644 index 000000000000..fee04569ce9d --- /dev/null +++ b/compiler-rt/test/dfsan/origin_memmove.c @@ -0,0 +1,69 @@ +// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK0 < %t.out +// +// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK10 < %t.out +// +// REQUIRES: x86_64-target-arch + +#include + +#include + +int xx[10000]; + +volatile int idx = 30; + +__attribute__((noinline)) +void fn_g(int a, int b) { + xx[idx] = a; xx[idx + 10] = b; +} + +__attribute__((noinline)) +void fn_f(int a, int b) { + fn_g(a, b); +} + +__attribute__((noinline)) +void fn_h() { + memmove(&xx[24], &xx, 7500); +} + +int main(int argc, char *argv[]) { + int volatile z1 = 0; + int volatile z2 = 0; + dfsan_set_label(8, (void *)&z1, sizeof(z1)); + dfsan_set_label(16, (void *)&z2, sizeof(z2)); + fn_f(z1, z2); + fn_h(); + dfsan_print_origin_trace(&xx[24 + idx + OFFSET], NULL); + return 0; +} + +// CHECK0: Taint value 0x8 {{.*}} origin tracking () +// CHECK0: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK0: #0 {{.*}} in dfs$fn_h {{.*}}origin_memmove.c:[[@LINE-16]] +// CHECK0: #1 {{.*}} in main {{.*}}origin_memmove.c:[[@LINE-8]] + +// CHECK0: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK0: #0 {{.*}} in dfs$fn_g {{.*}}origin_memmove.c:[[@LINE-30]] +// CHECK0: #1 {{.*}} in dfs$fn_f {{.*}}origin_memmove.c:[[@LINE-26]] +// CHECK0: #2 {{.*}} in main {{.*}}origin_memmove.c:[[@LINE-14]] + +// CHECK0: Origin value: {{.*}}, Taint value was created at +// CHECK0: #0 {{.*}} in main {{.*}}origin_memmove.c:[[@LINE-19]] + +// CHECK10: Taint value 0x10 {{.*}} origin tracking () +// CHECK10: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK10: #0 {{.*}} in dfs$fn_h {{.*}}origin_memmove.c:[[@LINE-29]] +// CHECK10: #1 {{.*}} in main {{.*}}origin_memmove.c:[[@LINE-21]] + +// CHECK10: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK10: #0 {{.*}} in dfs$fn_g {{.*}}origin_memmove.c:[[@LINE-43]] +// CHECK10: #1 {{.*}} in dfs$fn_f {{.*}}origin_memmove.c:[[@LINE-39]] +// CHECK10: #2 {{.*}} in main {{.*}}origin_memmove.c:[[@LINE-27]] + +// CHECK10: Origin value: {{.*}}, Taint value was created at +// CHECK10: #0 {{.*}} in main {{.*}}origin_memmove.c:[[@LINE-31]] diff --git a/compiler-rt/test/dfsan/origin_memset.c b/compiler-rt/test/dfsan/origin_memset.c index afc9855e04d6..21b384188057 100644 --- a/compiler-rt/test/dfsan/origin_memset.c +++ b/compiler-rt/test/dfsan/origin_memset.c @@ -1,10 +1,12 @@ // RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK0 < %t.out - +// // RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK10 < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_overlapped.c b/compiler-rt/test/dfsan/origin_overlapped.c index 98b4d5073376..33bd0ec9cb1a 100644 --- a/compiler-rt/test/dfsan/origin_overlapped.c +++ b/compiler-rt/test/dfsan/origin_overlapped.c @@ -1,6 +1,8 @@ // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_set_label.c b/compiler-rt/test/dfsan/origin_set_label.c index 41617e7df147..d6a5d264772e 100644 --- a/compiler-rt/test/dfsan/origin_set_label.c +++ b/compiler-rt/test/dfsan/origin_set_label.c @@ -1,10 +1,12 @@ // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out - +// // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_unaligned_memtrans.c b/compiler-rt/test/dfsan/origin_unaligned_memtrans.c new file mode 100644 index 000000000000..fa3db7c32fc7 --- /dev/null +++ b/compiler-rt/test/dfsan/origin_unaligned_memtrans.c @@ -0,0 +1,80 @@ +// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK0 < %t.out +// +// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK10 < %t.out +// +// REQUIRES: x86_64-target-arch + +#include + +#include + +char xx[10000]; +char yy[10000]; +volatile int idx = 30; + +__attribute__((noinline)) void fn_g(char a, char b) { + xx[idx] = a; xx[idx + 10] = b; +} + +__attribute__((noinline)) void fn_f(char a, char b) { + fn_g(a, b); +} + +__attribute__((noinline)) void fn_h() { + memcpy(&yy[2], &xx[2], sizeof(xx) - 4); +} + +__attribute__((noinline)) void fn_i() { + memmove(&yy[25], &yy, 7500); +} + +int main(int argc, char *argv[]) { + char volatile z1 = 0; + int volatile buffer = 0; + char volatile z2 = 0; + dfsan_set_label(8, (void *)&z1, sizeof(z1)); + dfsan_set_label(16, (void *)&z2, sizeof(z2)); + fn_f(z1, z2); + fn_h(); + fn_i(); + dfsan_print_origin_trace(&yy[25 + idx + OFFSET], NULL); + return 0; +} + +// CHECK0: Taint value 0x8 {{.*}} origin tracking () +// CHECK0: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK0: #0 {{.*}} in dfs$fn_i {{.*}}origin_unaligned_memtrans.c:[[@LINE-18]] +// CHECK0: #1 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-8]] + +// CHECK0: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK0: #0 {{.*}} in dfs$fn_h {{.*}}origin_unaligned_memtrans.c:[[@LINE-26]] +// CHECK0: #1 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-13]] + +// CHECK0: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK0: #0 {{.*}} in dfs$fn_g {{.*}}origin_unaligned_memtrans.c:[[@LINE-38]] +// CHECK0: #1 {{.*}} in dfs$fn_f {{.*}}origin_unaligned_memtrans.c:[[@LINE-35]] +// CHECK0: #2 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-19]] + +// CHECK0: Origin value: {{.*}}, Taint value was created at +// CHECK0: #0 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-24]] + +// CHECK10: Taint value 0x10 {{.*}} origin tracking +// CHECK10: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK10: #0 {{.*}} in dfs$fn_i {{.*}}origin_unaligned_memtrans.c:[[@LINE-35]] +// CHECK10: #1 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-25]] + +// CHECK10: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK10: #0 {{.*}} in dfs$fn_h {{.*}}origin_unaligned_memtrans.c:[[@LINE-43]] +// CHECK10: #1 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-30]] + +// CHECK10: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK10: #0 {{.*}} in dfs$fn_g {{.*}}origin_unaligned_memtrans.c:[[@LINE-55]] +// CHECK10: #1 {{.*}} in dfs$fn_f {{.*}}origin_unaligned_memtrans.c:[[@LINE-52]] +// CHECK10: #2 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-36]] + +// CHECK10: Origin value: {{.*}}, Taint value was created at +// CHECK10: #0 {{.*}} in main {{.*}}origin_unaligned_memtrans.c:[[@LINE-40]] diff --git a/compiler-rt/test/dfsan/origin_untainted.c b/compiler-rt/test/dfsan/origin_untainted.c index 6404618a20c1..d51ab1bd1e05 100644 --- a/compiler-rt/test/dfsan/origin_untainted.c +++ b/compiler-rt/test/dfsan/origin_untainted.c @@ -1,6 +1,8 @@ // RUN: %clang_dfsan -gmlt -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-track-origins=1 %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK < %t.out +// +// REQUIRES: x86_64-target-arch #include diff --git a/compiler-rt/test/dfsan/origin_with_sigactions.c b/compiler-rt/test/dfsan/origin_with_sigactions.c new file mode 100644 index 000000000000..3f7986dd540e --- /dev/null +++ b/compiler-rt/test/dfsan/origin_with_sigactions.c @@ -0,0 +1,79 @@ +// Check that stores in signal handlers are not recorded in origin history. +// +// Origin tracking uses ChainedOriginDepot that is not async signal safe, so we +// do not track origins inside signal handlers. +// +// RUN: %clang_dfsan -gmlt -DUSE_SIGNAL_ACTION -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// RUN: %clang_dfsan -gmlt -DUSE_SIGNAL_ACTION -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// RUN: %clang_dfsan -gmlt -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// REQUIRES: x86_64-target-arch + +#include + +#include +#include +#include +#include +#include + +int x, y, u; + +void CopyXtoYtoU() { + y = x; + memcpy(&u, &y, sizeof(int)); +} + +void SignalHandler(int signo) { + CopyXtoYtoU(); +} + +void SignalAction(int signo, siginfo_t *si, void *uc) { + CopyXtoYtoU(); +} + +int main(int argc, char *argv[]) { + int z = 1; + dfsan_set_label(8, &z, sizeof(z)); + x = z; + + struct sigaction psa = {}; +#ifdef USE_SIGNAL_ACTION + psa.sa_flags = SA_SIGINFO; + psa.sa_sigaction = SignalAction; +#else + psa.sa_flags = 0; + psa.sa_handler = SignalHandler; +#endif + sigaction(SIGHUP, &psa, NULL); + kill(getpid(), SIGHUP); + signal(SIGHUP, SIG_DFL); + + assert(x == 1); + assert(y == 1); + assert(u == 1); + + dfsan_print_origin_trace(&u, NULL); + return 0; +} + +// CHECK: Taint value 0x8 {{.*}} origin tracking () +// CHECK: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK-NOT: {{.*}} in dfs$CopyXtoYtoU {{.*}}origin_with_sigactions.c{{.*}} + +// CHECK: #0 {{.*}} in main {{.*}}origin_with_sigactions.c:[[@LINE-26]] + +// CHECK: Origin value: {{.*}}, Taint value was created at +// CHECK: #0 {{.*}} in main {{.*}}origin_with_sigactions.c:[[@LINE-30]] diff --git a/compiler-rt/test/dfsan/origin_with_signals.cpp b/compiler-rt/test/dfsan/origin_with_signals.cpp new file mode 100644 index 000000000000..d4885563a447 --- /dev/null +++ b/compiler-rt/test/dfsan/origin_with_signals.cpp @@ -0,0 +1,50 @@ +// Check that stores in signal handlers are not recorded in origin history. +// +// Origin tracking uses ChainedOriginDepot that is not async signal safe, so we +// do not track origins inside signal handlers. +// +// RUN: %clangxx_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// RUN: %clangxx_dfsan -gmlt -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// REQUIRES: x86_64-target-arch + +#include + +#include +#include +#include +#include + +int x, y, u; + +void SignalHandler(int signo) { + y = x; + memcpy(&u, &y, sizeof(int)); +} + +int main(int argc, char *argv[]) { + int z = 0; + dfsan_set_label(8, &z, sizeof(z)); + x = z; + + signal(SIGHUP, SignalHandler); + kill(getpid(), SIGHUP); + signal(SIGHUP, SIG_DFL); + + dfsan_print_origin_trace(&u, nullptr); + return 0; +} + +// CHECK: Taint value 0x8 {{.*}} origin tracking () +// CHECK: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK-NOT: {{.*}} in dfs$SignalHandler {{.*}}origin_with_signals.cpp{{.*}} + +// CHECK: #0 {{.*}} in main {{.*}}origin_with_signals.cpp:[[@LINE-14]] + +// CHECK: Origin value: {{.*}}, Taint value was created at +// CHECK: #0 {{.*}} in main {{.*}}origin_with_signals.cpp:[[@LINE-18]] diff --git a/compiler-rt/test/dfsan/pthread.c b/compiler-rt/test/dfsan/pthread.c index 6824cb32c003..75bc4720cea8 100644 --- a/compiler-rt/test/dfsan/pthread.c +++ b/compiler-rt/test/dfsan/pthread.c @@ -1,29 +1,53 @@ // RUN: %clang_dfsan -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t +// +// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \ +// RUN: %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// +// REQUIRES: x86_64-target-arch #include #include #include +#include -int volatile x; -int __thread y; +const int kNumThreads = 24; +int x = 0; +int __thread y, z; static void *ThreadFn(void *a) { y = x; assert(dfsan_get_label(y) == 8); + memcpy(&z, &y, sizeof(y)); + if ((int)a == 7) + dfsan_print_origin_trace(&z, NULL); return 0; } int main(void) { dfsan_set_label(8, &x, sizeof(x)); - const int kNumThreads = 24; pthread_t t[kNumThreads]; - for (size_t i = 0; i < kNumThreads; ++i) { + for (size_t i = 0; i < kNumThreads; ++i) pthread_create(&t[i], 0, ThreadFn, (void *)i); - } - for (size_t i = 0; i < kNumThreads; ++i) { + + for (size_t i = 0; i < kNumThreads; ++i) pthread_join(t[i], 0); - } + return 0; } + +// CHECK: Taint value 0x8 {{.*}} origin tracking () +// CHECK: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK: #0 {{.*}} in dfs$ThreadFn {{.*}}pthread.c:[[@LINE-21]] + +// CHECK: Origin value: {{.*}}, Taint value was stored to memory at +// CHECK: #0 {{.*}} in dfs$ThreadFn {{.*}}pthread.c:[[@LINE-26]] + +// CHECK: Origin value: {{.*}}, Taint value was created at +// CHECK: #0 {{.*}} in main {{.*}}pthread.c:[[@LINE-20]] diff --git a/compiler-rt/test/dfsan/sigaction_stress_test.c b/compiler-rt/test/dfsan/sigaction_stress_test.c index 0748d20972a3..edb45fa5caf4 100644 --- a/compiler-rt/test/dfsan/sigaction_stress_test.c +++ b/compiler-rt/test/dfsan/sigaction_stress_test.c @@ -1,6 +1,10 @@ -// RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true -O0 %s -o %t && %run %t +// RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t +// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t +// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && %run %t // // Test that the state of shadows from a sigaction handler are consistent. +// +// REQUIRES: x86_64-target-arch #include #include @@ -10,7 +14,7 @@ #include const int kSigCnt = 200; -int x; +int x = 0; __attribute__((noinline)) int f(int a) { diff --git a/compiler-rt/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cpp b/compiler-rt/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cpp index 1a1acb2b8833..3d7a4e2ba7a1 100644 --- a/compiler-rt/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cpp +++ b/compiler-rt/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cpp @@ -9,8 +9,6 @@ #include #include -#include "../utils.h" - extern void *aligned_alloc(size_t alignment, size_t size); int main() { @@ -20,7 +18,7 @@ int main() { // CHECK: {{#1 0x.* in main .*aligned_alloc-alignment.cpp:}}[[@LINE-3]] // CHECK: SUMMARY: HWAddressSanitizer: invalid-aligned-alloc-alignment - untag_printf("pointer after failed aligned_alloc: %zd\n", (size_t)p); + printf("pointer after failed aligned_alloc: %zd\n", (size_t)p); // CHECK-NULL: pointer after failed aligned_alloc: 0 return 0; diff --git a/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c b/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c index ce33d45179fe..26babb1addc5 100644 --- a/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c +++ b/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c @@ -8,9 +8,6 @@ // A-NEXT: ---p {{.*}}shadow gap] // A-NEXT: rw-p {{.*}}high shadow] -// B-DAG: rw-p {{.*}}SizeClassAllocator: region data] -// B-DAG: rw-p {{.*}}SizeClassAllocator: region metadata] -// B-DAG: rw-p {{.*}}SizeClassAllocator: freearray] // B-DAG: rw-p {{.*}}SizeClassAllocator: region info] // B-DAG: rw-p {{.*}}LargeMmapAllocator] // B-DAG: rw-p {{.*}}stack depot] @@ -25,7 +22,7 @@ #include #include -#include "../utils.h" +#include "utils.h" void CopyFdToFd(int in_fd, int out_fd) { const size_t kBufSize = 0x10000; @@ -37,7 +34,7 @@ void CopyFdToFd(int in_fd, int out_fd) { } else if (got == 0) { break; } else if (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR) { - untag_fprintf(stderr, "error reading file, errno %d\n", errno); + fprintf(stderr, "error reading file, errno %d\n", errno); abort(); } } diff --git a/compiler-rt/test/hwasan/TestCases/Linux/pvalloc-overflow.cpp b/compiler-rt/test/hwasan/TestCases/Linux/pvalloc-overflow.cpp index 2a203028aef8..8e54ead4133e 100644 --- a/compiler-rt/test/hwasan/TestCases/Linux/pvalloc-overflow.cpp +++ b/compiler-rt/test/hwasan/TestCases/Linux/pvalloc-overflow.cpp @@ -18,8 +18,6 @@ #include #include -#include "../utils.h" - int main(int argc, char *argv[]) { assert(argc == 2); const char *action = argv[1]; @@ -27,15 +25,15 @@ int main(int argc, char *argv[]) { const size_t page_size = sysconf(_SC_PAGESIZE); void *p = nullptr; - if (!untag_strcmp(action, "m1")) { + if (!strcmp(action, "m1")) { p = pvalloc((uintptr_t)-1); - } else if (!untag_strcmp(action, "psm1")) { + } else if (!strcmp(action, "psm1")) { p = pvalloc((uintptr_t)-(page_size - 1)); } else { assert(0); } - untag_fprintf(stderr, "errno: %d\n", errno); + fprintf(stderr, "errno: %d\n", errno); return p != nullptr; } diff --git a/compiler-rt/test/hwasan/TestCases/Linux/release-shadow.c b/compiler-rt/test/hwasan/TestCases/Linux/release-shadow.c index 68237fe1d3f3..948bacb7090d 100644 --- a/compiler-rt/test/hwasan/TestCases/Linux/release-shadow.c +++ b/compiler-rt/test/hwasan/TestCases/Linux/release-shadow.c @@ -12,7 +12,7 @@ #include -#include "../utils.h" +#include "utils.h" const unsigned char kTag = 42; const size_t kNumShadowPages = 256; @@ -38,7 +38,7 @@ size_t current_rss() { char buf[100]; assert(read(statm_fd, &buf, sizeof(buf)) > 0); size_t size, rss; - assert(sscanf(buf, UNTAG("%zu %zu"), &size, &rss) == 2); + assert(sscanf(buf, "%zu %zu", &size, &rss) == 2); close(statm_fd); return rss; @@ -49,20 +49,20 @@ void test_rss_difference(void *p) { size_t rss_before = current_rss(); __hwasan_tag_memory(p, 0, kMapSize); size_t rss_after = current_rss(); - untag_fprintf(stderr, "%zu -> %zu\n", rss_before, rss_after); + fprintf(stderr, "%zu -> %zu\n", rss_before, rss_after); assert(rss_before > rss_after); size_t diff = rss_before - rss_after; - untag_fprintf(stderr, "diff %zu\n", diff); + fprintf(stderr, "diff %zu\n", diff); // Check that the difference is at least close to kNumShadowPages. assert(diff > kNumShadowPages / 4 * 3); } int main() { - untag_fprintf(stderr, "starting rss %zu\n", current_rss()); - untag_fprintf(stderr, "shadow pages: %zu\n", kNumShadowPages); + fprintf(stderr, "starting rss %zu\n", current_rss()); + fprintf(stderr, "shadow pages: %zu\n", kNumShadowPages); void *p = mmap(0, kMapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - untag_fprintf(stderr, "p = %p\n", p); + fprintf(stderr, "p = %p\n", p); test_rss_difference(p); test_rss_difference(p); diff --git a/compiler-rt/test/hwasan/TestCases/Linux/reuse-threads.cpp b/compiler-rt/test/hwasan/TestCases/Linux/reuse-threads.cpp index 590bee36945e..865b7b2a7097 100644 --- a/compiler-rt/test/hwasan/TestCases/Linux/reuse-threads.cpp +++ b/compiler-rt/test/hwasan/TestCases/Linux/reuse-threads.cpp @@ -10,7 +10,7 @@ #include -#include "../utils.h" +#include "utils.h" pthread_barrier_t bar; @@ -37,7 +37,7 @@ void start_stop_threads() { int main() { // Cut off initial threads. // CHECK: === test start === - untag_fprintf(stderr, "=== test start ===\n"); + fprintf(stderr, "=== test start ===\n"); // CHECK: Creating : T{{[0-9]+}} [[A:0x[0-9a-f]+]] stack: // CHECK: Creating : T{{[0-9]+}} [[B:0x[0-9a-f]+]] stack: diff --git a/compiler-rt/test/hwasan/TestCases/Linux/utils.h b/compiler-rt/test/hwasan/TestCases/Linux/utils.h new file mode 100644 index 000000000000..46ece2df5b48 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/Linux/utils.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +#if defined(__x86_64__) +#define UNTAG(x) (x) +#else +#define UNTAG(x) (typeof((x) + 0))(((uintptr_t)(x)) & 0xffffffffffffff) +#endif diff --git a/compiler-rt/test/hwasan/TestCases/Linux/vfork.c b/compiler-rt/test/hwasan/TestCases/Linux/vfork.c index 84e960279673..2b40c2bd1893 100644 --- a/compiler-rt/test/hwasan/TestCases/Linux/vfork.c +++ b/compiler-rt/test/hwasan/TestCases/Linux/vfork.c @@ -3,6 +3,9 @@ // REQUIRES: aarch64-target-arch || x86_64-target-arch +// Aliasing mode does not support stack tagging. +// XFAIL: x86_64 + #include #include #include diff --git a/compiler-rt/test/hwasan/TestCases/Posix/posix_memalign-alignment.cpp b/compiler-rt/test/hwasan/TestCases/Posix/posix_memalign-alignment.cpp index 5224dcb0ab1f..0ccc2ad33886 100644 --- a/compiler-rt/test/hwasan/TestCases/Posix/posix_memalign-alignment.cpp +++ b/compiler-rt/test/hwasan/TestCases/Posix/posix_memalign-alignment.cpp @@ -7,8 +7,6 @@ #include #include -#include "../utils.h" - int main() { void *p = reinterpret_cast(42); int res = posix_memalign(&p, 17, 100); @@ -17,7 +15,7 @@ int main() { // CHECK: {{#1 0x.* in main .*posix_memalign-alignment.cpp:}}[[@LINE-3]] // CHECK: SUMMARY: HWAddressSanitizer: invalid-posix-memalign-alignment - untag_printf("pointer after failed posix_memalign: %zd\n", (size_t)p); + printf("pointer after failed posix_memalign: %zd\n", (size_t)p); // CHECK-NULL: pointer after failed posix_memalign: 42 return 0; diff --git a/compiler-rt/test/hwasan/TestCases/allocator_returns_null.cpp b/compiler-rt/test/hwasan/TestCases/allocator_returns_null.cpp index 11a9615f6f50..e1326c319b57 100644 --- a/compiler-rt/test/hwasan/TestCases/allocator_returns_null.cpp +++ b/compiler-rt/test/hwasan/TestCases/allocator_returns_null.cpp @@ -48,42 +48,40 @@ #include #include -#include "utils.h" - int main(int argc, char **argv) { assert(argc == 2); const char *action = argv[1]; - untag_fprintf(stderr, "%s:\n", action); + fprintf(stderr, "%s:\n", action); static const size_t kMaxAllowedMallocSizePlusOne = (1UL << 40) + 1; void *x = nullptr; - if (!untag_strcmp(action, "malloc")) { + if (!strcmp(action, "malloc")) { x = malloc(kMaxAllowedMallocSizePlusOne); - } else if (!untag_strcmp(action, "calloc")) { + } else if (!strcmp(action, "calloc")) { x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4); - } else if (!untag_strcmp(action, "calloc-overflow")) { + } else if (!strcmp(action, "calloc-overflow")) { volatile size_t kMaxSizeT = std::numeric_limits::max(); size_t kArraySize = 4096; volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; x = calloc(kArraySize, kArraySize2); - } else if (!untag_strcmp(action, "realloc")) { + } else if (!strcmp(action, "realloc")) { x = realloc(0, kMaxAllowedMallocSizePlusOne); - } else if (!untag_strcmp(action, "realloc-after-malloc")) { + } else if (!strcmp(action, "realloc-after-malloc")) { char *t = (char*)malloc(100); *t = 42; x = realloc(t, kMaxAllowedMallocSizePlusOne); assert(*t == 42); free(t); - } else if (!untag_strcmp(action, "new")) { + } else if (!strcmp(action, "new")) { x = operator new(kMaxAllowedMallocSizePlusOne); - } else if (!untag_strcmp(action, "new-nothrow")) { + } else if (!strcmp(action, "new-nothrow")) { x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow); } else { assert(0); } - untag_fprintf(stderr, "errno: %d\n", errno); + fprintf(stderr, "errno: %d\n", errno); free(x); diff --git a/compiler-rt/test/hwasan/TestCases/deep-recursion.c b/compiler-rt/test/hwasan/TestCases/deep-recursion.c index 2fe77a7bdaaf..081becabdbfd 100644 --- a/compiler-rt/test/hwasan/TestCases/deep-recursion.c +++ b/compiler-rt/test/hwasan/TestCases/deep-recursion.c @@ -7,6 +7,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include // At least -O1 is needed for this function to not have a stack frame on // AArch64. diff --git a/compiler-rt/test/hwasan/TestCases/global.c b/compiler-rt/test/hwasan/TestCases/global.c index 7b6bbad3b191..5a1dcb47ad3a 100644 --- a/compiler-rt/test/hwasan/TestCases/global.c +++ b/compiler-rt/test/hwasan/TestCases/global.c @@ -5,6 +5,9 @@ // RUN: not %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LSYM %s // RUN: not %env_hwasan_opts=symbolize=0 %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LNOSYM %s +// Global aliasing is not implemented on x86. +// XFAIL: x86_64 + int x = 1; int main(int argc, char **argv) { diff --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c index 26a07c3b8969..67398141209a 100644 --- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c +++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c @@ -15,8 +15,6 @@ #include #include -#include "utils.h" - static volatile char sink; int main(int argc, char **argv) { @@ -24,9 +22,21 @@ int main(int argc, char **argv) { int offset = argc < 2 ? 40 : atoi(argv[1]); int size = argc < 3 ? 30 : atoi(argv[2]); char * volatile x = (char*)malloc(size); - untag_fprintf(stderr, "base: %p access: %p\n", x, &x[offset]); + fprintf(stderr, "base: %p access: %p\n", x, &x[offset]); sink = x[offset]; +#if defined(__x86_64__) + // Aliasing mode doesn't support the secondary allocator, so we fake a HWASan + // report instead of disabling the entire test. + if (size == 1000000) { + fprintf(stderr, "is a large allocated heap chunk; size: 1003520 offset: %d\n", + offset); + fprintf(stderr, "is located %s of 1000000-byte region\n", + offset == -30 ? "30 bytes to the left" : "0 bytes to the right"); + return -1; + } +#endif + // CHECK40: allocated heap chunk; size: 32 offset: 8 // CHECK40: is located 10 bytes to the right of 30-byte region // diff --git a/compiler-rt/test/hwasan/TestCases/hwasan-print-shadow.cpp b/compiler-rt/test/hwasan/TestCases/hwasan-print-shadow.cpp index fa6330bbcccd..1abe209c10b5 100644 --- a/compiler-rt/test/hwasan/TestCases/hwasan-print-shadow.cpp +++ b/compiler-rt/test/hwasan/TestCases/hwasan-print-shadow.cpp @@ -8,8 +8,7 @@ #include int main() { - char *p = (char *)mmap(nullptr, 4096, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + char *p = (char *)malloc(4096); assert(p); __hwasan_tag_memory(p, 1, 32); @@ -26,4 +25,6 @@ int main() { // CHECK-NEXT: {{.*}}0: 0 // CHECK-NEXT: {{.*}}0: 0 // CHECK-NEXT: {{.*}}0: 4 + + free(p); } diff --git a/compiler-rt/test/hwasan/TestCases/longjmp.c b/compiler-rt/test/hwasan/TestCases/longjmp.c index 8d847b54b275..2e3431ca6abe 100644 --- a/compiler-rt/test/hwasan/TestCases/longjmp.c +++ b/compiler-rt/test/hwasan/TestCases/longjmp.c @@ -3,6 +3,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include #include diff --git a/compiler-rt/test/hwasan/TestCases/malloc_fill.cpp b/compiler-rt/test/hwasan/TestCases/malloc_fill.cpp index 27e28c700071..c2debfb88d63 100644 --- a/compiler-rt/test/hwasan/TestCases/malloc_fill.cpp +++ b/compiler-rt/test/hwasan/TestCases/malloc_fill.cpp @@ -8,17 +8,15 @@ #include -#include "utils.h" - int main(int argc, char **argv) { // With asan allocator this makes sure we get memory from mmap. static const int kSize = 1 << 25; unsigned char *x = new unsigned char[kSize]; - untag_printf("-"); + printf("-"); for (int i = 0; i <= 32; i++) { - untag_printf("%02x", x[i]); + printf("%02x", x[i]); } - untag_printf("-\n"); + printf("-\n"); delete [] x; } diff --git a/compiler-rt/test/hwasan/TestCases/many-threads-uaf.c b/compiler-rt/test/hwasan/TestCases/many-threads-uaf.c index e90432c57a01..3a79cb37b608 100644 --- a/compiler-rt/test/hwasan/TestCases/many-threads-uaf.c +++ b/compiler-rt/test/hwasan/TestCases/many-threads-uaf.c @@ -7,8 +7,6 @@ #include -#include "utils.h" - void *BoringThread(void *arg) { char * volatile x = (char*)malloc(10); x[5] = 0; @@ -25,7 +23,7 @@ void *BoringThread(void *arg) { void *UAFThread(void *arg) { char * volatile x = (char*)malloc(10); - untag_fprintf(stderr, "ZZZ %p\n", x); + fprintf(stderr, "ZZZ %p\n", x); free(x); x[5] = 42; // CHECK: ERROR: HWAddressSanitizer: tag-mismatch on address diff --git a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c index 9c4ca4fa3efe..1c8df8676f98 100644 --- a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c +++ b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c @@ -5,12 +5,13 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include #include -#include "utils.h" - int main() { char Q[16] __attribute__((aligned(256))); char P[16] __attribute__((aligned(256))); @@ -21,7 +22,7 @@ int main() { #elif TEST_NO == 3 memcpy(Q, P, 32); #endif - write(STDOUT_FILENO, UNTAG("recovered\n"), 10); + write(STDOUT_FILENO, "recovered\n", 10); // WRITE: ERROR: HWAddressSanitizer: tag-mismatch on address // WRITE: WRITE of size 32 at {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) // WRITE: Invalid access starting at offset [16, 32) diff --git a/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp b/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp index 8fff9876a642..5b218e11c7ad 100644 --- a/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp +++ b/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp @@ -16,7 +16,7 @@ __attribute__((noinline)) void f(int *p) { *p = 3; } // CHECK: ERROR: HWAddressSanitizer: -// CHECK: #0 {{.*}} in f(int*) {{.*}}register-dump-no-fp.cpp:[[@LINE-3]] +// CHECK: #{{[0-9]}} {{.*}} in f(int*) {{.*}}register-dump-no-fp.cpp:[[@LINE-3]] int main() { __hwasan_enable_allocator_tagging(); @@ -24,5 +24,5 @@ int main() { int *volatile a = new int; a = (int *)__hwasan_tag_pointer(a, 0); f(a); - // CHECK: #1 {{.*}} in main {{.*}}register-dump-no-fp.cpp:[[@LINE-1]] + // CHECK: #{{[0-9]}} {{.*}} in main {{.*}}register-dump-no-fp.cpp:[[@LINE-1]] } diff --git a/compiler-rt/test/hwasan/TestCases/rich-stack.c b/compiler-rt/test/hwasan/TestCases/rich-stack.c index 6787d57769f4..ce04709f0cc9 100644 --- a/compiler-rt/test/hwasan/TestCases/rich-stack.c +++ b/compiler-rt/test/hwasan/TestCases/rich-stack.c @@ -2,6 +2,10 @@ // RUN: %clang_hwasan %s -o %t // RUN: not %run %t 3 2 -1 2>&1 | FileCheck %s --check-prefix=R321 // REQUIRES: stable-runtime + +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include void USE(void *x) { // pretend_to_do_something(void *x) diff --git a/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp b/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp index 736f8a8b923d..c2a20be75def 100644 --- a/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp +++ b/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp @@ -5,10 +5,8 @@ #include -#include "utils.h" - __attribute__((no_sanitize("hwaddress"))) extern "C" void callback(const char *msg) { - untag_fprintf(stderr, "== error start\n%s\n== error end\n", msg); + fprintf(stderr, "== error start\n%s\n== error end\n", msg); } int main() { diff --git a/compiler-rt/test/hwasan/TestCases/sizes.cpp b/compiler-rt/test/hwasan/TestCases/sizes.cpp index 1bfc760e1f9e..4a1156b91b5c 100644 --- a/compiler-rt/test/hwasan/TestCases/sizes.cpp +++ b/compiler-rt/test/hwasan/TestCases/sizes.cpp @@ -34,11 +34,9 @@ #include #include -#include "utils.h" - int main(int argc, char **argv) { assert(argc <= 3); - bool test_size_max = argc == 3 && !untag_strcmp(argv[2], "max"); + bool test_size_max = argc == 3 && !strcmp(argv[2], "max"); static const size_t kMaxAllowedMallocSize = 1ULL << 40; static const size_t kChunkHeaderSize = 16; @@ -46,26 +44,26 @@ int main(int argc, char **argv) { size_t MallocSize = test_size_max ? std::numeric_limits::max() : (kMaxAllowedMallocSize + 1); - if (!untag_strcmp(argv[1], "malloc")) { + if (!strcmp(argv[1], "malloc")) { void *p = malloc(MallocSize); assert(!p); - } else if (!untag_strcmp(argv[1], "calloc")) { + } else if (!strcmp(argv[1], "calloc")) { // Trigger an overflow in calloc. size_t size = std::numeric_limits::max(); void *p = calloc((size / 0x1000) + 1, 0x1000); assert(!p); - } else if (!untag_strcmp(argv[1], "reallocarray")) { + } else if (!strcmp(argv[1], "reallocarray")) { // Trigger an overflow in reallocarray. size_t size = std::numeric_limits::max(); void *p = __sanitizer_reallocarray(nullptr, (size / 0x1000) + 1, 0x1000); assert(!p); - } else if (!untag_strcmp(argv[1], "new")) { + } else if (!strcmp(argv[1], "new")) { void *p = operator new(MallocSize); assert(!p); - } else if (!untag_strcmp(argv[1], "new-nothrow")) { + } else if (!strcmp(argv[1], "new-nothrow")) { void *p = operator new(MallocSize, std::nothrow); assert(!p); - } else if (!untag_strcmp(argv[1], "usable")) { + } else if (!strcmp(argv[1], "usable")) { // Playing with the actual usable size of a chunk. void *p = malloc(1007); assert(p); diff --git a/compiler-rt/test/hwasan/TestCases/stack-history-length.c b/compiler-rt/test/hwasan/TestCases/stack-history-length.c index 584046ee6cea..14a085e509ef 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-history-length.c +++ b/compiler-rt/test/hwasan/TestCases/stack-history-length.c @@ -4,6 +4,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include void USE(void *x) { // pretend_to_do_something(void *x) diff --git a/compiler-rt/test/hwasan/TestCases/stack-oob.c b/compiler-rt/test/hwasan/TestCases/stack-oob.c index 8c8c11055492..c052752b0ad8 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-oob.c +++ b/compiler-rt/test/hwasan/TestCases/stack-oob.c @@ -9,6 +9,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include @@ -22,7 +25,7 @@ int f() { int main() { f(); // CHECK: READ of size 1 at - // CHECK: #0 {{.*}} in f{{.*}}stack-oob.c:19 + // CHECK: #0 {{.*}} in f{{.*}}stack-oob.c:[[@LINE-6]] // CHECK: is located in stack of threa diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c index 4fb8a9006045..ae453f66c4c4 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c @@ -4,6 +4,9 @@ // still be using FP-relative debug info locations that we can use to find stack // objects. +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + __attribute((noinline)) char *buggy(int b) { char c[64]; diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c b/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c index fdd95651f957..fa602404d256 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c @@ -6,6 +6,9 @@ // be able to handle this case somehow (e.g. by using a different register for // DW_AT_frame_base) but at least we shouldn't get confused by it. +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + __attribute((noinline)) char *buggy() { _Alignas(64) char c[64]; diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar.c b/compiler-rt/test/hwasan/TestCases/stack-uar.c index 9a7e357f1b26..d251995d2e85 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar.c @@ -4,6 +4,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + void USE(void *x) { // pretend_to_do_something(void *x) __asm__ __volatile__("" : : "r" (x) : "memory"); } diff --git a/compiler-rt/test/hwasan/TestCases/tail-magic.c b/compiler-rt/test/hwasan/TestCases/tail-magic.c index 73f31dbe5c90..acce591a7ac9 100644 --- a/compiler-rt/test/hwasan/TestCases/tail-magic.c +++ b/compiler-rt/test/hwasan/TestCases/tail-magic.c @@ -10,22 +10,20 @@ #include #include -#include "utils.h" - static volatile char *sink; // Overwrite the tail in a non-hwasan function so that we don't detect the // stores as OOB. __attribute__((no_sanitize("hwaddress"))) void overwrite_tail() { - (*UNTAG(&sink))[20] = 0x42; - (*UNTAG(&sink))[24] = 0x66; + sink[20] = 0x42; + sink[24] = 0x66; } int main(int argc, char **argv) { __hwasan_enable_allocator_tagging(); char *p = (char*)malloc(20); - sink = UNTAG(p); + sink = p; overwrite_tail(); free(p); // CHECK: ERROR: HWAddressSanitizer: allocation-tail-overwritten; heap object [{{.*}}) of size 20 diff --git a/compiler-rt/test/hwasan/TestCases/use-after-free.c b/compiler-rt/test/hwasan/TestCases/use-after-free.c index 2b2562d60122..05ea7f4d7137 100644 --- a/compiler-rt/test/hwasan/TestCases/use-after-free.c +++ b/compiler-rt/test/hwasan/TestCases/use-after-free.c @@ -11,19 +11,17 @@ #include #include -#include "utils.h" - int main() { __hwasan_enable_allocator_tagging(); char * volatile x = (char*)malloc(10); free(x); __hwasan_disable_allocator_tagging(); - untag_fprintf(stderr, ISREAD ? "Going to do a READ\n" : "Going to do a WRITE\n"); + fprintf(stderr, ISREAD ? "Going to do a READ\n" : "Going to do a WRITE\n"); // CHECK: Going to do a [[TYPE:[A-Z]*]] int r = 0; if (ISREAD) r = x[5]; else x[5] = 42; // should be on the same line. // CHECK: [[TYPE]] of size 1 at {{.*}} tags: [[PTR_TAG:[0-9a-f][0-9a-f]]]/[[MEM_TAG:[0-9a-f][0-9a-f]]] (ptr/mem) - // CHECK: #0 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]] + // CHECK: #{{[0-9]}} {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]] // Offset is 5 or 11 depending on left/right alignment. // CHECK: is a small unallocated heap chunk; size: 32 offset: {{5|11}} // CHECK: is located 5 bytes inside of 10-byte region @@ -37,6 +35,6 @@ int main() { // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-19]] // CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes): // CHECK: =>{{.*}}[[MEM_TAG]] - // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main + // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch return r; } diff --git a/compiler-rt/test/hwasan/TestCases/utils.h b/compiler-rt/test/hwasan/TestCases/utils.h deleted file mode 100644 index 7c9f8852d23c..000000000000 --- a/compiler-rt/test/hwasan/TestCases/utils.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#define UNTAG(x) (typeof((x) + 0))(((uintptr_t)(x)) & 0xffffffffffffff) - -__attribute__((no_sanitize("hwaddress"))) -int untag_printf(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - int ret = vprintf(UNTAG(fmt), ap); - va_end(ap); - return ret; -} - -__attribute__((no_sanitize("hwaddress"))) -int untag_fprintf(FILE *stream, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - int ret = vfprintf(stream, UNTAG(fmt), ap); - va_end(ap); - return ret; -} - -int untag_strcmp(const char *s1, const char *s2) { - return strcmp(UNTAG(s1), UNTAG(s2)); -} diff --git a/compiler-rt/test/lsan/TestCases/Linux/fork_and_leak.cpp b/compiler-rt/test/lsan/TestCases/Linux/fork_and_leak.cpp index d7427ce3ed04..758cd819f16e 100644 --- a/compiler-rt/test/lsan/TestCases/Linux/fork_and_leak.cpp +++ b/compiler-rt/test/lsan/TestCases/Linux/fork_and_leak.cpp @@ -1,6 +1,9 @@ // Test that leaks detected after forking without exec(). // RUN: %clangxx_lsan %s -o %t && not %run %t 2>&1 | FileCheck %s +/// Fails on clang-cmake-aarch64-full (glibc 2.27-3ubuntu1.4). +// UNSUPPORTED: aarch64 + #include #include #include diff --git a/compiler-rt/test/lsan/TestCases/malloc_zero.c b/compiler-rt/test/lsan/TestCases/malloc_zero.c new file mode 100644 index 000000000000..daefe71ab1d6 --- /dev/null +++ b/compiler-rt/test/lsan/TestCases/malloc_zero.c @@ -0,0 +1,15 @@ +// RUN: %clang_lsan %s -o %t +// RUN: %env_lsan_opts=use_stacks=0 not %run %t 2>&1 | FileCheck %s + +#include +#include + +// CHECK: {{Leak|Address}}Sanitizer: detected memory leaks +// CHECK: {{Leak|Address}}Sanitizer: 1 byte(s) leaked in 1 allocation(s). + +int main() { + // The behavior of malloc(0) is implementation-defined. + char *p = malloc(0); + fprintf(stderr, "zero: %p\n", p); + p = 0; +} diff --git a/compiler-rt/test/lsan/TestCases/many_tls_keys_pthread.cpp b/compiler-rt/test/lsan/TestCases/many_tls_keys_pthread.cpp index ecc577ac4c68..8c4970c9b137 100644 --- a/compiler-rt/test/lsan/TestCases/many_tls_keys_pthread.cpp +++ b/compiler-rt/test/lsan/TestCases/many_tls_keys_pthread.cpp @@ -5,8 +5,9 @@ // RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t 2>&1 // RUN: %env_lsan_opts="" %run %t 2>&1 -// Patch r303906 did not fix all the problems. -// UNSUPPORTED: arm-linux,armhf-linux +// On glibc, this requires the range returned by GetTLS to include +// specific_1stblock and specific in `struct pthread`. +// UNSUPPORTED: arm-linux, armhf-linux // TSD on NetBSD does not use TLS // UNSUPPORTED: netbsd diff --git a/compiler-rt/test/lsan/TestCases/realloc_too_big.c b/compiler-rt/test/lsan/TestCases/realloc_too_big.c new file mode 100644 index 000000000000..e4d2431a3dfa --- /dev/null +++ b/compiler-rt/test/lsan/TestCases/realloc_too_big.c @@ -0,0 +1,18 @@ +// RUN: %clang_lsan %s -o %t +// RUN: %env_lsan_opts=allocator_may_return_null=1:max_allocation_size_mb=1:use_stacks=0 not %run %t 2>&1 | FileCheck %s + +#include +#include +#include + +// CHECK: {{Leak|Address}}Sanitizer failed to allocate 0x100001 bytes + +// CHECK: {{Leak|Address}}Sanitizer: detected memory leaks +// CHECK: {{Leak|Address}}Sanitizer: 9 byte(s) leaked in 1 allocation(s). + +int main() { + char *p = malloc(9); + fprintf(stderr, "nine: %p\n", p); + assert(realloc(p, 0x100001) == NULL); // 1MiB+1 + p = 0; +} diff --git a/compiler-rt/test/lsan/TestCases/realloc_zero.c b/compiler-rt/test/lsan/TestCases/realloc_zero.c new file mode 100644 index 000000000000..d4ce4754d9bd --- /dev/null +++ b/compiler-rt/test/lsan/TestCases/realloc_zero.c @@ -0,0 +1,13 @@ +// RUN: %clang_lsan %s -o %t +// RUN: %run %t + +#include +#include + +int main() { + char *p = malloc(1); + // The behavior of realloc(p, 0) is implementation-defined. + // We free the allocation. + assert(realloc(p, 0) == NULL); + p = 0; +} diff --git a/compiler-rt/test/lsan/TestCases/swapcontext.cpp b/compiler-rt/test/lsan/TestCases/swapcontext.cpp index d0999598ad4c..f78867cc0695 100644 --- a/compiler-rt/test/lsan/TestCases/swapcontext.cpp +++ b/compiler-rt/test/lsan/TestCases/swapcontext.cpp @@ -5,7 +5,7 @@ // RUN: %env_lsan_opts= %run %t 2>&1 // RUN: %env_lsan_opts= not %run %t foo 2>&1 | FileCheck %s // Missing 'getcontext' and 'makecontext' on Android. -// UNSUPPORTED: arm,powerpc64,android +// UNSUPPORTED: arm,aarch64,powerpc64,android #include "sanitizer_common/sanitizer_ucontext.h" #include diff --git a/compiler-rt/test/lsan/lit.common.cfg.py b/compiler-rt/test/lsan/lit.common.cfg.py index 6e012c06ab11..88c557549b38 100644 --- a/compiler-rt/test/lsan/lit.common.cfg.py +++ b/compiler-rt/test/lsan/lit.common.cfg.py @@ -76,7 +76,7 @@ def build_invocation(compile_flags): # LeakSanitizer tests are currently supported on # Android{aarch64, x86, x86_64}, x86-64 Linux, PowerPC64 Linux, arm Linux, mips64 Linux, s390x Linux and x86_64 Darwin. supported_android = config.android and config.target_arch in ['x86_64', 'i386', 'aarch64'] and 'android-thread-properties-api' in config.available_features -supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['x86_64', 'ppc64', 'ppc64le', 'mips64', 'riscv64', 'arm', 'armhf', 'armv7l', 's390x'] +supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['aarch64', 'x86_64', 'ppc64', 'ppc64le', 'mips64', 'riscv64', 'arm', 'armhf', 'armv7l', 's390x'] supported_darwin = config.host_os == 'Darwin' and config.target_arch in ['x86_64'] supported_netbsd = config.host_os == 'NetBSD' and config.target_arch in ['x86_64', 'i386'] if not (supported_android or supported_linux or supported_darwin or supported_netbsd): diff --git a/compiler-rt/test/memprof/TestCases/test_terse.cpp b/compiler-rt/test/memprof/TestCases/test_terse.cpp index 4ac0d5e77278..04763008016e 100644 --- a/compiler-rt/test/memprof/TestCases/test_terse.cpp +++ b/compiler-rt/test/memprof/TestCases/test_terse.cpp @@ -8,7 +8,7 @@ // RUN: %clangxx_memprof -DFREE -O0 %s -o %t // RUN: %env_memprof_opts=log_path=stderr:print_terse=1 %run %t 2>&1 | FileCheck %s -// CHECK: MIB:[[STACKID:[0-9]+]]/1/40.00/40/40/20.00/20/20/[[AVELIFETIME:[0-9]+]].00/[[AVELIFETIME]]/[[AVELIFETIME]]/0/0/0/0 +// CHECK: MIB:[[STACKID:[0-9]+]]/1/40.00/40/40/20.00/20/20/[[AVELIFETIME:[0-9]+]].00/[[AVELIFETIME]]/[[AVELIFETIME]]/{{[01]}}/0/0/0 // CHECK: Stack for id [[STACKID]]: // CHECK-NEXT: #0 {{.*}} in operator new // CHECK-NEXT: #1 {{.*}} in main {{.*}}:[[@LINE+6]] diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/regex_startend.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/regex_startend.cpp index 1a445783bcbe..e143c6c9b5e2 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/regex_startend.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/regex_startend.cpp @@ -14,6 +14,8 @@ #include #include +/// REG_STARTEND is a BSD extension not supported everywhere. +#ifdef REG_STARTEND void test_matched(const regex_t *preg, const char *string, size_t start, size_t end, const char *expected) { regmatch_t match[1]; @@ -59,3 +61,8 @@ int main(void) { printf("Successful test\n"); return 0; } +#else +int main(void) { + return 0; +} +#endif diff --git a/compiler-rt/test/tsan/on_initialize_finalize_hooks.cpp b/compiler-rt/test/tsan/on_initialize_finalize_hooks.cpp new file mode 100644 index 000000000000..0b82ec176179 --- /dev/null +++ b/compiler-rt/test/tsan/on_initialize_finalize_hooks.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_tsan -O1 %s -o %t.lib -fno-sanitize=thread -shared -fPIC -DBUILD_LIB=1 +// RUN: %clang_tsan -O1 %s %t.lib -o %t +// RUN: %run %t | FileCheck %s + +// Test that initialization/finalization hooks are called, even when they are +// not defined in the main executable, but by another another library that +// doesn't directly link against the TSan runtime. + +#include + +#if BUILD_LIB + +extern "C" void __tsan_on_initialize() { + printf("__tsan_on_initialize()\n"); +} + +extern "C" int __tsan_on_finalize(int failed) { + printf("__tsan_on_finalize()\n"); + return failed; +} + +#else // BUILD_LIB + +int main() { + printf("main()\n"); + return 0; +} + +#endif // BUILD_LIB + +// CHECK: __tsan_on_initialize() +// CHECK: main() +// CHECK: __tsan_on_finalize() diff --git a/debuginfo-tests/dexter/dex/debugger/DebuggerBase.py b/debuginfo-tests/dexter/dex/debugger/DebuggerBase.py index 37aaffe48898..5b97974674a5 100644 --- a/debuginfo-tests/dexter/dex/debugger/DebuggerBase.py +++ b/debuginfo-tests/dexter/dex/debugger/DebuggerBase.py @@ -125,26 +125,46 @@ def clear_breakpoints(self): pass def add_breakpoint(self, file_, line): + """Returns a unique opaque breakpoint id. + + The ID type depends on the debugger being used, but will probably be + an int. + """ return self._add_breakpoint(self._external_to_debug_path(file_), line) @abc.abstractmethod def _add_breakpoint(self, file_, line): + """Returns a unique opaque breakpoint id. + """ pass def add_conditional_breakpoint(self, file_, line, condition): + """Returns a unique opaque breakpoint id. + + The ID type depends on the debugger being used, but will probably be + an int. + """ return self._add_conditional_breakpoint( self._external_to_debug_path(file_), line, condition) @abc.abstractmethod def _add_conditional_breakpoint(self, file_, line, condition): + """Returns a unique opaque breakpoint id. + """ pass - def delete_conditional_breakpoint(self, file_, line, condition): - return self._delete_conditional_breakpoint( - self._external_to_debug_path(file_), line, condition) + @abc.abstractmethod + def delete_breakpoint(self, id): + """Delete a breakpoint by id. + + Raises a KeyError if no breakpoint with this id exists. + """ + pass @abc.abstractmethod - def _delete_conditional_breakpoint(self, file_, line, condition): + def get_triggered_breakpoint_ids(self): + """Returns a set of opaque ids for just-triggered breakpoints. + """ pass @abc.abstractmethod diff --git a/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py b/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py index 4e4327b53f82..e225a48bcb66 100644 --- a/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py +++ b/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py @@ -42,17 +42,18 @@ class ConditionalController(DebuggerControllerBase): def __init__(self, context, step_collection): self.context = context self.step_collection = step_collection - self._conditional_bps = None + self._conditional_bp_ranges = None + self._build_conditional_bp_ranges() self._watches = set() self._step_index = 0 - self._build_conditional_bps() - self._path_and_line_to_conditional_bp = defaultdict(list) self._pause_between_steps = context.options.pause_between_steps self._max_steps = context.options.max_steps + # Map {id: ConditionalBpRange} + self._conditional_bp_handles = {} - def _build_conditional_bps(self): + def _build_conditional_bp_ranges(self): commands = self.step_collection.commands - self._conditional_bps = [] + self._conditional_bp_ranges = [] try: limit_commands = commands['DexLimitSteps'] for lc in limit_commands: @@ -62,22 +63,19 @@ def _build_conditional_bps(self): lc.from_line, lc.to_line, lc.values) - self._conditional_bps.append(conditional_bp) + self._conditional_bp_ranges.append(conditional_bp) except KeyError: raise DebuggerException('Missing DexLimitSteps commands, cannot conditionally step.') def _set_conditional_bps(self): - # When we break in the debugger we need a quick and easy way to look up - # which conditional bp we've breaked on. - for cbp in self._conditional_bps: - conditional_bp_list = self._path_and_line_to_conditional_bp[(cbp.path, cbp.range_from)] - conditional_bp_list.append(cbp) - - # Set break points only on the first line of any conditional range, we'll set - # more break points for a range when the condition is satisfied. - for cbp in self._conditional_bps: + # Set a conditional breakpoint for each ConditionalBpRange and build a + # map of {id: ConditionalBpRange}. + for cbp in self._conditional_bp_ranges: for cond_expr in cbp.get_conditional_expression_list(): - self.debugger.add_conditional_breakpoint(cbp.path, cbp.range_from, cond_expr) + id = self.debugger.add_conditional_breakpoint(cbp.path, + cbp.range_from, + cond_expr) + self._conditional_bp_handles[id] = cbp def _conditional_met(self, cbp): for cond_expr in cbp.get_conditional_expression_list(): @@ -98,7 +96,7 @@ def _run_debugger_custom(self): self._watches.update(command_obj.get_watches()) self.debugger.launch() - time.sleep(self._pause_between_steps) + time.sleep(self._pause_between_steps) while not self.debugger.is_finished: while self.debugger.is_running: pass @@ -109,19 +107,28 @@ def _run_debugger_custom(self): update_step_watches(step_info, self._watches, self.step_collection.commands) self.step_collection.new_step(self.context, step_info) - loc = step_info.current_location - conditional_bp_key = (loc.path, loc.lineno) - if conditional_bp_key in self._path_and_line_to_conditional_bp: + bp_to_delete = [] + for bp_id in self.debugger.get_triggered_breakpoint_ids(): + try: + # See if this is one of our conditional breakpoints. + cbp = self._conditional_bp_handles[bp_id] + except KeyError: + # This is an unconditional bp. Mark it for removal. + bp_to_delete.append(bp_id) + continue + # We have triggered a breakpoint with a condition. Check that + # the condition has been met. + if self._conditional_met(cbp): + # Add a range of unconditional breakpoints covering the + # lines requested in the DexLimitSteps command. Ignore + # first line as that's the conditional bp we just hit and + # include the final line. + for line in range(cbp.range_from + 1, cbp.range_to + 1): + self.debugger.add_breakpoint(cbp.path, line) + + # Remove any unconditional breakpoints we just hit. + for bp_id in bp_to_delete: + self.debugger.delete_breakpoint(bp_id) - conditional_bps = self._path_and_line_to_conditional_bp[conditional_bp_key] - for cbp in conditional_bps: - if self._conditional_met(cbp): - # Unconditional range should ignore first line as that's the - # conditional bp we just hit and should be inclusive of final line - for line in range(cbp.range_from + 1, cbp.range_to + 1): - self.debugger.add_conditional_breakpoint(cbp.path, line, condition='') - - # Clear any uncondtional break points at this loc. - self.debugger.delete_conditional_breakpoint(file_=loc.path, line=loc.lineno, condition='') self.debugger.go() time.sleep(self._pause_between_steps) diff --git a/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py b/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py index adac7674aff6..a8e0722579b6 100644 --- a/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py +++ b/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py @@ -27,7 +27,8 @@ def update_step_watches(step_info, watches, commands): # Iterate over all watches of the types named in watch_cmds for watch in towatch: loc = step_info.current_location - if (os.path.exists(loc.path) + if (loc.path != None + and os.path.exists(loc.path) and os.path.samefile(watch.path, loc.path) and watch.lineno == loc.lineno): result = watch.eval(step_info) diff --git a/debuginfo-tests/dexter/dex/debugger/dbgeng/dbgeng.py b/debuginfo-tests/dexter/dex/debugger/dbgeng/dbgeng.py index 5105b4afa706..c95aa54f7e6b 100644 --- a/debuginfo-tests/dexter/dex/debugger/dbgeng/dbgeng.py +++ b/debuginfo-tests/dexter/dex/debugger/dbgeng/dbgeng.py @@ -87,7 +87,10 @@ def _add_conditional_breakpoint(self, file_, line, condition): # but is something that should be considered in the future. raise NotImplementedError('add_conditional_breakpoint is not yet implemented by dbgeng') - def _delete_conditional_breakpoint(self, file_, line, condition): + def get_triggered_breakpoint_ids(self): + raise NotImplementedError('get_triggered_breakpoint_ids is not yet implemented by dbgeng') + + def delete_breakpoint(self, id): # breakpoint setting/deleting is not supported by dbgeng at this moment # but is something that should be considered in the future. raise NotImplementedError('delete_conditional_breakpoint is not yet implemented by dbgeng') diff --git a/debuginfo-tests/dexter/dex/debugger/lldb/LLDB.py b/debuginfo-tests/dexter/dex/debugger/lldb/LLDB.py index 5fc8fd3e95f8..324467dd0819 100644 --- a/debuginfo-tests/dexter/dex/debugger/lldb/LLDB.py +++ b/debuginfo-tests/dexter/dex/debugger/lldb/LLDB.py @@ -104,9 +104,11 @@ def clear_breakpoints(self): self._target.DeleteAllBreakpoints() def _add_breakpoint(self, file_, line): - if not self._target.BreakpointCreateByLocation(file_, line): + bp = self._target.BreakpointCreateByLocation(file_, line) + if not bp: raise DebuggerException( 'could not add breakpoint [{}:{}]'.format(file_, line)) + return bp.GetID() def _add_conditional_breakpoint(self, file_, line, condition): bp = self._target.BreakpointCreateByLocation(file_, line) @@ -115,37 +117,24 @@ def _add_conditional_breakpoint(self, file_, line, condition): else: raise DebuggerException( 'could not add breakpoint [{}:{}]'.format(file_, line)) - - def _delete_conditional_breakpoint(self, file_, line, condition): - bp_count = self._target.GetNumBreakpoints() - bps = [self._target.GetBreakpointAtIndex(ix) for ix in range(0, bp_count)] - - for bp in bps: - bp_cond = bp.GetCondition() - bp_cond = bp_cond if bp_cond is not None else '' - - if bp_cond != condition: - continue - - # If one of the bound bp locations for this bp is bound to the same - # line in file_ above, then delete the entire parent bp and all - # bp locs. - # https://lldb.llvm.org/python_reference/lldb.SBBreakpoint-class.html - for breakpoint_location in bp: - sb_address = breakpoint_location.GetAddress() - - sb_line_entry = sb_address.GetLineEntry() - bl_line = sb_line_entry.GetLine() - - sb_file_entry = sb_line_entry.GetFileSpec() - bl_dir = sb_file_entry.GetDirectory() - bl_file_name = sb_file_entry.GetFilename() - - bl_file_path = os.path.join(bl_dir, bl_file_name) - - if bl_file_path == file_ and bl_line == line: - self._target.BreakpointDelete(bp.GetID()) - break + return bp.GetID() + + def get_triggered_breakpoint_ids(self): + # Breakpoints can only have been triggered if we've hit one. + stop_reason = self._translate_stop_reason(self._thread.GetStopReason()) + if stop_reason != StopReason.BREAKPOINT: + return [] + # Breakpoints have two data parts: Breakpoint ID, Location ID. We're + # only interested in the Breakpoint ID so we skip every other item. + return set([self._thread.GetStopReasonDataAtIndex(i) + for i in range(0, self._thread.GetStopReasonDataCount(), 2)]) + + def delete_breakpoint(self, id): + bp = self._target.FindBreakpointByID(id) + if not bp: + # The ID is not valid. + raise KeyError + self._target.BreakpointDelete(bp.GetID()) def launch(self): self._process = self._target.LaunchSimple(None, None, os.getcwd()) diff --git a/debuginfo-tests/dexter/dex/debugger/visualstudio/VisualStudio.py b/debuginfo-tests/dexter/dex/debugger/visualstudio/VisualStudio.py index 6585a4938c12..b4558e2d8a50 100644 --- a/debuginfo-tests/dexter/dex/debugger/visualstudio/VisualStudio.py +++ b/debuginfo-tests/dexter/dex/debugger/visualstudio/VisualStudio.py @@ -10,6 +10,9 @@ import imp import os import sys +from pathlib import PurePath +from collections import namedtuple +from collections import defaultdict from dex.debugger.DebuggerBase import DebuggerBase from dex.dextIR import FrameIR, LocIR, StepIR, StopReason, ValueIR @@ -28,6 +31,11 @@ def _load_com_module(): raise LoadDebuggerException(e, sys.exc_info()) +# VSBreakpoint(path: PurePath, line: int, col: int, cond: str). This is enough +# info to identify breakpoint equivalence in visual studio based on the +# properties we set through dexter currently. +VSBreakpoint = namedtuple('VSBreakpoint', 'path, line, col, cond') + class VisualStudio(DebuggerBase, metaclass=abc.ABCMeta): # pylint: disable=abstract-method # Constants for results of Debugger.CurrentMode @@ -42,6 +50,21 @@ def __init__(self, *args): self._solution = None self._fn_step = None self._fn_go = None + # The next available unique breakpoint id. Use self._get_next_id(). + self._next_bp_id = 0 + # VisualStudio appears to common identical breakpoints. That is, if you + # ask for a breakpoint that already exists the Breakpoints list will + # not grow. DebuggerBase requires all breakpoints have a unique id, + # even for duplicates, so we'll need to do some bookkeeping. Map + # {VSBreakpoint: list(id)} where id is the unique dexter-side id for + # the requested breakpoint. + self._vs_to_dex_ids = defaultdict(list) + # Map {id: VSBreakpoint} where id is unique and VSBreakpoint identifies + # a breakpoint in Visual Studio. There may be many ids mapped to a + # single VSBreakpoint. Use self._vs_to_dex_ids to find (dexter) + # breakpoints mapped to the same visual studio breakpoint. + self._dex_id_to_vs = {} + super(VisualStudio, self).__init__(*args) def _custom_init(self): @@ -110,21 +133,88 @@ def version(self): def clear_breakpoints(self): for bp in self._debugger.Breakpoints: bp.Delete() + self._vs_to_dex_ids.clear() + self._dex_id_to_vs.clear() def _add_breakpoint(self, file_, line): - self._debugger.Breakpoints.Add('', file_, line) + return self._add_conditional_breakpoint(file_, line, '') - def _add_conditional_breakpoint(self, file_, line, condition): - column = 1 - self._debugger.Breakpoints.Add('', file_, line, column, condition) + def _get_next_id(self): + # "Generate" a new unique id for the breakpoint. + id = self._next_bp_id + self._next_bp_id += 1 + return id - def _delete_conditional_breakpoint(self, file_, line, condition): + def _add_conditional_breakpoint(self, file_, line, condition): + col = 1 + vsbp = VSBreakpoint(PurePath(file_), line, col, condition) + new_id = self._get_next_id() + + # Do we have an exact matching breakpoint already? + if vsbp in self._vs_to_dex_ids: + self._vs_to_dex_ids[vsbp].append(new_id) + self._dex_id_to_vs[new_id] = vsbp + return new_id + + # Breakpoint doesn't exist already. Add it now. + count_before = self._debugger.Breakpoints.Count + self._debugger.Breakpoints.Add('', file_, line, col, condition) + # Our internal representation of VS says that the breakpoint doesn't + # already exist so we do not expect this operation to fail here. + assert count_before < self._debugger.Breakpoints.Count + # We've added a new breakpoint, record its id. + self._vs_to_dex_ids[vsbp].append(new_id) + self._dex_id_to_vs[new_id] = vsbp + return new_id + + def get_triggered_breakpoint_ids(self): + """Returns a set of opaque ids for just-triggered breakpoints. + """ + bps_hit = self._debugger.AllBreakpointsLastHit + bp_id_list = [] + # Intuitively, AllBreakpointsLastHit breakpoints are the last hit + # _bound_ breakpoints. A bound breakpoint's parent holds the info of + # the breakpoint the user requested. Our internal state tracks the user + # requested breakpoints so we look at the Parent of these triggered + # breakpoints to determine which have been hit. + for bp in bps_hit: + # All bound breakpoints should have the user-defined breakpoint as + # a parent. + assert bp.Parent + vsbp = VSBreakpoint(PurePath(bp.Parent.File), bp.Parent.FileLine, + bp.Parent.FileColumn, bp.Parent.Condition) + try: + ids = self._vs_to_dex_ids[vsbp] + except KeyError: + pass + else: + bp_id_list += ids + return set(bp_id_list) + + def delete_breakpoint(self, id): + """Delete a breakpoint by id. + + Raises a KeyError if no breakpoint with this id exists. + """ + vsbp = self._dex_id_to_vs[id] + + # Remove our id from the associated list of dex ids. + self._vs_to_dex_ids[vsbp].remove(id) + del self._dex_id_to_vs[id] + + # Bail if there are other uses of this vsbp. + if len(self._vs_to_dex_ids[vsbp]) > 0: + return + # Otherwise find and delete it. for bp in self._debugger.Breakpoints: - for bound_bp in bp.Children: - if (bound_bp.File == file_ and bound_bp.FileLine == line and - bound_bp.Condition == condition): - bp.Delete() - break + # We're looking at the user-set breakpoints so there shouild be no + # Parent. + assert bp.Parent == None + this_vsbp = VSBreakpoint(PurePath(bp.File), bp.FileLine, + bp.FileColumn, bp.Condition) + if vsbp == this_vsbp: + bp.Delete() + break def launch(self): self._fn_go() diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_line_mismatch.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_line_mismatch.cpp new file mode 100644 index 000000000000..68ae4766653e --- /dev/null +++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_line_mismatch.cpp @@ -0,0 +1,25 @@ +// Purpose: +// Check that \DexLimitSteps works even if the opening breakpoint line +// doesn't exist. This can happen due to optimisations or label is on an +// empty line. +// +// FIXME: Windows regression tests run with dbgeng. \DexLimitSteps isn't yet +// supported with dbgeng. +// +// REQUIRES: system-linux +// +// RUN: %dexter_regression_test -- %s | FileCheck %s +// CHECK: limit_steps_line_mismatch.cpp + +int main() { + int i = 0; + for (; i < 2; i++) { + // DexLabel('from') + int x = i; + } + int ret = 0; + return ret; // DexLabel('to') +} + +// DexLimitSteps('1', '1', from_line='from', to_line='to') +// DexExpectWatchValue('i', 0, 1, 2, from_line='from', to_line='to') diff --git a/debuginfo-tests/llvm-prettyprinters/gdb/mlir-support.cpp b/debuginfo-tests/llvm-prettyprinters/gdb/mlir-support.cpp index a1d62f509b21..9a65ad377fd5 100644 --- a/debuginfo-tests/llvm-prettyprinters/gdb/mlir-support.cpp +++ b/debuginfo-tests/llvm-prettyprinters/gdb/mlir-support.cpp @@ -24,11 +24,11 @@ mlir::Type TupleType = mlir::TupleType::get(&Context, mlir::TypeRange({IndexType, FloatType})); auto UnknownLoc = mlir::UnknownLoc::get(&Context); -auto FileLineColLoc = mlir::FileLineColLoc::get("file", 7, 8, &Context); +auto FileLineColLoc = mlir::FileLineColLoc::get(&Context, "file", 7, 8); auto OpaqueLoc = mlir::OpaqueLoc::get(9, &Context); auto NameLoc = mlir::NameLoc::get(Identifier); auto CallSiteLoc = mlir::CallSiteLoc::get(FileLineColLoc, OpaqueLoc); -auto FusedLoc = mlir::FusedLoc::get({FileLineColLoc, NameLoc}, &Context); +auto FusedLoc = mlir::FusedLoc::get(&Context, {FileLineColLoc, NameLoc}); mlir::Attribute UnitAttr = mlir::UnitAttr::get(&Context); mlir::Attribute FloatAttr = mlir::FloatAttr::get(FloatType, 1.0); diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 4ea0569ceb47..812a794fe3e7 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -48,9 +48,23 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR_ABSOLUTE}) if(FLANG_BUILD_NEW_DRIVER) + # Users might specify a path to CLANG_DIR that's: + # * a full path, or + # * a path relative to the path of this script. + # Append the absolute path to CLANG_DIR so that find_package works in both + # cases. + get_filename_component( + CLANG_DIR_ABSOLUTE + ${CLANG_DIR} + REALPATH + ${CMAKE_CURRENT_SOURCE_DIR}) + list(APPEND CMAKE_MODULE_PATH ${CLANG_DIR_ABSOLUTE}) + # TODO: Remove when libclangDriver is lifted out of Clang - list(APPEND CMAKE_MODULE_PATH ${CLANG_DIR}) - find_package(Clang REQUIRED HINTS "${CLANG_DIR}") + find_package(Clang REQUIRED PATHS "${CLANG_DIR_ABSOLUTE}" NO_DEFAULT_PATH) + if (NOT Clang_FOUND) + message(FATAL_ERROR "Failed to find Clang") + endif() endif() # If LLVM links to zlib we need the imported targets so we can too. @@ -190,6 +204,7 @@ else() include_directories(SYSTEM ${MLIR_INCLUDE_DIR}) include_directories(SYSTEM ${MLIR_TABLEGEN_OUTPUT_DIR}) endif() +set(FLANG_INTRINSIC_MODULES_DIR ${CMAKE_BINARY_DIR}/include/flang) if(FLANG_BUILD_NEW_DRIVER) # TODO: Remove when libclangDriver is lifted out of Clang diff --git a/flang/LICENSE.txt b/flang/LICENSE.TXT similarity index 100% rename from flang/LICENSE.txt rename to flang/LICENSE.TXT diff --git a/flang/docs/GettingInvolved.md b/flang/docs/GettingInvolved.md index 31a3cf6c459a..44d7519a9c03 100644 --- a/flang/docs/GettingInvolved.md +++ b/flang/docs/GettingInvolved.md @@ -92,6 +92,6 @@ To understand the status of various developments in Flang please join the respec - Development updates on the new Flang driver. - Join [New Flang Driver Technical Call](https://bit.ly/2Yo6RYI) -- Time: On Mondays 8:30 AM Pacific Time, on the weeks alternating with Flang Community Technical Biweekly Call +- Time: On Mondays 4:30 PM UK Time, on the weeks alternating with Flang Community Technical Biweekly Call - Meeting minutes are [here](https://docs.google.com/document/d/1G042fAWgVN-QW9fi8JGy4lyTLC1IMQ_tfWDZin3RHW4). - Status tracking [page](https://docs.google.com/spreadsheets/d/1JRe39lP_KhtkYxFEIvwrCFlE5v1Ofa_krOHI-XXXWPY) diff --git a/flang/include/flang/Evaluate/constant.h b/flang/include/flang/Evaluate/constant.h index 89a5867722f7..d5f7db8be45d 100644 --- a/flang/include/flang/Evaluate/constant.h +++ b/flang/include/flang/Evaluate/constant.h @@ -195,8 +195,11 @@ class Constant> : public ConstantBounds { }; class StructureConstructor; -using StructureConstructorValues = - std::map>>; +struct ComponentCompare { + bool operator()(SymbolRef x, SymbolRef y) const; +}; +using StructureConstructorValues = std::map>, ComponentCompare>; template <> class Constant diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index 5ad999c550e3..bcfb1c55e287 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -730,7 +730,8 @@ common::IfNoLvalue>, WRAPPED> TypedWrapper( // GetLastSymbol() returns the rightmost symbol in an object or procedure // designator (which has perhaps been wrapped in an Expr<>), or a null pointer -// when none is found. +// when none is found. It will return an ASSOCIATE construct entity's symbol +// rather than descending into its expression. struct GetLastSymbolHelper : public AnyTraverse> { using Result = std::optional; @@ -806,7 +807,7 @@ template bool IsAllocatableOrPointer(const A &x) { // Procedure and pointer detection predicates bool IsProcedure(const Expr &); bool IsFunction(const Expr &); -bool IsProcedurePointer(const Expr &); +bool IsProcedurePointerTarget(const Expr &); bool IsNullPointer(const Expr &); bool IsObjectPointer(const Expr &, FoldingContext &); @@ -839,10 +840,12 @@ template SymbolVector GetSymbolVector(const A &x) { const Symbol *GetLastTarget(const SymbolVector &); // Collects all of the Symbols in an expression -template semantics::SymbolSet CollectSymbols(const A &); -extern template semantics::SymbolSet CollectSymbols(const Expr &); -extern template semantics::SymbolSet CollectSymbols(const Expr &); -extern template semantics::SymbolSet CollectSymbols( +template semantics::UnorderedSymbolSet CollectSymbols(const A &); +extern template semantics::UnorderedSymbolSet CollectSymbols( + const Expr &); +extern template semantics::UnorderedSymbolSet CollectSymbols( + const Expr &); +extern template semantics::UnorderedSymbolSet CollectSymbols( const Expr &); // Predicate: does a variable contain a vector-valued subscript (not a triplet)? @@ -963,6 +966,7 @@ const Symbol *FindCommonBlockContaining(const Symbol &); int CountLenParameters(const DerivedTypeSpec &); int CountNonConstantLenParameters(const DerivedTypeSpec &); const Symbol &GetUsedModule(const UseDetails &); +const Symbol *FindFunctionResult(const Symbol &); } // namespace Fortran::semantics diff --git a/flang/include/flang/Evaluate/traverse.h b/flang/include/flang/Evaluate/traverse.h index c9455910aa41..7a5a4ec9ff87 100644 --- a/flang/include/flang/Evaluate/traverse.h +++ b/flang/include/flang/Evaluate/traverse.h @@ -33,6 +33,9 @@ // subtrees of interior nodes, and the visitor's Combine() to merge their // results together. // - Overloads of operator() in each visitor handle the cases of interest. +// +// The default handler for semantics::Symbol will descend into the associated +// expression of an ASSOCIATE (or related) construct entity. #include "expression.h" #include "flang/Semantics/symbol.h" @@ -102,7 +105,15 @@ template class Traverse { return visitor_.Default(); } } - Result operator()(const Symbol &) const { return visitor_.Default(); } + Result operator()(const Symbol &symbol) const { + const Symbol &ultimate{symbol.GetUltimate()}; + if (const auto *assoc{ + ultimate.detailsIf()}) { + return visitor_(assoc->expr()); + } else { + return visitor_.Default(); + } + } Result operator()(const StaticDataObject &) const { return visitor_.Default(); } diff --git a/flang/include/flang/Frontend/CompilerInvocation.h b/flang/include/flang/Frontend/CompilerInvocation.h index 9946f3e4a6e6..99050dcdbd7b 100644 --- a/flang/include/flang/Frontend/CompilerInvocation.h +++ b/flang/include/flang/Frontend/CompilerInvocation.h @@ -69,9 +69,13 @@ class CompilerInvocation : public CompilerInvocationBase { // of options. std::string moduleDir_ = "."; + bool debugModuleDir_ = false; + // Fortran Dialect options Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_; + bool EnableConformanceChecks_ = false; + public: CompilerInvocation() = default; @@ -91,6 +95,14 @@ class CompilerInvocation : public CompilerInvocationBase { std::string &moduleDir() { return moduleDir_; } const std::string &moduleDir() const { return moduleDir_; } + bool &debugModuleDir() { return debugModuleDir_; } + const bool &debugModuleDir() const { return debugModuleDir_; } + + bool &enableConformanceChecks() { return EnableConformanceChecks_; } + const bool &enableConformanceChecks() const { + return EnableConformanceChecks_; + } + Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() { return defaultKinds_; } @@ -106,6 +118,14 @@ class CompilerInvocation : public CompilerInvocationBase { llvm::ArrayRef commandLineArgs, clang::DiagnosticsEngine &diags); + // Enables the std=f2018 conformance check + void set_EnableConformanceChecks() { EnableConformanceChecks_ = true; } + + /// Useful setters + void SetModuleDir(std::string &moduleDir) { moduleDir_ = moduleDir; } + + void SetDebugModuleDir(bool flag) { debugModuleDir_ = flag; } + /// Set the Fortran options to predifined defaults. These defaults are /// consistend with f18/f18.cpp. // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h index f6dfdd2dc09b..f49f9f4714b5 100644 --- a/flang/include/flang/Frontend/FrontendActions.h +++ b/flang/include/flang/Frontend/FrontendActions.h @@ -54,6 +54,10 @@ class DebugDumpProvenanceAction : public PrescanAction { void ExecuteAction() override; }; +class DebugDumpParsingLogAction : public PrescanAction { + void ExecuteAction() override; +}; + class DebugMeasureParseTreeAction : public PrescanAction { void ExecuteAction() override; }; @@ -96,6 +100,10 @@ class DebugPreFIRTreeAction : public PrescanAndSemaAction { void ExecuteAction() override; }; +class GetSymbolsSourcesAction : public PrescanAndSemaAction { + void ExecuteAction() override; +}; + class ParseSyntaxOnlyAction : public PrescanAndSemaAction { void ExecuteAction() override; }; diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h index 98a717dfa6ec..1d9002335c3c 100644 --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/include/flang/Frontend/FrontendOptions.h @@ -50,12 +50,18 @@ enum ActionKind { /// Dump provenance DebugDumpProvenance, + /// Parse then output the parsing log + DebugDumpParsingLog, + /// Parse then output the number of objects in the parse tree and the overall /// size DebugMeasureParseTree, /// Parse, run semantics and then output the pre-FIR tree - DebugPreFIRTree + DebugPreFIRTree, + + /// Parse, run semantics and then dump symbol sources map + GetSymbolsSources /// TODO: RunPreprocessor, EmitLLVM, EmitLLVMOnly, /// EmitCodeGenOnly, EmitAssembly, (...) @@ -172,6 +178,9 @@ class FrontendOptions { /// Show the -version text. unsigned showVersion_ : 1; + /// Instrument the parse to get a more verbose log + unsigned instrumentedParse_ : 1; + /// The input files and their types. std::vector inputs_; diff --git a/flang/include/flang/Frontend/PreprocessorOptions.h b/flang/include/flang/Frontend/PreprocessorOptions.h index 39ea4d3d3c6c..3a3877bf0b28 100644 --- a/flang/include/flang/Frontend/PreprocessorOptions.h +++ b/flang/include/flang/Frontend/PreprocessorOptions.h @@ -29,6 +29,8 @@ class PreprocessorOptions { // consider collecting them in a separate aggregate. For now we keep it here // as there is no point creating a class for just one field. std::vector searchDirectoriesFromDashI; + // Search directories specified by the user with -fintrinsic-modules-path + std::vector searchDirectoriesFromIntrModPath; public: PreprocessorOptions() {} @@ -44,4 +46,4 @@ class PreprocessorOptions { } // namespace Fortran::frontend -#endif // LLVM_FLANG_PREPROCESSOROPTIONS_H \ No newline at end of file +#endif // LLVM_FLANG_PREPROCESSOROPTIONS_H diff --git a/flang/include/flang/Lower/IO.h b/flang/include/flang/Lower/IO.h index 9d5147f8e42a..cbfd6dffaed7 100644 --- a/flang/include/flang/Lower/IO.h +++ b/flang/include/flang/Lower/IO.h @@ -43,7 +43,7 @@ namespace pft { struct Evaluation; using LabelEvalMap = llvm::DenseMap; using SymbolRef = Fortran::common::Reference; -using LabelSet = llvm::SmallSet; +using LabelSet = llvm::SmallSet; using SymbolLabelMap = llvm::DenseMap; } // namespace pft diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h index 044e6084330f..16abf6bc8f3a 100644 --- a/flang/include/flang/Lower/PFTBuilder.h +++ b/flang/include/flang/Lower/PFTBuilder.h @@ -6,6 +6,10 @@ // //===----------------------------------------------------------------------===// // +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// +// // PFT (Pre-FIR Tree) interface. // //===----------------------------------------------------------------------===// @@ -15,31 +19,20 @@ #include "flang/Common/reference.h" #include "flang/Common/template.h" +#include "flang/Lower/PFTDefs.h" #include "flang/Parser/parse-tree.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallSet.h" +#include "flang/Semantics/attr.h" +#include "flang/Semantics/symbol.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -namespace mlir { -class Block; -} - -namespace Fortran { -namespace semantics { -class SemanticsContext; -class Scope; -} // namespace semantics -namespace lower { -namespace pft { +namespace Fortran::lower::pft { struct Evaluation; struct Program; struct ModuleLikeUnit; struct FunctionLikeUnit; -// TODO: A collection of Evaluations can obviously be any of the container -// types; leaving this as a std::list _for now_ because we reserve the right to -// insert PFT nodes in any order in O(1) time. using EvaluationList = std::list; using LabelEvalMap = llvm::DenseMap; @@ -61,7 +54,11 @@ class ReferenceVariantBase { template constexpr BaseType &get() const { - return std::get> > (u).get(); + return std::get>(u).get(); + } + template + constexpr BaseType &getStatement() const { + return std::get>>(u).get().statement; } template constexpr BaseType *getIf() const { @@ -87,10 +84,10 @@ using ReferenceVariant = ReferenceVariantBase; template using MutableReferenceVariant = ReferenceVariantBase; -/// ParentVariant is used to provide a reference to the unit a parse-tree node +/// PftNode is used to provide a reference to the unit a parse-tree node /// belongs to. It is a variant of non-nullable pointers. -using ParentVariant = MutableReferenceVariant; +using PftNode = MutableReferenceVariant; /// Classify the parse-tree nodes from ExecutablePartConstruct @@ -109,8 +106,8 @@ using ActionStmts = std::tuple< parser::ComputedGotoStmt, parser::ForallStmt, parser::ArithmeticIfStmt, parser::AssignStmt, parser::AssignedGotoStmt, parser::PauseStmt>; -using OtherStmts = std::tuple; +using OtherStmts = + std::tuple; using ConstructStmts = std::tuple< parser::AssociateStmt, parser::EndAssociateStmt, parser::BlockStmt, @@ -123,6 +120,10 @@ using ConstructStmts = std::tuple< parser::MaskedElsewhereStmt, parser::ElsewhereStmt, parser::EndWhereStmt, parser::ForallConstructStmt, parser::EndForallStmt>; +using EndStmts = + std::tuple; + using Constructs = std::tuple}; template static constexpr bool isConstructStmt{common::HasMember}; +template +static constexpr bool isEndStmt{common::HasMember}; + template static constexpr bool isConstruct{common::HasMember}; @@ -168,10 +172,6 @@ static constexpr bool isFunctionLike{common::HasMember< parser::SubroutineSubprogram, parser::SeparateModuleSubprogram>>}; -using LabelSet = llvm::SmallSet; -using SymbolRef = common::Reference; -using SymbolLabelMap = llvm::DenseMap; - template struct MakeReferenceVariantHelper {}; template @@ -186,8 +186,8 @@ template using MakeReferenceVariant = typename MakeReferenceVariantHelper::type; using EvaluationTuple = - common::CombineTuples; + common::CombineTuples; /// Hide non-nullable pointers to the parse-tree node. /// Build type std::variant /// from EvaluationTuple type (std::tuple). @@ -199,16 +199,16 @@ struct Evaluation : EvaluationVariant { /// General ctor template - Evaluation(const A &a, const ParentVariant &parentVariant, + Evaluation(const A &a, const PftNode &parent, const parser::CharBlock &position, const std::optional &label) - : EvaluationVariant{a}, - parentVariant{parentVariant}, position{position}, label{label} {} + : EvaluationVariant{a}, parent{parent}, position{position}, label{label} { + } - /// Construct ctor + /// Construct and Directive ctor template - Evaluation(const A &a, const ParentVariant &parentVariant) - : EvaluationVariant{a}, parentVariant{parentVariant} { + Evaluation(const A &a, const PftNode &parent) + : EvaluationVariant{a}, parent{parent} { static_assert(pft::isConstruct || pft::isDirective, "must be a construct or directive"); } @@ -227,6 +227,10 @@ struct Evaluation : EvaluationVariant { return pft::isConstructStmt>; }}); } + constexpr bool isEndStmt() const { + return visit(common::visitors{ + [](auto &r) { return pft::isEndStmt>; }}); + } constexpr bool isConstruct() const { return visit(common::visitors{ [](auto &r) { return pft::isConstruct>; }}); @@ -249,6 +253,8 @@ struct Evaluation : EvaluationVariant { }}); } + LLVM_DUMP_METHOD void dump() const; + /// Return the first non-nop successor of an evaluation, possibly exiting /// from one or more enclosing constructs. Evaluation &nonNopSuccessor() const { @@ -287,14 +293,13 @@ struct Evaluation : EvaluationVariant { bool lowerAsStructured() const; bool lowerAsUnstructured() const; - // FIR generation looks primarily at PFT statement (leaf) nodes. So members - // such as lexicalSuccessor and the various block fields are only applicable - // to statement nodes. One exception is that an internal construct node is - // a convenient place for a constructExit link that applies to exits from any - // statement within the construct. The controlSuccessor member is used for - // nonlexical successors, such as linking to a GOTO target. For multiway - // branches, controlSuccessor is set to one of the targets (might as well be - // the first target). Successor and exit links always target statements. + // FIR generation looks primarily at PFT ActionStmt and ConstructStmt leaf + // nodes. Members such as lexicalSuccessor and block are applicable only + // to these nodes. The controlSuccessor member is used for nonlexical + // successors, such as linking to a GOTO target. For multiway branches, + // it is set to the first target. Successor and exit links always target + // statements. An internal Construct node has a constructExit link that + // applies to exits from anywhere within the construct. // // An unstructured construct is one that contains some form of goto. This // is indicated by the isUnstructured member flag, which may be set on a @@ -303,25 +308,21 @@ struct Evaluation : EvaluationVariant { // FIR operations. An unstructured statement is materialized as mlir // operation sequences that include explicit branches. // - // There are two mlir::Block members. The block member is set for statements - // that begin a new block. If a statement may have more than one associated - // block, this member must be the block that would be the target of a branch - // to the statement. The prime example of a statement that may have multiple - // associated blocks is NonLabelDoStmt, which may have a loop preheader block - // for loop initialization code, and always has a header block that is the - // target of the loop back edge. If the NonLabelDoStmt is a concurrent loop, - // there may be an arbitrary number of nested preheader, header, and mask - // blocks. Any such additional blocks in the localBlocks member are local - // to a construct and cannot be the target of an unstructured branch. For - // NonLabelDoStmt, the block member designates the preheader block, which may - // be absent if loop initialization code may be appended to a predecessor - // block. The primary loop header block is localBlocks[0], with additional - // DO CONCURRENT blocks at localBlocks[1], etc. + // The block member is set for statements that begin a new block. This + // block is the target of any branch to the statement. Statements may have + // additional (unstructured) "local" blocks, but such blocks cannot be the + // target of any explicit branch. The primary example of an (unstructured) + // statement that may have multiple associated blocks is NonLabelDoStmt, + // which may have a loop preheader block for loop initialization code (the + // block member), and always has a "local" header block that is the target + // of the loop back edge. If the NonLabelDoStmt is a concurrent loop, it + // may be associated with an arbitrary number of nested preheader, header, + // and mask blocks. // // The printIndex member is only set for statements. It is used for dumps - // and does not affect FIR generation. It may also be helpful for debugging. + // (and debugging) and does not affect FIR generation. - ParentVariant parentVariant; + PftNode parent; parser::CharBlock position{}; std::optional label{}; std::unique_ptr evaluationList; // nested evaluations @@ -331,9 +332,8 @@ struct Evaluation : EvaluationVariant { Evaluation *constructExit{nullptr}; // set for constructs bool isNewBlock{false}; // evaluation begins a new basic block bool isUnstructured{false}; // evaluation has unstructured control flow - bool skip{false}; // evaluation has been processed in advance - mlir::Block *block{nullptr}; // isNewBlock block - llvm::SmallVector localBlocks{}; // construct local blocks + bool negateCondition{false}; // If[Then]Stmt condition must be negated + mlir::Block *block{nullptr}; // isNewBlock block (ActionStmt, ConstructStmt) int printIndex{0}; // (ActionStmt, ConstructStmt) evaluation index for dumps }; @@ -341,49 +341,201 @@ using ProgramVariant = ReferenceVariant; + parser::BlockData, parser::CompilerDirective>; /// A program is a list of program units. /// These units can be function like, module like, or block data. struct ProgramUnit : ProgramVariant { template - ProgramUnit(const A &p, const ParentVariant &parentVariant) - : ProgramVariant{p}, parentVariant{parentVariant} {} + ProgramUnit(const A &p, const PftNode &parent) + : ProgramVariant{p}, parent{parent} {} ProgramUnit(ProgramUnit &&) = default; ProgramUnit(const ProgramUnit &) = delete; - ParentVariant parentVariant; + PftNode parent; }; /// A variable captures an object to be created per the declaration part of a /// function like unit. /// +/// Fortran EQUIVALENCE statements are a mechanism that introduces aliasing +/// between named variables. The set of overlapping aliases will materialize a +/// generic store object with a designated offset and size. Participant +/// symbols will simply be pointers into the aggregate store. +/// +/// EQUIVALENCE can also interact with COMMON and other global variables to +/// imply aliasing between (subparts of) a global and other local variable +/// names. +/// /// Properties can be applied by lowering. For example, a local array that is /// known to be very large may be transformed into a heap allocated entity by /// lowering. That decision would be tracked in its Variable instance. struct Variable { + /// Most variables are nominal and require the allocation of local/global + /// storage space. A nominal variable may also be an alias for some other + /// (subpart) of storage. + struct Nominal { + Nominal(const semantics::Symbol *symbol, int depth, bool global) + : symbol{symbol}, depth{depth}, global{global} {} + const semantics::Symbol *symbol{}; + + bool isGlobal() const { return global; } + bool isDeclaration() const { + return !symbol || symbol != &symbol->GetUltimate(); + } + + int depth{}; + bool global{}; + bool heapAlloc{}; // variable needs deallocation on exit + bool pointer{}; + bool target{}; + bool aliaser{}; // participates in EQUIVALENCE union + std::size_t aliasOffset{}; + }; + + using Interval = std::tuple; + + /// An interval of storage is a contiguous block of memory to be allocated or + /// mapped onto another variable. Aliasing variables will be pointers into + /// interval stores and may overlap each other. + struct AggregateStore { + AggregateStore(Interval &&interval, const Fortran::semantics::Scope &scope, + bool isDeclaration = false) + : interval{std::move(interval)}, scope{&scope}, isDecl{isDeclaration} {} + AggregateStore(Interval &&interval, const Fortran::semantics::Scope &scope, + const llvm::SmallVector &vars, + bool isDeclaration = false) + : interval{std::move(interval)}, scope{&scope}, vars{vars}, + isDecl{isDeclaration} {} + + bool isGlobal() const { return vars.size() > 0; } + bool isDeclaration() const { return isDecl; } + /// Get offset of the aggregate inside its scope. + std::size_t getOffset() const { return std::get<0>(interval); } + + Interval interval{}; + /// scope in which the interval is. + const Fortran::semantics::Scope *scope; + llvm::SmallVector vars{}; + /// Is this a declaration of a storage defined in another scope ? + bool isDecl; + }; + explicit Variable(const Fortran::semantics::Symbol &sym, bool global = false, int depth = 0) - : sym{&sym}, depth{depth}, global{global} {} + : var{Nominal(&sym, depth, global)} {} + explicit Variable(AggregateStore &&istore) : var{std::move(istore)} {} + + /// Return the front-end symbol for a nominal variable. + const Fortran::semantics::Symbol &getSymbol() const { + assert(hasSymbol() && "variable is not nominal"); + return *std::get(var).symbol; + } + + /// Return the aggregate store. + const AggregateStore &getAggregateStore() const { + assert(isAggregateStore()); + return std::get(var); + } + + /// Return the interval range of an aggregate store. + const Interval &getInterval() const { + assert(isAggregateStore()); + return std::get(var).interval; + } + + /// Only nominal variable have front-end symbols. + bool hasSymbol() const { return std::holds_alternative(var); } + + /// Is this an aggregate store? + bool isAggregateStore() const { + return std::holds_alternative(var); + } + + /// Is this variable a global? + bool isGlobal() const { + return std::visit([](const auto &x) { return x.isGlobal(); }, var); + } + + /// Is this a declaration of a variable owned by another scope ? + bool isDeclaration() const { + return std::visit([](const auto &x) { return x.isDeclaration(); }, var); + } + + const Fortran::semantics::Scope *getOwningScope() const { + return std::visit( + common::visitors{ + [](const Nominal &x) { return &x.symbol->GetUltimate().owner(); }, + [](const AggregateStore &agg) { return agg.scope; }}, + var); + } + + bool isHeapAlloc() const { + if (const auto *s = std::get_if(&var)) + return s->heapAlloc; + return false; + } + bool isPointer() const { + if (const auto *s = std::get_if(&var)) + return s->pointer; + return false; + } + bool isTarget() const { + if (const auto *s = std::get_if(&var)) + return s->target; + return false; + } - const Fortran::semantics::Symbol &getSymbol() const { return *sym; } + /// An alias(er) is a variable that is part of a EQUIVALENCE that is allocated + /// locally on the stack. + bool isAlias() const { + if (const auto *s = std::get_if(&var)) + return s->aliaser; + return false; + } + std::size_t getAlias() const { + if (auto *s = std::get_if(&var)) + return s->aliasOffset; + return 0; + } + void setAlias(std::size_t offset) { + if (auto *s = std::get_if(&var)) { + s->aliaser = true; + s->aliasOffset = offset; + } else { + llvm_unreachable("not a nominal var"); + } + } - bool isGlobal() const { return global; } - bool isHeapAlloc() const { return heapAlloc; } - bool isPointer() const { return pointer; } - bool isTarget() const { return target; } - int getDepth() const { return depth; } + void setHeapAlloc(bool to = true) { + if (auto *s = std::get_if(&var)) + s->heapAlloc = to; + else + llvm_unreachable("not a nominal var"); + } + void setPointer(bool to = true) { + if (auto *s = std::get_if(&var)) + s->pointer = to; + else + llvm_unreachable("not a nominal var"); + } + void setTarget(bool to = true) { + if (auto *s = std::get_if(&var)) + s->target = to; + else + llvm_unreachable("not a nominal var"); + } - void setHeapAlloc(bool to = true) { heapAlloc = to; } - void setPointer(bool to = true) { pointer = to; } - void setTarget(bool to = true) { target = to; } + /// The depth is recorded for nominal variables as a debugging aid. + int getDepth() const { + if (const auto *s = std::get_if(&var)) + return s->depth; + return 0; + } + + LLVM_DUMP_METHOD void dump() const; private: - const Fortran::semantics::Symbol *sym; - int depth; - bool global; - bool heapAlloc{false}; // variable needs deallocation on exit - bool pointer{false}; - bool target{false}; + std::variant var; }; /// Function-like units may contain evaluations (executable statements) and @@ -401,22 +553,30 @@ struct FunctionLikeUnit : public ProgramUnit { parser::Statement>; FunctionLikeUnit( - const parser::MainProgram &f, const ParentVariant &parentVariant, + const parser::MainProgram &f, const PftNode &parent, const Fortran::semantics::SemanticsContext &semanticsContext); FunctionLikeUnit( - const parser::FunctionSubprogram &f, const ParentVariant &parentVariant, + const parser::FunctionSubprogram &f, const PftNode &parent, const Fortran::semantics::SemanticsContext &semanticsContext); FunctionLikeUnit( - const parser::SubroutineSubprogram &f, const ParentVariant &parentVariant, + const parser::SubroutineSubprogram &f, const PftNode &parent, const Fortran::semantics::SemanticsContext &semanticsContext); FunctionLikeUnit( - const parser::SeparateModuleSubprogram &f, - const ParentVariant &parentVariant, + const parser::SeparateModuleSubprogram &f, const PftNode &parent, const Fortran::semantics::SemanticsContext &semanticsContext); FunctionLikeUnit(FunctionLikeUnit &&) = default; FunctionLikeUnit(const FunctionLikeUnit &) = delete; - void processSymbolTable(const Fortran::semantics::Scope &); + /// Return true iff this function like unit is Fortran recursive (actually + /// meaning it's reentrant). + bool isRecursive() const { + if (isMainProgram()) + return false; + const auto &sym = getSubprogramSymbol(); + return sym.attrs().test(semantics::Attr::RECURSIVE) || + (!sym.attrs().test(semantics::Attr::NON_RECURSIVE) && + defaultRecursiveFunctionSetting()); + } std::vector getOrderedSymbolTable() { return varList[0]; } @@ -433,18 +593,36 @@ struct FunctionLikeUnit : public ProgramUnit { return stmtSourceLoc(endStmt); } - /// Returns reference to the subprogram symbol of this FunctionLikeUnit. - /// Dies if the FunctionLikeUnit is not a subprogram. + void setActiveEntry(int entryIndex) { + assert(entryIndex >= 0 && entryIndex < (int)entryPointList.size() && + "invalid entry point index"); + activeEntry = entryIndex; + } + + /// Return a reference to the subprogram symbol of this FunctionLikeUnit. + /// This should not be called if the FunctionLikeUnit is the main program + /// since anonymous main programs do not have a symbol. const semantics::Symbol &getSubprogramSymbol() const { - assert(symbol && "not inside a procedure"); + const auto *symbol = entryPointList[activeEntry].first; + if (!symbol) + llvm::report_fatal_error( + "not inside a procedure; do not call on main program."); return *symbol; } + /// Return a pointer to the current entry point Evaluation. + /// This is null for a primary entry point. + Evaluation *getEntryEval() const { + return entryPointList[activeEntry].second; + } + /// Helper to get location from FunctionLikeUnit begin/end statements. static parser::CharBlock stmtSourceLoc(const FunctionStatement &stmt) { return stmt.visit(common::visitors{[](const auto &x) { return x.source; }}); } + LLVM_DUMP_METHOD void dump() const; + /// Anonymous programs do not have a begin statement std::optional beginStmt; FunctionStatement endStmt; @@ -452,11 +630,20 @@ struct FunctionLikeUnit : public ProgramUnit { LabelEvalMap labelEvaluationMap; SymbolLabelMap assignSymbolLabelMap; std::list nestedFunctions; - /// Symbol associated to this FunctionLikeUnit. - /// Null if the FunctionLikeUnit is an anonymous program. - /// The symbol has MainProgramDetails for named programs, otherwise it has - /// SubprogramDetails. - const semantics::Symbol *symbol{nullptr}; + /// pairs for each entry point. The pair at index 0 + /// is the primary entry point; remaining pairs are alternate entry points. + /// The primary entry point symbol is Null for an anonymous program. + /// A named program symbol has MainProgramDetails. Other symbols have + /// SubprogramDetails. Evaluations are filled in for alternate entries. + llvm::SmallVector, 1> + entryPointList{std::pair{nullptr, nullptr}}; + /// Current index into entryPointList. Index 0 is the primary entry point. + int activeEntry = 0; + /// Dummy arguments that are not universal across entry points. + llvm::SmallVector nonUniversalDummyArguments; + /// Primary result for function subprograms with alternate entries. This + /// is one of the largest result values, not necessarily the first one. + const semantics::Symbol *primaryResult{nullptr}; /// Terminal basic block (if any) mlir::Block *finalBlock{}; std::vector> varList; @@ -471,44 +658,66 @@ struct ModuleLikeUnit : public ProgramUnit { parser::Statement, parser::Statement>; - ModuleLikeUnit(const parser::Module &m, const ParentVariant &parentVariant); - ModuleLikeUnit(const parser::Submodule &m, - const ParentVariant &parentVariant); + ModuleLikeUnit(const parser::Module &m, const PftNode &parent); + ModuleLikeUnit(const parser::Submodule &m, const PftNode &parent); ~ModuleLikeUnit() = default; ModuleLikeUnit(ModuleLikeUnit &&) = default; ModuleLikeUnit(const ModuleLikeUnit &) = delete; + LLVM_DUMP_METHOD void dump() const; + + std::vector getOrderedSymbolTable() { return varList[0]; } + ModuleStatement beginStmt; ModuleStatement endStmt; std::list nestedFunctions; + std::vector> varList; }; +/// Block data units contain the variables and data initializers for common +/// blocks, etc. struct BlockDataUnit : public ProgramUnit { - BlockDataUnit(const parser::BlockData &bd, - const ParentVariant &parentVariant); + BlockDataUnit(const parser::BlockData &bd, const PftNode &parent, + const Fortran::semantics::SemanticsContext &semanticsContext); BlockDataUnit(BlockDataUnit &&) = default; BlockDataUnit(const BlockDataUnit &) = delete; + + LLVM_DUMP_METHOD void dump() const; + + const Fortran::semantics::Scope &symTab; // symbol table +}; + +// Top level compiler directives +struct CompilerDirectiveUnit : public ProgramUnit { + CompilerDirectiveUnit(const parser::CompilerDirective &directive, + const PftNode &parent) + : ProgramUnit{directive, parent} {}; + CompilerDirectiveUnit(CompilerDirectiveUnit &&) = default; + CompilerDirectiveUnit(const CompilerDirectiveUnit &) = delete; }; /// A Program is the top-level root of the PFT. struct Program { - using Units = std::variant; + using Units = std::variant; Program() = default; Program(Program &&) = default; Program(const Program &) = delete; + const std::list &getUnits() const { return units; } std::list &getUnits() { return units; } /// LLVM dump method on a Program. - void dump(); + LLVM_DUMP_METHOD void dump() const; private: std::list units; }; -} // namespace pft +} // namespace Fortran::lower::pft +namespace Fortran::lower { /// Create a PFT (Pre-FIR Tree) from the parse tree. /// /// A PFT is a light weight tree over the parse tree that is used to create FIR. @@ -522,9 +731,8 @@ createPFT(const parser::Program &root, const Fortran::semantics::SemanticsContext &semanticsContext); /// Dumper for displaying a PFT. -void dumpPFT(llvm::raw_ostream &outputStream, pft::Program &pft); +void dumpPFT(llvm::raw_ostream &outputStream, const pft::Program &pft); -} // namespace lower -} // namespace Fortran +} // namespace Fortran::lower #endif // FORTRAN_LOWER_PFTBUILDER_H diff --git a/flang/include/flang/Lower/PFTDefs.h b/flang/include/flang/Lower/PFTDefs.h new file mode 100644 index 000000000000..4dc31756ea4a --- /dev/null +++ b/flang/include/flang/Lower/PFTDefs.h @@ -0,0 +1,62 @@ +//===-- Lower/PFTDefs.h -- shared PFT info ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_PFTDEFS_H +#define FORTRAN_LOWER_PFTDEFS_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringRef.h" + +namespace mlir { +class Block; +} + +namespace Fortran { +namespace semantics { +class Symbol; +class SemanticsContext; +class Scope; +} // namespace semantics + +namespace evaluate { +template +class Expr; +struct SomeType; +} // namespace evaluate + +namespace common { +template +class Reference; +} + +namespace lower { + +bool definedInCommonBlock(const semantics::Symbol &sym); +bool defaultRecursiveFunctionSetting(); + +namespace pft { + +struct Evaluation; + +using SomeExpr = Fortran::evaluate::Expr; +using SymbolRef = Fortran::common::Reference; +using Label = std::uint64_t; +using LabelSet = llvm::SmallSet; +using SymbolLabelMap = llvm::DenseMap; +using LabelEvalMap = llvm::DenseMap; + +} // namespace pft +} // namespace lower +} // namespace Fortran + +#endif // FORTRAN_LOWER_PFTDEFS_H diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h new file mode 100644 index 000000000000..7884634d6607 --- /dev/null +++ b/flang/include/flang/Lower/Support/Utils.h @@ -0,0 +1,49 @@ +//===-- Lower/Support/Utils.h -- utilities ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_SUPPORT_UTILS_H +#define FORTRAN_LOWER_SUPPORT_UTILS_H + +#include "flang/Common/indirection.h" +#include "flang/Parser/char-block.h" +#include "mlir/Dialect/StandardOps/IR/Ops.h" +#include "mlir/IR/BuiltinAttributes.h" +#include "llvm/ADT/StringRef.h" +#include + +//===----------------------------------------------------------------------===// +// Small inline helper functions to deal with repetitive, clumsy conversions. +//===----------------------------------------------------------------------===// + +/// Convert an F18 CharBlock to an LLVM StringRef. +inline llvm::StringRef toStringRef(const Fortran::parser::CharBlock &cb) { + return {cb.begin(), cb.size()}; +} + +namespace fir { +/// Return the integer value of a ConstantOp. +inline std::int64_t toInt(mlir::ConstantOp cop) { + return cop.getValue().cast().getValue().getSExtValue(); +} +} // namespace fir + +/// Template helper to remove Fortran::common::Indirection wrappers. +template +const A &removeIndirection(const A &a) { + return a; +} +template +const A &removeIndirection(const Fortran::common::Indirection &a) { + return a.value(); +} + +#endif // FORTRAN_LOWER_SUPPORT_UTILS_H diff --git a/flang/include/flang/Optimizer/CodeGen/CGOps.td b/flang/include/flang/Optimizer/CodeGen/CGOps.td new file mode 100644 index 000000000000..9ebda32825a6 --- /dev/null +++ b/flang/include/flang/Optimizer/CodeGen/CGOps.td @@ -0,0 +1,177 @@ +//===-- CGOps.td - FIR operation definitions ---------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Definition of the FIRCG dialect operations +/// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_DIALECT_FIRCG_OPS +#define FORTRAN_DIALECT_FIRCG_OPS + +include "mlir/IR/SymbolInterfaces.td" +include "flang/Optimizer/Dialect/FIRTypes.td" + +def fircg_Dialect : Dialect { + let name = "fircg"; + let cppNamespace = "::fir::cg"; +} + +// Base class for FIR CG operations. +// All operations automatically get a prefix of "fircg.". +class fircg_Op traits> + : Op; + +// Extended embox operation. +def fircg_XEmboxOp : fircg_Op<"ext_embox", [AttrSizedOperandSegments]> { + let summary = "for internal conversion only"; + + let description = [{ + Prior to lowering to LLVM IR dialect, a non-scalar non-trivial embox op will + be converted to an extended embox. This op will have the following sets of + arguments. + + - memref: The memory reference being emboxed. + - shape: A vector that is the runtime shape of the underlying array. + - shift: A vector that is the runtime origin of the first element. + The default is a vector of the value 1. + - slice: A vector of triples that describe an array slice. + - subcomponent: A vector of indices for subobject slicing. + - LEN type parameters: A vector of runtime LEN type parameters that + describe an correspond to the elemental derived type. + + The memref and shape arguments are mandatory. The rest are optional. + }]; + + let arguments = (ins + AnyReferenceLike:$memref, + Variadic:$shape, + Variadic:$shift, + Variadic:$slice, + Variadic:$subcomponent, + Variadic:$lenParams + ); + let results = (outs fir_BoxType); + + let assemblyFormat = [{ + $memref (`(`$shape^`)`)? (`origin` $shift^)? (`[`$slice^`]`)? + (`path` $subcomponent^)? (`typeparams` $lenParams^)? attr-dict + `:` functional-type(operands, results) + }]; + + let extraClassDeclaration = [{ + // The rank of the entity being emboxed + unsigned getRank() { return shape().size(); } + + // The rank of the result. A slice op can reduce the rank. + unsigned getOutRank(); + + // The shape operands are mandatory and always start at 1. + unsigned shapeOffset() { return 1; } + unsigned shiftOffset() { return shapeOffset() + shape().size(); } + unsigned sliceOffset() { return shiftOffset() + shift().size(); } + unsigned subcomponentOffset() { return sliceOffset() + slice().size(); } + unsigned lenParamOffset() { + return subcomponentOffset() + subcomponent().size(); + } + }]; +} + +// Extended rebox operation. +def fircg_XReboxOp : fircg_Op<"ext_rebox", [AttrSizedOperandSegments]> { + let summary = "for internal conversion only"; + + let description = [{ + Prior to lowering to LLVM IR dialect, a non-scalar non-trivial rebox op will + be converted to an extended rebox. This op will have the following sets of + arguments. + + - box: The box being reboxed. + - shape: A vector that is the new runtime shape for the array + - shift: A vector that is the new runtime origin of the first element. + The default is a vector of the value 1. + - slice: A vector of triples that describe an array slice. + - subcomponent: A vector of indices for subobject slicing. + + The box argument is mandatory, the other arguments are optional. + There must not both be a shape and slice/subcomponent arguments + }]; + + let arguments = (ins + fir_BoxType:$box, + Variadic:$shape, + Variadic:$shift, + Variadic:$slice, + Variadic:$subcomponent + ); + let results = (outs fir_BoxType); + + let assemblyFormat = [{ + $box (`(`$shape^`)`)? (`origin` $shift^)? (`[`$slice^`]`)? + (`path` $subcomponent^) ? attr-dict + `:` functional-type(operands, results) + }]; + + let extraClassDeclaration = [{ + // The rank of the entity being reboxed + unsigned getRank(); + // The rank of the result box + unsigned getOutRank(); + }]; +} + + +// Extended array coordinate operation. +def fircg_XArrayCoorOp : fircg_Op<"ext_array_coor", [AttrSizedOperandSegments]> { + let summary = "for internal conversion only"; + + let description = [{ + Prior to lowering to LLVM IR dialect, a non-scalar non-trivial embox op will + be converted to an extended embox. This op will have the following sets of + arguments. + + - memref: The memory reference of the array's data. It can be a fir.box if + the underlying data is not contiguous. + - shape: A vector that is the runtime shape of the underlying array. + - shift: A vector that is the runtime origin of the first element. + The default is a vector of the value 1. + - slice: A vector of triples that describe an array slice. + - subcomponent: A vector of indices that describe subobject slicing. + - indices: A vector of runtime values that describe the coordinate of + the element of the array to be computed. + - LEN type parameters: A vector of runtime LEN type parameters that + describe an correspond to the elemental derived type. + + The memref and indices arguments are mandatory. + The shape argument is mandatory if the memref is not a box, and should be + omitted otherwise. The rest of the arguments are optional. + }]; + + let arguments = (ins + AnyRefOrBox:$memref, + Variadic:$shape, + Variadic:$shift, + Variadic:$slice, + Variadic:$subcomponent, + Variadic:$indices, + Variadic:$lenParams + ); + let results = (outs fir_ReferenceType); + + let assemblyFormat = [{ + $memref (`(`$shape^`)`)? (`origin` $shift^)? (`[`$slice^`]`)? + (`path` $subcomponent^)? `<`$indices`>` (`typeparams` $lenParams^)? + attr-dict `:` functional-type(operands, results) + }]; + + let extraClassDeclaration = [{ + unsigned getRank(); + }]; +} + +#endif diff --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td index 46442a281606..ffe829644d1a 100644 --- a/flang/include/flang/Optimizer/CodeGen/CGPasses.td +++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td @@ -11,18 +11,24 @@ // //===----------------------------------------------------------------------===// -#ifndef FLANG_OPTIMIZER_CODEGEN_PASSES -#define FLANG_OPTIMIZER_CODEGEN_PASSES +#ifndef FORTRAN_OPTIMIZER_CODEGEN_FIR_PASSES +#define FORTRAN_OPTIMIZER_CODEGEN_FIR_PASSES include "mlir/Pass/PassBase.td" -def CodeGenRewrite : Pass<"cg-rewrite", "mlir::ModuleOp"> { +def CodeGenRewrite : Pass<"cg-rewrite"> { let summary = "Rewrite some FIR ops into their code-gen forms."; let description = [{ Fuse specific subgraphs into single Ops for code generation. }]; let constructor = "fir::createFirCodeGenRewritePass()"; - let dependentDialects = ["fir::FIROpsDialect"]; + let dependentDialects = [ + "fir::FIROpsDialect", "fir::FIRCodeGenDialect", "mlir::BuiltinDialect", + "mlir::LLVM::LLVMDialect", "mlir::omp::OpenMPDialect" + ]; + let statistics = [ + Statistic<"numDCE", "num-dce'd", "Number of operations eliminated"> + ]; } -#endif // FLANG_OPTIMIZER_CODEGEN_PASSES +#endif // FORTRAN_OPTIMIZER_CODEGEN_FIR_PASSES diff --git a/flang/include/flang/Optimizer/CodeGen/CMakeLists.txt b/flang/include/flang/Optimizer/CodeGen/CMakeLists.txt index 8cbd772b30ab..3eda75190ba2 100644 --- a/flang/include/flang/Optimizer/CodeGen/CMakeLists.txt +++ b/flang/include/flang/Optimizer/CodeGen/CMakeLists.txt @@ -1,3 +1,7 @@ +set(LLVM_TARGET_DEFINITIONS CGOps.td) +mlir_tablegen(CGOps.h.inc -gen-op-decls) +mlir_tablegen(CGOps.cpp.inc -gen-op-defs) +add_public_tablegen_target(CGOpsIncGen) set(LLVM_TARGET_DEFINITIONS CGPasses.td) mlir_tablegen(CGPasses.h.inc -gen-pass-decls -name OptCodeGen) diff --git a/flang/include/flang/Optimizer/Dialect/FIRDialect.h b/flang/include/flang/Optimizer/Dialect/FIRDialect.h index fb82d520dbc2..fb828716d45a 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRDialect.h +++ b/flang/include/flang/Optimizer/Dialect/FIRDialect.h @@ -32,6 +32,22 @@ class FIROpsDialect final : public mlir::Dialect { mlir::Type type) const override; void printAttribute(mlir::Attribute attr, mlir::DialectAsmPrinter &p) const override; + +private: + // Register the Attributes of this dialect. + void registerAttributes(); + // Register the Types of this dialect. + void registerTypes(); +}; + +/// The FIR codegen dialect is a dialect containing a small set of transient +/// operations used exclusively during code generation. +class FIRCodeGenDialect final : public mlir::Dialect { +public: + explicit FIRCodeGenDialect(mlir::MLIRContext *ctx); + virtual ~FIRCodeGenDialect(); + + static llvm::StringRef getDialectNamespace() { return "fircg"; } }; } // namespace fir diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index a039001cb079..a38630b2a04f 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2795,18 +2795,7 @@ class RealArithmeticOp traits = []> : fir_ArithmeticOp, Arguments<(ins AnyRealLike:$lhs, AnyRealLike:$rhs)>; -def fir_AddfOp : RealArithmeticOp<"addf", [Commutative]> { - let hasFolder = 1; -} -def fir_SubfOp : RealArithmeticOp<"subf"> { - let hasFolder = 1; -} -def fir_MulfOp : RealArithmeticOp<"mulf", [Commutative]> { - let hasFolder = 1; -} -def fir_DivfOp : RealArithmeticOp<"divf">; def fir_ModfOp : RealArithmeticOp<"modf">; -// Pow is a builtin call and not a primitive def fir_CmpfOp : fir_Op<"cmpf", [NoSideEffect, SameTypeOperands, SameOperandsAndResultShape]> { diff --git a/flang/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h index cb2dd4f4776b..194d42a41a1c 100644 --- a/flang/include/flang/Optimizer/Support/InitFIR.h +++ b/flang/include/flang/Optimizer/Support/InitFIR.h @@ -21,15 +21,16 @@ #include "mlir/Pass/PassRegistry.h" #include "mlir/Transforms/LocationSnapshot.h" #include "mlir/Transforms/Passes.h" +#include "flang/Optimizer/CodeGen/CodeGen.h" namespace fir::support { // The definitive list of dialects used by flang. #define FLANG_DIALECT_LIST \ - mlir::AffineDialect, FIROpsDialect, mlir::LLVM::LLVMDialect, \ - mlir::acc::OpenACCDialect, mlir::omp::OpenMPDialect, \ - mlir::scf::SCFDialect, mlir::StandardOpsDialect, \ - mlir::vector::VectorDialect + mlir::AffineDialect, FIROpsDialect, FIRCodeGenDialect, \ + mlir::LLVM::LLVMDialect, mlir::acc::OpenACCDialect, \ + mlir::omp::OpenMPDialect, mlir::scf::SCFDialect, \ + mlir::StandardOpsDialect, mlir::vector::VectorDialect /// Register all the dialects used by flang. inline void registerDialects(mlir::DialectRegistry ®istry) { @@ -45,7 +46,7 @@ inline void loadDialects(mlir::MLIRContext &context) { /// Register the standard passes we use. This comes from registerAllPasses(), /// but is a smaller set since we aren't using many of the passes found there. -inline void registerFIRPasses() { +inline void registerMLIRPassesForFortranTools() { mlir::registerCanonicalizerPass(); mlir::registerCSEPass(); mlir::registerAffineLoopFusionPass(); @@ -69,6 +70,9 @@ inline void registerFIRPasses() { mlir::registerAffineDataCopyGenerationPass(); mlir::registerConvertAffineToStandardPass(); + + // Flang passes + fir::registerOptCodeGenPasses(); } } // namespace fir::support diff --git a/flang/include/flang/Parser/char-block.h b/flang/include/flang/Parser/char-block.h index 7c29c9aa41a0..0f5758f8c552 100644 --- a/flang/include/flang/Parser/char-block.h +++ b/flang/include/flang/Parser/char-block.h @@ -138,6 +138,13 @@ inline bool operator>(const char *left, const CharBlock &right) { return right < left; } +// An alternative comparator based on pointer values; use with care! +struct CharBlockPointerComparator { + bool operator()(CharBlock x, CharBlock y) const { + return x.end() < y.begin(); + } +}; + llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const CharBlock &x); } // namespace Fortran::parser diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index bc0fd388b11c..150b011ad8ba 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -793,7 +793,7 @@ class ParseTreeDumper { template std::string AsFortran(const T &x) { std::string buf; llvm::raw_string_ostream ss{buf}; - if constexpr (std::is_same_v) { + if constexpr (HasTypedExpr::value) { if (asFortran_ && x.typedExpr) { asFortran_->expr(ss, *x.typedExpr); } diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index dcc38090a3a1..152c2c8c9076 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -1836,6 +1836,7 @@ struct ArrayElement { // R933 allocate-object -> variable-name | structure-component struct AllocateObject { UNION_CLASS_BOILERPLATE(AllocateObject); + mutable TypedExpr typedExpr; std::variant u; }; @@ -1907,6 +1908,7 @@ struct AllocateStmt { // variable-name | structure-component | proc-pointer-name struct PointerObject { UNION_CLASS_BOILERPLATE(PointerObject); + mutable TypedExpr typedExpr; std::variant u; }; diff --git a/flang/include/flang/Parser/provenance.h b/flang/include/flang/Parser/provenance.h index bce79809c766..7ff475a2316a 100644 --- a/flang/include/flang/Parser/provenance.h +++ b/flang/include/flang/Parser/provenance.h @@ -47,6 +47,7 @@ namespace Fortran::parser { // necessary.) class AllSources; +class AllCookedSources; class Provenance { public: @@ -219,6 +220,9 @@ class AllSources { // single instances of CookedSource. class CookedSource { public: + int number() const { return number_; } + void set_number(int n) { number_ = n; } + CharBlock AsCharBlock() const { return CharBlock{data_}; } std::optional GetProvenanceRange(CharBlock) const; std::optional GetCharBlock(ProvenanceRange) const; @@ -242,11 +246,12 @@ class CookedSource { } std::size_t BufferedBytes() const; - void Marshal(AllSources &); // marshals text into one contiguous block + void Marshal(AllCookedSources &); // marshals text into one contiguous block void CompileProvenanceRangeToOffsetMappings(AllSources &); llvm::raw_ostream &Dump(llvm::raw_ostream &) const; private: + int number_{0}; // for sorting purposes CharBuffer buffer_; // before Marshal() std::string data_; // all of it, prescanned and preprocessed OffsetToProvenanceMappings provenanceMap_; @@ -263,15 +268,8 @@ class AllCookedSources { CookedSource &NewCookedSource(); - template // const char * or CharBlock - const CookedSource *Find(A x) const { - for (const auto &c : cooked_) { - if (c.AsCharBlock().Contains(x)) { - return &c; - } - } - return nullptr; - } + const CookedSource *Find(CharBlock) const; + const CookedSource *Find(const char *p) const { return Find(CharBlock{p}); } bool IsValid(ProvenanceRange r) const { return allSources_.IsValid(r); } @@ -283,9 +281,29 @@ class AllCookedSources { std::optional GetCharBlock(ProvenanceRange) const; void Dump(llvm::raw_ostream &) const; + // For sorting symbol names without being dependent on pointer values + bool Precedes(CharBlock, CharBlock) const; + + // Once a CookedSource is complete, add it to index_ and assign its number_ + void Register(CookedSource &); + private: AllSources &allSources_; std::list cooked_; // owns all CookedSource instances + std::map index_; }; + +// For use as a Comparator for maps, sets, sorting, &c. +class CharBlockComparator { +public: + explicit CharBlockComparator(const AllCookedSources &all) : all_{all} {} + bool operator()(CharBlock x, CharBlock y) const { + return all_.Precedes(x, y); + } + +private: + const AllCookedSources &all_; +}; + } // namespace Fortran::parser #endif // FORTRAN_PARSER_PROVENANCE_H_ diff --git a/flang/include/flang/Parser/tools.h b/flang/include/flang/Parser/tools.h index 66c8793399c9..ccd49d2a790e 100644 --- a/flang/include/flang/Parser/tools.h +++ b/flang/include/flang/Parser/tools.h @@ -117,5 +117,10 @@ template struct HasSource(A::source), 0)> : std::true_type {}; +// Detects parse tree nodes with "typedExpr" members. +template struct HasTypedExpr : std::false_type {}; +template +struct HasTypedExpr(A::typedExpr), 0)> + : std::true_type {}; } // namespace Fortran::parser #endif // FORTRAN_PARSER_TOOLS_H_ diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h index f81d5199dc20..2f89820f4b0b 100644 --- a/flang/include/flang/Semantics/expression.h +++ b/flang/include/flang/Semantics/expression.h @@ -74,14 +74,13 @@ struct SetExprHelper { x.Reset(new GenericExprWrapper{std::move(expr_)}, evaluate::GenericExprWrapper::Deleter); } - void Set(const parser::Expr &x) { Set(x.typedExpr); } - void Set(const parser::Variable &x) { Set(x.typedExpr); } - void Set(const parser::DataStmtConstant &x) { Set(x.typedExpr); } template void Set(const common::Indirection &x) { Set(x.value()); } template void Set(const T &x) { - if constexpr (ConstraintTrait) { + if constexpr (parser::HasTypedExpr::value) { + Set(x.typedExpr); + } else if constexpr (ConstraintTrait) { Set(x.thing); } else if constexpr (WrapperTrait) { Set(x.v); @@ -157,6 +156,8 @@ class ExpressionAnalyzer { MaybeExpr Analyze(const parser::Variable &); MaybeExpr Analyze(const parser::Designator &); MaybeExpr Analyze(const parser::DataStmtValue &); + MaybeExpr Analyze(const parser::AllocateObject &); + MaybeExpr Analyze(const parser::PointerObject &); template MaybeExpr Analyze(const common::Indirection &x) { return Analyze(x.value()); @@ -451,6 +452,14 @@ class ExprChecker { exprAnalyzer_.Analyze(x); return false; } + bool Pre(const parser::AllocateObject &x) { + exprAnalyzer_.Analyze(x); + return false; + } + bool Pre(const parser::PointerObject &x) { + exprAnalyzer_.Analyze(x); + return false; + } bool Pre(const parser::DataImpliedDo &); bool Pre(const parser::CallStmt &x) { diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index 81840bdb0122..f1d5b0c87d48 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -62,9 +62,10 @@ class Scope { using ImportKind = common::ImportKind; // Create the Global scope -- the root of the scope tree - Scope() : Scope{*this, Kind::Global, nullptr} {} - Scope(Scope &parent, Kind kind, Symbol *symbol) - : parent_{parent}, kind_{kind}, symbol_{symbol} { + explicit Scope(SemanticsContext &context) + : Scope{*this, Kind::Global, nullptr, context} {} + Scope(Scope &parent, Kind kind, Symbol *symbol, SemanticsContext &context) + : parent_{parent}, kind_{kind}, symbol_{symbol}, context_{context} { if (symbol) { symbol->set_scope(this); } @@ -99,6 +100,7 @@ class Scope { } Symbol *symbol() { return symbol_; } const Symbol *symbol() const { return symbol_; } + SemanticsContext &context() const { return context_; } inline const Symbol *GetSymbol() const; const Scope *GetDerivedTypeParent() const; @@ -107,6 +109,9 @@ class Scope { bool Contains(const Scope &) const; /// Make a scope nested in this one Scope &MakeScope(Kind kind, Symbol *symbol = nullptr); + SemanticsContext &GetMutableSemanticsContext() const { + return const_cast(context()); + } using size_type = mapType::size_type; using iterator = mapType::iterator; @@ -244,7 +249,7 @@ class Scope { symbol_->test(Symbol::Flag::ModFile); } - void InstantiateDerivedTypes(SemanticsContext &); + void InstantiateDerivedTypes(); const Symbol *runtimeDerivedTypeDescription() const { return runtimeDerivedTypeDescription_; @@ -273,8 +278,9 @@ class Scope { parser::Message::Reference instantiationContext_; bool hasSAVE_{false}; // scope has a bare SAVE statement const Symbol *runtimeDerivedTypeDescription_{nullptr}; + SemanticsContext &context_; // When additional data members are added to Scope, remember to - // copy them, if appropriate, in InstantiateDerivedType(). + // copy them, if appropriate, in FindOrInstantiateDerivedType(). // Storage for all Symbols. Every Symbol is in allSymbols and every Symbol* // or Symbol& points to one in there. diff --git a/flang/include/flang/Semantics/semantics.h b/flang/include/flang/Semantics/semantics.h index e6202c666429..3ef0cafa872a 100644 --- a/flang/include/flang/Semantics/semantics.h +++ b/flang/include/flang/Semantics/semantics.h @@ -198,8 +198,9 @@ class SemanticsContext { parser::CharBlock location; IndexVarKind kind; }; - std::map activeIndexVars_; - SymbolSet errorSymbols_; + std::map + activeIndexVars_; + UnorderedSymbolSet errorSymbols_; std::set tempNames_; }; diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h index 55859696be52..4586ad9f864d 100644 --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include namespace llvm { @@ -60,7 +60,18 @@ class MainProgramDetails { private: }; -class SubprogramDetails { +class WithBindName { +public: + const std::string *bindName() const { + return bindName_ ? &*bindName_ : nullptr; + } + void set_bindName(std::string &&name) { bindName_ = std::move(name); } + +private: + std::optional bindName_; +}; + +class SubprogramDetails : public WithBindName { public: bool isFunction() const { return result_ != nullptr; } bool isInterface() const { return isInterface_; } @@ -68,8 +79,6 @@ class SubprogramDetails { Scope *entryScope() { return entryScope_; } const Scope *entryScope() const { return entryScope_; } void set_entryScope(Scope &scope) { entryScope_ = &scope; } - MaybeExpr bindName() const { return bindName_; } - void set_bindName(MaybeExpr &&expr) { bindName_ = std::move(expr); } const Symbol &result() const { CHECK(isFunction()); return *result_; @@ -86,7 +95,6 @@ class SubprogramDetails { private: bool isInterface_{false}; // true if this represents an interface-body - MaybeExpr bindName_; std::vector dummyArgs_; // nullptr -> alternate return indicator Symbol *result_{nullptr}; Scope *entryScope_{nullptr}; // if ENTRY, points to subprogram's scope @@ -117,7 +125,7 @@ class SubprogramNameDetails { }; // A name from an entity-decl -- could be object or function. -class EntityDetails { +class EntityDetails : public WithBindName { public: explicit EntityDetails(bool isDummy = false) : isDummy_{isDummy} {} const DeclTypeSpec *type() const { return type_; } @@ -127,14 +135,11 @@ class EntityDetails { void set_isDummy(bool value = true) { isDummy_ = value; } bool isFuncResult() const { return isFuncResult_; } void set_funcResult(bool x) { isFuncResult_ = x; } - MaybeExpr bindName() const { return bindName_; } - void set_bindName(MaybeExpr &&expr) { bindName_ = std::move(expr); } private: bool isDummy_{false}; bool isFuncResult_{false}; const DeclTypeSpec *type_{nullptr}; - MaybeExpr bindName_; friend llvm::raw_ostream &operator<<( llvm::raw_ostream &, const EntityDetails &); }; @@ -310,19 +315,16 @@ class NamelistDetails { SymbolVector objects_; }; -class CommonBlockDetails { +class CommonBlockDetails : public WithBindName { public: MutableSymbolVector &objects() { return objects_; } const MutableSymbolVector &objects() const { return objects_; } void add_object(Symbol &object) { objects_.emplace_back(object); } - MaybeExpr bindName() const { return bindName_; } - void set_bindName(MaybeExpr &&expr) { bindName_ = std::move(expr); } std::size_t alignment() const { return alignment_; } void set_alignment(std::size_t alignment) { alignment_ = alignment; } private: MutableSymbolVector objects_; - MaybeExpr bindName_; std::size_t alignment_{0}; // required alignment in bytes }; @@ -565,8 +567,10 @@ class Symbol { inline DeclTypeSpec *GetType(); inline const DeclTypeSpec *GetType() const; - void SetType(const DeclTypeSpec &); + + const std::string *GetBindName() const; + void SetBindName(std::string &&); bool IsFuncResult() const; bool IsObjectArray() const; bool IsSubprogram() const; @@ -595,10 +599,6 @@ class Symbol { bool operator==(const Symbol &that) const { return this == &that; } bool operator!=(const Symbol &that) const { return !(*this == that); } - bool operator<(const Symbol &that) const { - // For maps of symbols: collate them by source location - return name_.begin() < that.name_.begin(); - } int Rank() const { return std::visit( @@ -651,6 +651,8 @@ class Symbol { // for a parameterized derived type instantiation with the instance's scope. const DerivedTypeSpec *GetParentTypeSpec(const Scope * = nullptr) const; + SemanticsContext &GetSemanticsContext() const; + private: const Scope *owner_; SourceName name_; @@ -762,17 +764,40 @@ inline const DeclTypeSpec *Symbol::GetType() const { details_); } -inline bool operator<(SymbolRef x, SymbolRef y) { return *x < *y; } -inline bool operator<(MutableSymbolRef x, MutableSymbolRef y) { - return *x < *y; -} -struct SymbolHash { - std::size_t operator()(SymbolRef symRef) const { - std::hash hasher; - return hasher(symRef->name().ToString()); +// Sets and maps keyed by Symbols + +struct SymbolAddressCompare { + bool operator()(const SymbolRef &x, const SymbolRef &y) const { + return &*x < &*y; + } + bool operator()(const MutableSymbolRef &x, const MutableSymbolRef &y) const { + return &*x < &*y; } }; -using SymbolSet = std::unordered_set; + +// Symbol comparison is based on the order of cooked source +// stream creation and, when both are from the same cooked source, +// their positions in that cooked source stream. +// Don't use this comparator or OrderedSymbolSet to hold +// Symbols that might be subject to ReplaceName(). +struct SymbolSourcePositionCompare { + // These functions are implemented in Evaluate/tools.cpp to + // satisfy complicated shared library interdependency. + bool operator()(const SymbolRef &, const SymbolRef &) const; + bool operator()(const MutableSymbolRef &, const MutableSymbolRef &) const; +}; + +using UnorderedSymbolSet = std::set; +using OrderedSymbolSet = std::set; + +template +OrderedSymbolSet OrderBySourcePosition(const A &container) { + OrderedSymbolSet result; + for (SymbolRef x : container) { + result.emplace(x); + } + return result; +} } // namespace Fortran::semantics diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h index 3e8d1993f9a0..550cc99f85ef 100644 --- a/flang/include/flang/Semantics/tools.h +++ b/flang/include/flang/Semantics/tools.h @@ -257,9 +257,13 @@ bool ExprTypeKindIsDefault( const SomeExpr &expr, const SemanticsContext &context); struct GetExprHelper { + // Specializations for parse tree nodes that have a typedExpr member. static const SomeExpr *Get(const parser::Expr &); static const SomeExpr *Get(const parser::Variable &); static const SomeExpr *Get(const parser::DataStmtConstant &); + static const SomeExpr *Get(const parser::AllocateObject &); + static const SomeExpr *Get(const parser::PointerObject &); + template static const SomeExpr *Get(const common::Indirection &x) { return Get(x.value()); @@ -268,6 +272,8 @@ struct GetExprHelper { return x ? Get(*x) : nullptr; } template static const SomeExpr *Get(const T &x) { + static_assert( + !parser::HasTypedExpr::value, "explicit Get overload must be added"); if constexpr (ConstraintTrait) { return Get(x.thing); } else if constexpr (WrapperTrait) { diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp index 4d5436a9776c..c6d6afeb81d1 100644 --- a/flang/lib/Evaluate/characteristics.cpp +++ b/flang/lib/Evaluate/characteristics.cpp @@ -343,30 +343,29 @@ bool DummyProcedure::operator==(const DummyProcedure &that) const { procedure.value() == that.procedure.value(); } -static std::string GetSeenProcs(const semantics::SymbolSet &seenProcs) { +static std::string GetSeenProcs( + const semantics::UnorderedSymbolSet &seenProcs) { // Sort the symbols so that they appear in the same order on all platforms - std::vector sorter{seenProcs.begin(), seenProcs.end()}; - std::sort(sorter.begin(), sorter.end()); - + auto ordered{semantics::OrderBySourcePosition(seenProcs)}; std::string result; llvm::interleave( - sorter, + ordered, [&](const SymbolRef p) { result += '\'' + p->name().ToString() + '\''; }, [&]() { result += ", "; }); return result; } -// These functions with arguments of type SymbolSet are used with mutually -// recursive calls when characterizing a Procedure, a DummyArgument, or a -// DummyProcedure to detect circularly defined procedures as required by +// These functions with arguments of type UnorderedSymbolSet are used with +// mutually recursive calls when characterizing a Procedure, a DummyArgument, +// or a DummyProcedure to detect circularly defined procedures as required by // 15.4.3.6, paragraph 2. static std::optional CharacterizeDummyArgument( const semantics::Symbol &symbol, FoldingContext &context, - semantics::SymbolSet &seenProcs); + semantics::UnorderedSymbolSet &seenProcs); static std::optional CharacterizeProcedure( const semantics::Symbol &original, FoldingContext &context, - semantics::SymbolSet &seenProcs) { + semantics::UnorderedSymbolSet &seenProcs) { Procedure result; const auto &symbol{original.GetUltimate()}; if (seenProcs.find(symbol) != seenProcs.end()) { @@ -475,7 +474,7 @@ static std::optional CharacterizeProcedure( static std::optional CharacterizeDummyProcedure( const semantics::Symbol &symbol, FoldingContext &context, - semantics::SymbolSet &seenProcs) { + semantics::UnorderedSymbolSet &seenProcs) { if (auto procedure{CharacterizeProcedure(symbol, context, seenProcs)}) { // Dummy procedures may not be elemental. Elemental dummy procedure // interfaces are errors when the interface is not intrinsic, and that @@ -516,7 +515,7 @@ bool DummyArgument::operator==(const DummyArgument &that) const { static std::optional CharacterizeDummyArgument( const semantics::Symbol &symbol, FoldingContext &context, - semantics::SymbolSet &seenProcs) { + semantics::UnorderedSymbolSet &seenProcs) { auto name{symbol.name().ToString()}; if (symbol.has()) { if (auto obj{DummyDataObject::Characterize(symbol, context)}) { @@ -779,7 +778,7 @@ bool Procedure::CanOverride( std::optional Procedure::Characterize( const semantics::Symbol &original, FoldingContext &context) { - semantics::SymbolSet seenProcs; + semantics::UnorderedSymbolSet seenProcs; return CharacterizeProcedure(original, context, seenProcs); } diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp index 2e061f0fe3fe..418d16105365 100644 --- a/flang/lib/Evaluate/check-expression.cpp +++ b/flang/lib/Evaluate/check-expression.cpp @@ -39,7 +39,7 @@ class IsConstantExprHelper : public AllTraverse { return semantics::IsKindTypeParameter(inq.parameter()); } bool operator()(const semantics::Symbol &symbol) const { - const auto &ultimate{symbol.GetUltimate()}; + const auto &ultimate{GetAssociationRoot(symbol)}; return IsNamedConstant(ultimate) || IsImpliedDoIndex(ultimate) || IsInitialProcedureTarget(ultimate); } @@ -180,21 +180,19 @@ class IsInitialDataTargetHelper return false; } bool operator()(const semantics::Symbol &symbol) { + // This function checks only base symbols, not components. const Symbol &ultimate{symbol.GetUltimate()}; - if (IsAllocatable(ultimate)) { - if (messages_) { - messages_->Say( - "An initial data target may not be a reference to an ALLOCATABLE '%s'"_err_en_US, - ultimate.name()); - emittedMessage_ = true; - } - return false; - } else if (ultimate.Corank() > 0) { - if (messages_) { - messages_->Say( - "An initial data target may not be a reference to a coarray '%s'"_err_en_US, - ultimate.name()); - emittedMessage_ = true; + if (const auto *assoc{ + ultimate.detailsIf()}) { + if (const auto &expr{assoc->expr()}) { + if (IsVariable(*expr)) { + return (*this)(*expr); + } else if (messages_) { + messages_->Say( + "An initial data target may not be an associated expression ('%s')"_err_en_US, + ultimate.name()); + emittedMessage_ = true; + } } return false; } else if (!ultimate.attrs().test(semantics::Attr::TARGET)) { @@ -213,8 +211,9 @@ class IsInitialDataTargetHelper emittedMessage_ = true; } return false; + } else { + return CheckVarOrComponent(ultimate); } - return true; } bool operator()(const StaticDataObject &) const { return false; } bool operator()(const TypeParamInquiry &) const { return false; } @@ -233,6 +232,9 @@ class IsInitialDataTargetHelper x.u); } bool operator()(const CoarrayRef &) const { return false; } + bool operator()(const Component &x) { + return CheckVarOrComponent(x.GetLastSymbol()) && (*this)(x.base()); + } bool operator()(const Substring &x) const { return IsConstantExpr(x.lower()) && IsConstantExpr(x.upper()) && (*this)(x.parent()); @@ -258,6 +260,28 @@ class IsInitialDataTargetHelper bool operator()(const Relational &) const { return false; } private: + bool CheckVarOrComponent(const semantics::Symbol &symbol) { + const Symbol &ultimate{symbol.GetUltimate()}; + if (IsAllocatable(ultimate)) { + if (messages_) { + messages_->Say( + "An initial data target may not be a reference to an ALLOCATABLE '%s'"_err_en_US, + ultimate.name()); + emittedMessage_ = true; + } + return false; + } else if (ultimate.Corank() > 0) { + if (messages_) { + messages_->Say( + "An initial data target may not be a reference to a coarray '%s'"_err_en_US, + ultimate.name()); + emittedMessage_ = true; + } + return false; + } + return true; + } + parser::ContextualMessages *messages_; bool emittedMessage_{false}; }; @@ -440,8 +464,11 @@ class CheckSpecificationExprHelper Result operator()(const semantics::Symbol &symbol) const { const auto &ultimate{symbol.GetUltimate()}; - if (semantics::IsNamedConstant(ultimate) || ultimate.owner().IsModule() || - ultimate.owner().IsSubmodule()) { + if (const auto *assoc{ + ultimate.detailsIf()}) { + return (*this)(assoc->expr()); + } else if (semantics::IsNamedConstant(ultimate) || + ultimate.owner().IsModule() || ultimate.owner().IsSubmodule()) { return std::nullopt; } else if (scope_.IsDerivedType() && IsVariableName(ultimate)) { // C750, C754 @@ -584,16 +611,19 @@ class IsSimplyContiguousHelper using Base::operator(); Result operator()(const semantics::Symbol &symbol) const { - if (symbol.attrs().test(semantics::Attr::CONTIGUOUS) || - symbol.Rank() == 0) { + const auto &ultimate{symbol.GetUltimate()}; + if (ultimate.attrs().test(semantics::Attr::CONTIGUOUS) || + ultimate.Rank() == 0) { return true; - } else if (semantics::IsPointer(symbol)) { + } else if (semantics::IsPointer(ultimate)) { return false; } else if (const auto *details{ - symbol.detailsIf()}) { + ultimate.detailsIf()}) { // N.B. ALLOCATABLEs are deferred shape, not assumed, and // are obviously contiguous. return !details->IsAssumedShape() && !details->IsAssumedRank(); + } else if (auto assoc{Base::operator()(ultimate)}) { + return assoc; } else { return false; } diff --git a/flang/lib/Evaluate/constant.cpp b/flang/lib/Evaluate/constant.cpp index 5b73979f1e2c..8f30ca081162 100644 --- a/flang/lib/Evaluate/constant.cpp +++ b/flang/lib/Evaluate/constant.cpp @@ -315,5 +315,9 @@ std::size_t Constant::CopyFrom(const Constant &source, return Base::CopyFrom(source, count, resultSubscripts, dimOrder); } +bool ComponentCompare::operator()(SymbolRef x, SymbolRef y) const { + return semantics::SymbolSourcePositionCompare{}(x, y); +} + INSTANTIATE_CONSTANT_TEMPLATES } // namespace Fortran::evaluate diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp index 64e4bd8c8bd9..455b3c2605c3 100644 --- a/flang/lib/Evaluate/fold-logical.cpp +++ b/flang/lib/Evaluate/fold-logical.cpp @@ -106,6 +106,10 @@ Expr> FoldIntrinsicFunction( } } } + } else if (name == "logical") { + if (auto *expr{UnwrapExpr>(args[0])}) { + return Fold(context, ConvertToType(std::move(*expr))); + } } else if (name == "merge") { return FoldMerge(context, std::move(funcRef)); } else if (name == "__builtin_ieee_support_datatype" || diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp index b54ff78fccc2..8636c9ed3d77 100644 --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -1255,7 +1255,7 @@ std::optional IntrinsicInterface::Match( } } else { // NULL(), procedure, or procedure pointer - CHECK(IsProcedurePointer(expr)); + CHECK(IsProcedurePointerTarget(expr)); if (d.typePattern.kindCode == KindCode::addressable || d.rank == Rank::reduceOperation) { continue; @@ -1851,7 +1851,7 @@ SpecificCall IntrinsicProcTable::Implementation::HandleNull( if (IsAllocatableOrPointer(*mold)) { characteristics::DummyArguments args; std::optional fResult; - if (IsProcedurePointer(*mold)) { + if (IsProcedurePointerTarget(*mold)) { // MOLD= procedure pointer const Symbol *last{GetLastSymbol(*mold)}; CHECK(last); diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index d06463e39de7..9fbf21e43b72 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -52,10 +52,12 @@ std::optional ExtractSubstringBase(const Substring &substring) { // IsVariable() auto IsVariableHelper::operator()(const Symbol &symbol) const -> Result { - return !symbol.attrs().test(semantics::Attr::PARAMETER); + const Symbol &root{GetAssociationRoot(symbol)}; + return !IsNamedConstant(root) && root.has(); } auto IsVariableHelper::operator()(const Component &x) const -> Result { - return (*this)(x.base()); + const Symbol &comp{x.GetLastSymbol()}; + return (*this)(comp) && (IsPointer(comp) || (*this)(x.base())); } auto IsVariableHelper::operator()(const ArrayRef &x) const -> Result { return (*this)(x.base()); @@ -65,8 +67,11 @@ auto IsVariableHelper::operator()(const Substring &x) const -> Result { } auto IsVariableHelper::operator()(const ProcedureDesignator &x) const -> Result { - const Symbol *symbol{x.GetSymbol()}; - return symbol && IsPointer(*symbol); + if (const Symbol * symbol{x.GetSymbol()}) { + const Symbol *result{FindFunctionResult(*symbol)}; + return result && IsPointer(*result) && !IsProcedurePointer(*result); + } + return false; } // Conversions of COMPLEX component expressions to REAL. @@ -686,12 +691,15 @@ bool IsFunction(const Expr &expr) { return designator && designator->GetType().has_value(); } -bool IsProcedurePointer(const Expr &expr) { +bool IsProcedurePointerTarget(const Expr &expr) { return std::visit(common::visitors{ [](const NullPointer &) { return true; }, [](const ProcedureDesignator &) { return true; }, [](const ProcedureRef &) { return true; }, - [](const auto &) { return false; }, + [&](const auto &) { + const Symbol *last{GetLastSymbol(expr)}; + return last && IsProcedurePointer(*last); + }, }, expr.u); } @@ -715,14 +723,10 @@ inline const ProcedureRef *UnwrapProcedureRef(const Expr &expr) { bool IsObjectPointer(const Expr &expr, FoldingContext &context) { if (IsNullPointer(expr)) { return true; - } else if (IsProcedurePointer(expr)) { + } else if (IsProcedurePointerTarget(expr)) { return false; - } else if (const auto *procRef{UnwrapProcedureRef(expr)}) { - auto proc{ - characteristics::Procedure::Characterize(procRef->proc(), context)}; - return proc && proc->functionResult && - proc->functionResult->attrs.test( - characteristics::FunctionResult::Attr::Pointer); + } else if (const auto *funcRef{UnwrapProcedureRef(expr)}) { + return IsVariable(*funcRef); } else if (const Symbol * symbol{GetLastSymbol(expr)}) { return IsPointer(symbol->GetUltimate()); } else { @@ -778,20 +782,22 @@ const Symbol *GetLastTarget(const SymbolVector &symbols) { } struct CollectSymbolsHelper - : public SetTraverse { - using Base = SetTraverse; + : public SetTraverse { + using Base = SetTraverse; CollectSymbolsHelper() : Base{*this} {} using Base::operator(); - semantics::SymbolSet operator()(const Symbol &symbol) const { + semantics::UnorderedSymbolSet operator()(const Symbol &symbol) const { return {symbol}; } }; -template semantics::SymbolSet CollectSymbols(const A &x) { +template semantics::UnorderedSymbolSet CollectSymbols(const A &x) { return CollectSymbolsHelper{}(x); } -template semantics::SymbolSet CollectSymbols(const Expr &); -template semantics::SymbolSet CollectSymbols(const Expr &); -template semantics::SymbolSet CollectSymbols(const Expr &); +template semantics::UnorderedSymbolSet CollectSymbols(const Expr &); +template semantics::UnorderedSymbolSet CollectSymbols( + const Expr &); +template semantics::UnorderedSymbolSet CollectSymbols( + const Expr &); // HasVectorSubscript() struct HasVectorSubscriptHelper : public AnyTraverse { @@ -1089,7 +1095,7 @@ const Symbol *FindCommonBlockContaining(const Symbol &original) { } bool IsProcedurePointer(const Symbol &original) { - const Symbol &symbol{original.GetUltimate()}; + const Symbol &symbol{GetAssociationRoot(original)}; return symbol.has() && IsPointer(symbol); } @@ -1172,4 +1178,50 @@ const Symbol &GetUsedModule(const UseDetails &details) { return DEREF(details.symbol().owner().symbol()); } +static const Symbol *FindFunctionResult( + const Symbol &original, UnorderedSymbolSet &seen) { + const Symbol &root{GetAssociationRoot(original)}; + ; + if (!seen.insert(root).second) { + return nullptr; // don't loop + } + return std::visit( + common::visitors{[](const SubprogramDetails &subp) { + return subp.isFunction() ? &subp.result() : nullptr; + }, + [&](const ProcEntityDetails &proc) { + const Symbol *iface{proc.interface().symbol()}; + return iface ? FindFunctionResult(*iface, seen) : nullptr; + }, + [&](const ProcBindingDetails &binding) { + return FindFunctionResult(binding.symbol(), seen); + }, + [](const auto &) -> const Symbol * { return nullptr; }}, + root.details()); +} + +const Symbol *FindFunctionResult(const Symbol &symbol) { + UnorderedSymbolSet seen; + return FindFunctionResult(symbol, seen); +} + +// These are here in Evaluate/tools.cpp so that Evaluate can use +// them; they cannot be defined in symbol.h due to the dependence +// on Scope. + +bool SymbolSourcePositionCompare::operator()( + const SymbolRef &x, const SymbolRef &y) const { + return x->GetSemanticsContext().allCookedSources().Precedes( + x->name(), y->name()); +} +bool SymbolSourcePositionCompare::operator()( + const MutableSymbolRef &x, const MutableSymbolRef &y) const { + return x->GetSemanticsContext().allCookedSources().Precedes( + x->name(), y->name()); +} + +SemanticsContext &Symbol::GetSemanticsContext() const { + return DEREF(owner_).context(); +} + } // namespace Fortran::semantics diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 0dc7e7c3d395..3bd541e40c0f 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -21,6 +21,8 @@ #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" #include @@ -85,6 +87,15 @@ bool Fortran::frontend::ParseDiagnosticArgs(clang::DiagnosticOptions &opts, return true; } +// Tweak the frontend configuration based on the frontend action +static void setUpFrontendBasedOnAction(FrontendOptions &opts) { + assert(opts.programAction_ != Fortran::frontend::InvalidAction && + "Fortran frontend action not set!"); + + if (opts.programAction_ == DebugDumpParsingLog) + opts.instrumentedParse_ = true; +} + static InputKind ParseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args, clang::DiagnosticsEngine &diags) { @@ -125,12 +136,18 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts, case clang::driver::options::OPT_fdebug_dump_provenance: opts.programAction_ = DebugDumpProvenance; break; + case clang::driver::options::OPT_fdebug_dump_parsing_log: + opts.programAction_ = DebugDumpParsingLog; + break; case clang::driver::options::OPT_fdebug_measure_parse_tree: opts.programAction_ = DebugMeasureParseTree; break; case clang::driver::options::OPT_fdebug_pre_fir_tree: opts.programAction_ = DebugPreFIRTree; break; + case clang::driver::options::OPT_fget_symbols_sources: + opts.programAction_ = GetSymbolsSources; + break; // TODO: // case calng::driver::options::OPT_emit_llvm: @@ -264,9 +281,22 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts, << arg->getAsString(args) << argValue; } } + + setUpFrontendBasedOnAction(opts); + return dashX; } +// Generate the path to look for intrinsic modules +static std::string getIntrinsicDir() { + // TODO: Find a system independent API + llvm::SmallString<128> driverPath; + driverPath.assign(llvm::sys::fs::getMainExecutable(nullptr, nullptr)); + llvm::sys::path::remove_filename(driverPath); + driverPath.append("/../include/flang/"); + return std::string(driverPath); +} + /// Parses all preprocessor input arguments and populates the preprocessor /// options accordingly. /// @@ -287,13 +317,20 @@ static void parsePreprocessorArgs( // Add the ordered list of -I's. for (const auto *currentArg : args.filtered(clang::driver::options::OPT_I)) opts.searchDirectoriesFromDashI.emplace_back(currentArg->getValue()); + + // Prepend the ordered list of -intrinsic-modules-path + // to the default location to search. + for (const auto *currentArg : + args.filtered(clang::driver::options::OPT_fintrinsic_modules_path)) + opts.searchDirectoriesFromIntrModPath.emplace_back(currentArg->getValue()); } /// Parses all semantic related arguments and populates the variables /// options accordingly. -static void parseSemaArgs(std::string &moduleDir, llvm::opt::ArgList &args, +static void parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args, clang::DiagnosticsEngine &diags) { + // -J/module-dir option auto moduleDirList = args.getAllArgValues(clang::driver::options::OPT_module_dir); // User can only specify -J/-module-dir once @@ -305,7 +342,12 @@ static void parseSemaArgs(std::string &moduleDir, llvm::opt::ArgList &args, diags.Report(diagID); } if (moduleDirList.size() == 1) - moduleDir = moduleDirList[0]; + res.SetModuleDir(moduleDirList[0]); + + // -fdebug-module-writer option + if (args.hasArg(clang::driver::options::OPT_fdebug_module_writer)) { + res.SetDebugModuleDir(true); + } } /// Parses all Dialect related arguments and populates the variables @@ -347,6 +389,26 @@ static void parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args, res.frontendOpts().features_.Enable( Fortran::common::LanguageFeature::OpenMP); } + + // -pedantic + if (args.hasArg(clang::driver::options::OPT_pedantic)) { + res.set_EnableConformanceChecks(); + } + // -std=f2018 (currently this implies -pedantic) + // TODO: Set proper options when more fortran standards + // are supported. + if (args.hasArg(clang::driver::options::OPT_std_EQ)) { + auto standard = args.getLastArgValue(clang::driver::options::OPT_std_EQ); + // We only allow f2018 as the given standard + if (standard.equals("f2018")) { + res.set_EnableConformanceChecks(); + } else { + const unsigned diagID = + diags.getCustomDiagID(clang::DiagnosticsEngine::Error, + "Only -std=f2018 is allowed currently."); + diags.Report(diagID); + } + } return; } @@ -380,7 +442,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &res, // Parse the preprocessor args parsePreprocessorArgs(res.preprocessorOpts(), args); // Parse semantic args - parseSemaArgs(res.moduleDir(), args, diags); + parseSemaArgs(res, args, diags); // Parse dialect arguments parseDialectArgs(res, args, diags); @@ -475,15 +537,32 @@ void CompilerInvocation::setFortranOpts() { collectMacroDefinitions(preprocessorOptions, fortranOptions); + // Adding search directories specified by -I fortranOptions.searchDirectories.insert( fortranOptions.searchDirectories.end(), preprocessorOptions.searchDirectoriesFromDashI.begin(), preprocessorOptions.searchDirectoriesFromDashI.end()); + // Add the ordered list of -intrinsic-modules-path + fortranOptions.searchDirectories.insert( + fortranOptions.searchDirectories.end(), + preprocessorOptions.searchDirectoriesFromIntrModPath.begin(), + preprocessorOptions.searchDirectoriesFromIntrModPath.end()); + + // Add the default intrinsic module directory at the end + fortranOptions.searchDirectories.emplace_back(getIntrinsicDir()); + // Add the directory supplied through -J/-module-dir to the list of search // directories if (moduleDirJ.compare(".") != 0) fortranOptions.searchDirectories.emplace_back(moduleDirJ); + + if (frontendOptions.instrumentedParse_) + fortranOptions.instrumentedParse = true; + + if (enableConformanceChecks()) { + fortranOptions.features.WarnOnAllNonstandard(); + } } void CompilerInvocation::setSemanticsOpts( @@ -493,7 +572,7 @@ void CompilerInvocation::setSemanticsOpts( semanticsContext_ = std::make_unique( defaultKinds(), fortranOptions.features, allCookedSources); - auto &moduleDirJ = moduleDir(); - semanticsContext_->set_moduleDirectory(moduleDirJ) - .set_searchDirectories(fortranOptions.searchDirectories); + semanticsContext_->set_moduleDirectory(moduleDir()) + .set_searchDirectories(fortranOptions.searchDirectories) + .set_warnOnNonstandardUsage(enableConformanceChecks()); } diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index b7e4f912171f..1871a35444db 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -16,6 +16,7 @@ #include "flang/Parser/provenance.h" #include "flang/Parser/source.h" #include "flang/Parser/unparse.h" +#include "flang/Semantics/runtime-type-info.h" #include "flang/Semantics/semantics.h" #include "flang/Semantics/unparse-with-symbols.h" #include "llvm/ADT/StringRef.h" @@ -126,7 +127,7 @@ bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) { // Prepare semantics setSemantics(std::make_unique( ci.invocation().semanticsContext(), parseTree, - ci.parsing().cooked().AsCharBlock())); + ci.parsing().cooked().AsCharBlock(), ci.invocation().debugModuleDir())); auto &semantics = this->semantics(); // Run semantic checks @@ -307,6 +308,22 @@ void DebugPreFIRTreeAction::ExecuteAction() { } } +void DebugDumpParsingLogAction::ExecuteAction() { + CompilerInstance &ci = this->instance(); + + ci.parsing().Parse(llvm::errs()); + ci.parsing().DumpParsingLog(llvm::outs()); +} + +void GetSymbolsSourcesAction::ExecuteAction() { + // Report and exit if fatal semantic errors are present + if (reportFatalSemanticErrors(semantics(), this->instance().diagnostics(), + GetCurrentFileOrBufferName())) + return; + + semantics().DumpSymbolsSources(llvm::outs()); +} + void EmitObjAction::ExecuteAction() { CompilerInstance &ci = this->instance(); unsigned DiagID = ci.diagnostics().getCustomDiagID( diff --git a/flang/lib/Frontend/FrontendOptions.cpp b/flang/lib/Frontend/FrontendOptions.cpp index a43cac3bb1cb..2c2f7b84230c 100644 --- a/flang/lib/Frontend/FrontendOptions.cpp +++ b/flang/lib/Frontend/FrontendOptions.cpp @@ -13,17 +13,17 @@ using namespace Fortran::frontend; bool Fortran::frontend::isFixedFormSuffix(llvm::StringRef suffix) { // Note: Keep this list in-sync with flang/test/lit.cfg.py - return suffix == "f" || suffix == "F" || suffix == "ff" || suffix == "for" || - suffix == "FOR" || suffix == "fpp" || suffix == "FPP"; + return suffix == "f77" || suffix == "f" || suffix == "F" || suffix == "ff" || + suffix == "for" || suffix == "FOR" || suffix == "fpp" || suffix == "FPP"; } bool Fortran::frontend::isFreeFormSuffix(llvm::StringRef suffix) { // Note: Keep this list in-sync with flang/test/lit.cfg.py // TODO: Add Cuda Fortan files (i.e. `*.cuf` and `*.CUF`). - return suffix == "f77" || suffix == "f90" || suffix == "F90" || - suffix == "ff90" || suffix == "f95" || suffix == "F95" || - suffix == "ff95" || suffix == "f03" || suffix == "F03" || - suffix == "f08" || suffix == "F08" || suffix == "f18" || suffix == "F18"; + return suffix == "f90" || suffix == "F90" || suffix == "ff90" || + suffix == "f95" || suffix == "F95" || suffix == "ff95" || + suffix == "f03" || suffix == "F03" || suffix == "f08" || + suffix == "F08" || suffix == "f18" || suffix == "F18"; } // TODO: This is a copy of `asFortran` from f18.cpp and is added here for diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index c5f7bb27e8b8..2a08e388a9d8 100644 --- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -52,12 +52,18 @@ static std::unique_ptr CreateFrontendBaseAction( case DebugDumpProvenance: return std::make_unique(); break; + case DebugDumpParsingLog: + return std::make_unique(); + break; case DebugMeasureParseTree: return std::make_unique(); break; case DebugPreFIRTree: return std::make_unique(); break; + case GetSymbolsSources: + return std::make_unique(); + break; default: break; // TODO: diff --git a/flang/lib/Lower/IntervalSet.h b/flang/lib/Lower/IntervalSet.h new file mode 100644 index 000000000000..fddeea383173 --- /dev/null +++ b/flang/lib/Lower/IntervalSet.h @@ -0,0 +1,109 @@ +//===-- IntervalSet.h -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_INTERVALSET_H +#define FORTRAN_LOWER_INTERVALSET_H + +#include +#include + +namespace Fortran::lower { + +//===----------------------------------------------------------------------===// +// Interval set +//===----------------------------------------------------------------------===// + +/// Interval set to keep track of intervals, merging them when they overlap one +/// another. Used to refine the pseudo-offset ranges of the front-end symbols +/// into groups of aliasing variables. +struct IntervalSet { + using MAP = std::map; + using Iterator = MAP::const_iterator; + + // Handles the merging of overlapping intervals correctly, efficiently. + void merge(std::size_t lo, std::size_t up) { + assert(lo <= up); + if (empty()) { + m.insert({lo, up}); + return; + } + auto i = m.lower_bound(lo); + // i->first >= lo + if (i == begin()) { + if (up < i->first) { + // [lo..up] < i->first + m.insert({lo, up}); + return; + } + // up >= i->first + if (i->second > up) + up = i->second; + fuse(lo, up, i); + return; + } + auto i1 = i; + if (i == end() || i->first > lo) + i = std::prev(i); + // i->first <= lo + if (i->second >= up) { + // i->first <= lo && up <= i->second, keep i + return; + } + // i->second < up + if (i->second < lo) { + if (i1 == end() || i1->first > up) { + // i < [lo..up] < i1 + m.insert({lo, up}); + return; + } + // i < [lo..up], i1->first <= up --> [lo..up] union [i1..?] + i = i1; + } else { + // i->first <= lo, lo <= i->second --> [i->first..up] union [i..?] + lo = i->first; + } + fuse(lo, up, i); + } + + Iterator find(std::size_t pt) const { + auto i = m.lower_bound(pt); + if (i != end() && i->first == pt) + return i; + if (i == begin()) + return end(); + i = std::prev(i); + if (i->second < pt) + return end(); + return i; + } + + Iterator begin() const { return m.begin(); } + Iterator end() const { return m.end(); } + bool empty() const { return m.empty(); } + std::size_t size() const { return m.size(); } + +private: + // Find and fuse overlapping sets. + void fuse(std::size_t lo, std::size_t up, Iterator i) { + auto j = m.upper_bound(up); + // up < j->first + auto cu = std::prev(j)->second; + // cu < j->first + if (cu > up) + up = cu; + m.erase(i, j); + // merge [i .. j) with [i->first, max(up, cu)] + m.insert({lo, up}); + } + + MAP m{}; +}; + +} // namespace Fortran::lower + +#endif // FORTRAN_LOWER_INTERVALSET_H diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp index 15fedf55cbcb..b9c2bba03631 100644 --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -1039,7 +1039,7 @@ mlir::Value IntrinsicLibrary::genDim(mlir::Type resultType, } assert(fir::isa_real(resultType) && "Only expects real and integer in DIM"); auto zero = builder.createRealZeroConstant(loc, resultType); - auto diff = builder.create(loc, args[0], args[1]); + auto diff = builder.create(loc, args[0], args[1]); auto cmp = builder.create(loc, mlir::CmpFPredicate::OGT, diff, zero); return builder.create(loc, cmp, diff, zero); @@ -1053,7 +1053,7 @@ mlir::Value IntrinsicLibrary::genDprod(mlir::Type resultType, "Result must be double precision in DPROD"); auto a = builder.createConvert(loc, resultType, args[0]); auto b = builder.createConvert(loc, resultType, args[1]); - return builder.create(loc, a, b); + return builder.create(loc, a, b); } // FLOOR diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp index 349f76ee80ac..8dfc8f77be8f 100644 --- a/flang/lib/Lower/PFTBuilder.cpp +++ b/flang/lib/Lower/PFTBuilder.cpp @@ -7,17 +7,28 @@ //===----------------------------------------------------------------------===// #include "flang/Lower/PFTBuilder.h" -#include "flang/Lower/Utils.h" +#include "IntervalSet.h" +#include "flang/Lower/Support/Utils.h" #include "flang/Parser/dump-parse-tree.h" #include "flang/Parser/parse-tree-visitor.h" #include "flang/Semantics/semantics.h" #include "flang/Semantics/tools.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/IntervalMap.h" #include "llvm/Support/CommandLine.h" +#define DEBUG_TYPE "flang-pft" + static llvm::cl::opt clDisableStructuredFir( "no-structured-fir", llvm::cl::desc("disable generation of structured FIR"), llvm::cl::init(false), llvm::cl::Hidden); +static llvm::cl::opt nonRecursiveProcedures( + "non-recursive-procedures", + llvm::cl::desc("Make procedures non-recursive by default. This was the " + "default for all Fortran standards prior to 2018."), + llvm::cl::init(/*2018 standard=*/false)); + using namespace Fortran; namespace { @@ -66,8 +77,8 @@ class PFTBuilder { PFTBuilder(const semantics::SemanticsContext &semanticsContext) : pgm{std::make_unique()}, semanticsContext{ semanticsContext} { - lower::pft::ParentVariant parent{*pgm.get()}; - parentVariantStack.push_back(parent); + lower::pft::PftNode pftRoot{*pgm.get()}; + pftParentStack.push_back(pftRoot); } /// Get the result @@ -83,24 +94,65 @@ class PFTBuilder { } else if constexpr (UnwrapStmt::isStmt) { using T = typename UnwrapStmt::Type; // Node "a" being visited has one of the following types: - // Statement, Statement, UnlabeledStatement, + // Statement, Statement>, UnlabeledStatement, // or UnlabeledStatement> auto stmt{UnwrapStmt(a)}; if constexpr (lower::pft::isConstructStmt || lower::pft::isOtherStmt) { - addEvaluation(lower::pft::Evaluation{stmt.unwrapped, - parentVariantStack.back(), - stmt.position, stmt.label}); + addEvaluation(lower::pft::Evaluation{ + stmt.unwrapped, pftParentStack.back(), stmt.position, stmt.label}); return false; } else if constexpr (std::is_same_v) { - addEvaluation( - makeEvaluationAction(stmt.unwrapped, stmt.position, stmt.label)); - return true; + return std::visit( + common::visitors{ + [&](const common::Indirection &x) { + convertIfStmt(x.value(), stmt.position, stmt.label); + return false; + }, + [&](const auto &x) { + addEvaluation(lower::pft::Evaluation{ + removeIndirection(x), pftParentStack.back(), + stmt.position, stmt.label}); + return true; + }, + }, + stmt.unwrapped.u); } } return true; } + /// Convert an IfStmt into an IfConstruct, retaining the IfStmt as the + /// first statement of the construct. + void convertIfStmt(const parser::IfStmt &ifStmt, parser::CharBlock position, + std::optional label) { + // Generate a skeleton IfConstruct parse node. Its components are never + // referenced. The actual components are available via the IfConstruct + // evaluation's nested evaluationList, with the ifStmt in the position of + // the otherwise normal IfThenStmt. Caution: All other PFT nodes reference + // front end generated parse nodes; this is an exceptional case. + static const auto ifConstruct = parser::IfConstruct{ + parser::Statement{ + std::nullopt, + parser::IfThenStmt{ + std::optional{}, + parser::ScalarLogicalExpr{parser::LogicalExpr{parser::Expr{ + parser::LiteralConstant{parser::LogicalLiteralConstant{ + false, std::optional{}}}}}}}}, + parser::Block{}, std::list{}, + std::optional{}, + parser::Statement{std::nullopt, + parser::EndIfStmt{std::nullopt}}}; + enterConstructOrDirective(ifConstruct); + addEvaluation( + lower::pft::Evaluation{ifStmt, pftParentStack.back(), position, label}); + Pre(std::get>(ifStmt.t)); + static const auto endIfStmt = parser::EndIfStmt{std::nullopt}; + addEvaluation( + lower::pft::Evaluation{endIfStmt, pftParentStack.back(), {}, {}}); + exitConstructOrDirective(); + } + template constexpr void Post(const A &) { if constexpr (lower::pft::isFunctionLike) { @@ -120,25 +172,16 @@ class PFTBuilder { // Block data bool Pre(const parser::BlockData &node) { - addUnit(lower::pft::BlockDataUnit{node, parentVariantStack.back()}); + addUnit(lower::pft::BlockDataUnit{node, pftParentStack.back(), + semanticsContext}); return false; } // Get rid of production wrapper - bool Pre(const parser::UnlabeledStatement - &statement) { - addEvaluation(std::visit( - [&](const auto &x) { - return lower::pft::Evaluation{ - x, parentVariantStack.back(), statement.source, {}}; - }, - statement.statement.u)); - return false; - } bool Pre(const parser::Statement &statement) { addEvaluation(std::visit( [&](const auto &x) { - return lower::pft::Evaluation{x, parentVariantStack.back(), + return lower::pft::Evaluation{x, pftParentStack.back(), statement.source, statement.label}; }, statement.statement.u)); @@ -151,7 +194,7 @@ class PFTBuilder { // Not caught as other AssignmentStmt because it is not // wrapped in a parser::ActionStmt. addEvaluation(lower::pft::Evaluation{stmt.statement, - parentVariantStack.back(), + pftParentStack.back(), stmt.source, stmt.label}); return false; }, @@ -160,30 +203,69 @@ class PFTBuilder { whereBody.u); } + // CompilerDirective have special handling in case they are top level + // directives (i.e. they do not belong to a ProgramUnit). + bool Pre(const parser::CompilerDirective &directive) { + assert(pftParentStack.size() > 0 && + "At least the Program must be a parent"); + if (pftParentStack.back().isA()) { + addUnit( + lower::pft::CompilerDirectiveUnit(directive, pftParentStack.back())); + return false; + } + return enterConstructOrDirective(directive); + } + private: /// Initialize a new module-like unit and make it the builder's focus. template bool enterModule(const A &func) { auto &unit = - addUnit(lower::pft::ModuleLikeUnit{func, parentVariantStack.back()}); + addUnit(lower::pft::ModuleLikeUnit{func, pftParentStack.back()}); functionList = &unit.nestedFunctions; - parentVariantStack.emplace_back(unit); + pftParentStack.emplace_back(unit); return true; } void exitModule() { - parentVariantStack.pop_back(); + pftParentStack.pop_back(); resetFunctionState(); } - /// Ensure that a function has a branch target after the last user statement. + /// Add the end statement Evaluation of a sub/program to the PFT. + /// There may be intervening internal subprogram definitions between + /// prior statements and this end statement. void endFunctionBody() { - if (lastLexicalEvaluation) { - static const parser::ContinueStmt endTarget{}; - addEvaluation( - lower::pft::Evaluation{endTarget, parentVariantStack.back(), {}, {}}); - lastLexicalEvaluation = nullptr; + if (evaluationListStack.empty()) + return; + auto evaluationList = evaluationListStack.back(); + if (evaluationList->empty() || !evaluationList->back().isEndStmt()) { + const auto &endStmt = + pftParentStack.back().get().endStmt; + endStmt.visit(common::visitors{ + [&](const parser::Statement &s) { + addEvaluation(lower::pft::Evaluation{ + s.statement, pftParentStack.back(), s.source, s.label}); + }, + [&](const parser::Statement &s) { + addEvaluation(lower::pft::Evaluation{ + s.statement, pftParentStack.back(), s.source, s.label}); + }, + [&](const parser::Statement &s) { + addEvaluation(lower::pft::Evaluation{ + s.statement, pftParentStack.back(), s.source, s.label}); + }, + [&](const parser::Statement &s) { + addEvaluation(lower::pft::Evaluation{ + s.statement, pftParentStack.back(), s.source, s.label}); + }, + [&](const auto &s) { + llvm::report_fatal_error("missing end statement or unexpected " + "begin statement reference"); + }, + }); } + lastLexicalEvaluation = nullptr; } /// Initialize a new function-like unit and make it the builder's focus. @@ -192,47 +274,50 @@ class PFTBuilder { const semantics::SemanticsContext &semanticsContext) { endFunctionBody(); // enclosing host subprogram body, if any auto &unit = addFunction(lower::pft::FunctionLikeUnit{ - func, parentVariantStack.back(), semanticsContext}); + func, pftParentStack.back(), semanticsContext}); labelEvaluationMap = &unit.labelEvaluationMap; assignSymbolLabelMap = &unit.assignSymbolLabelMap; functionList = &unit.nestedFunctions; pushEvaluationList(&unit.evaluationList); - parentVariantStack.emplace_back(unit); + pftParentStack.emplace_back(unit); return true; } void exitFunction() { + rewriteIfGotos(); endFunctionBody(); analyzeBranches(nullptr, *evaluationListStack.back()); // add branch links + processEntryPoints(); popEvaluationList(); labelEvaluationMap = nullptr; assignSymbolLabelMap = nullptr; - parentVariantStack.pop_back(); + pftParentStack.pop_back(); resetFunctionState(); } /// Initialize a new construct and make it the builder's focus. template bool enterConstructOrDirective(const A &construct) { - auto &eval = addEvaluation( - lower::pft::Evaluation{construct, parentVariantStack.back()}); + auto &eval = + addEvaluation(lower::pft::Evaluation{construct, pftParentStack.back()}); eval.evaluationList.reset(new lower::pft::EvaluationList); pushEvaluationList(eval.evaluationList.get()); - parentVariantStack.emplace_back(eval); + pftParentStack.emplace_back(eval); constructAndDirectiveStack.emplace_back(&eval); return true; } void exitConstructOrDirective() { + rewriteIfGotos(); popEvaluationList(); - parentVariantStack.pop_back(); + pftParentStack.pop_back(); constructAndDirectiveStack.pop_back(); } /// Reset function state to that of an enclosing host function. void resetFunctionState() { - if (!parentVariantStack.empty()) { - parentVariantStack.back().visit(common::visitors{ + if (!pftParentStack.empty()) { + pftParentStack.back().visit(common::visitors{ [&](lower::pft::FunctionLikeUnit &p) { functionList = &p.nestedFunctions; labelEvaluationMap = &p.labelEvaluationMap; @@ -270,9 +355,8 @@ class PFTBuilder { return std::visit( common::visitors{ [&](const auto &x) { - return lower::pft::Evaluation{removeIndirection(x), - parentVariantStack.back(), position, - label}; + return lower::pft::Evaluation{ + removeIndirection(x), pftParentStack.back(), position, label}; }, }, statement.u); @@ -281,13 +365,13 @@ class PFTBuilder { /// Append an Evaluation to the end of the current list. lower::pft::Evaluation &addEvaluation(lower::pft::Evaluation &&eval) { assert(functionList && "not in a function"); - assert(evaluationListStack.size() > 0); - if (constructAndDirectiveStack.size() > 0) { + assert(!evaluationListStack.empty() && "empty evaluation list stack"); + if (!constructAndDirectiveStack.empty()) eval.parentConstruct = constructAndDirectiveStack.back(); - } + auto &entryPointList = eval.getOwningProcedure()->entryPointList; evaluationListStack.back()->emplace_back(std::move(eval)); lower::pft::Evaluation *p = &evaluationListStack.back()->back(); - if (p->isActionStmt() || p->isConstructStmt()) { + if (p->isActionStmt() || p->isConstructStmt() || p->isEndStmt()) { if (lastLexicalEvaluation) { lastLexicalEvaluation->lexicalSuccessor = p; p->printIndex = lastLexicalEvaluation->printIndex + 1; @@ -295,18 +379,28 @@ class PFTBuilder { p->printIndex = 1; } lastLexicalEvaluation = p; + for (auto entryIndex = entryPointList.size() - 1; + entryIndex && !entryPointList[entryIndex].second->lexicalSuccessor; + --entryIndex) + // Link to the entry's first executable statement. + entryPointList[entryIndex].second->lexicalSuccessor = p; + } else if (const auto *entryStmt = p->getIf()) { + const auto *sym = std::get(entryStmt->t).symbol; + assert(sym->has() && + "entry must be a subprogram"); + entryPointList.push_back(std::pair{sym, p}); } - if (p->label.has_value()) { + if (p->label.has_value()) labelEvaluationMap->try_emplace(*p->label, p); - } return evaluationListStack.back()->back(); } /// push a new list on the stack of Evaluation lists - void pushEvaluationList(lower::pft::EvaluationList *eval) { + void pushEvaluationList(lower::pft::EvaluationList *evaluationList) { assert(functionList && "not in a function"); - assert(eval && eval->empty() && "evaluation list isn't correct"); - evaluationListStack.emplace_back(eval); + assert(evaluationList && evaluationList->empty() && + "evaluation list isn't correct"); + evaluationListStack.emplace_back(evaluationList); } /// pop the current list and return to the last Evaluation list @@ -315,25 +409,119 @@ class PFTBuilder { evaluationListStack.pop_back(); } + /// Rewrite IfConstructs containing a GotoStmt to eliminate an unstructured + /// branch and a trivial basic block. The pre-branch-analysis code: + /// + /// <> + /// 1 If[Then]Stmt: if(cond) goto L + /// 2 GotoStmt: goto L + /// 3 EndIfStmt + /// <> + /// 4 Statement: ... + /// 5 Statement: ... + /// 6 Statement: L ... + /// + /// becomes: + /// + /// <> + /// 1 If[Then]Stmt [negate]: if(cond) goto L + /// 4 Statement: ... + /// 5 Statement: ... + /// 3 EndIfStmt + /// <> + /// 6 Statement: L ... + /// + /// The If[Then]Stmt condition is implicitly negated. It is not modified + /// in the PFT. It must be negated when generating FIR. The GotoStmt is + /// deleted. + /// + /// The transformation is only valid for forward branch targets at the same + /// construct nesting level as the IfConstruct. The result must not violate + /// construct nesting requirements or contain an EntryStmt. The result + /// is subject to normal un/structured code classification analysis. The + /// result is allowed to violate the F18 Clause 11.1.2.1 prohibition on + /// transfer of control into the interior of a construct block, as that does + /// not compromise correct code generation. When two transformation + /// candidates overlap, at least one must be disallowed. In such cases, + /// the current heuristic favors simple code generation, which happens to + /// favor later candidates over earlier candidates. That choice is probably + /// not significant, but could be changed. + /// + void rewriteIfGotos() { + using T = struct { + lower::pft::EvaluationList::iterator ifConstructIt; + parser::Label ifTargetLabel; + }; + llvm::SmallVector ifExpansionStack; + auto &evaluationList = *evaluationListStack.back(); + for (auto it = evaluationList.begin(), end = evaluationList.end(); + it != end; ++it) { + auto &eval = *it; + if (eval.isA()) { + ifExpansionStack.clear(); + continue; + } + auto firstStmt = [](lower::pft::Evaluation *e) { + return e->isConstruct() ? &*e->evaluationList->begin() : e; + }; + auto &targetEval = *firstStmt(&eval); + if (targetEval.label) { + while (!ifExpansionStack.empty() && + ifExpansionStack.back().ifTargetLabel == *targetEval.label) { + auto ifConstructIt = ifExpansionStack.back().ifConstructIt; + auto successorIt = std::next(ifConstructIt); + if (successorIt != it) { + auto &ifBodyList = *ifConstructIt->evaluationList; + auto gotoStmtIt = std::next(ifBodyList.begin()); + assert(gotoStmtIt->isA() && "expected GotoStmt"); + ifBodyList.erase(gotoStmtIt); + auto &ifStmt = *ifBodyList.begin(); + ifStmt.negateCondition = true; + ifStmt.lexicalSuccessor = firstStmt(&*successorIt); + auto endIfStmtIt = std::prev(ifBodyList.end()); + std::prev(it)->lexicalSuccessor = &*endIfStmtIt; + endIfStmtIt->lexicalSuccessor = firstStmt(&*it); + ifBodyList.splice(endIfStmtIt, evaluationList, successorIt, it); + for (; successorIt != endIfStmtIt; ++successorIt) + successorIt->parentConstruct = &*ifConstructIt; + } + ifExpansionStack.pop_back(); + } + } + if (eval.isA() && eval.evaluationList->size() == 3) { + if (auto *gotoStmt = std::next(eval.evaluationList->begin()) + ->getIf()) + ifExpansionStack.push_back({it, gotoStmt->v}); + } + } + } + /// Mark I/O statement ERR, EOR, and END specifier branch targets. + /// Mark an I/O statement with an assigned format as unstructured. template void analyzeIoBranches(lower::pft::Evaluation &eval, const A &stmt) { - auto processIfLabel{[&](const auto &specs) { - using LabelNodes = - std::tuple; - for (const auto &spec : specs) { - const auto *label = std::visit( - [](const auto &label) -> const parser::Label * { - using B = std::decay_t; - if constexpr (common::HasMember) { - return &label.v; - } - return nullptr; - }, + auto analyzeFormatSpec = [&](const parser::Format &format) { + if (const auto *expr = std::get_if(&format.u)) { + if (semantics::ExprHasTypeCategory(*semantics::GetExpr(*expr), + common::TypeCategory::Integer)) + eval.isUnstructured = true; + } + }; + auto analyzeSpecs{[&](const auto &specList) { + for (const auto &spec : specList) { + std::visit( + Fortran::common::visitors{ + [&](const Fortran::parser::Format &format) { + analyzeFormatSpec(format); + }, + [&](const auto &label) { + using LabelNodes = + std::tuple; + if constexpr (common::HasMember) + markBranchTarget(eval, label.v); + }}, spec.u); - - if (label) - markBranchTarget(eval, *label); } }}; @@ -344,11 +532,17 @@ class PFTBuilder { if constexpr (std::is_same_v || std::is_same_v) { - processIfLabel(stmt.controls); + if (stmt.format) + analyzeFormatSpec(*stmt.format); + analyzeSpecs(stmt.controls); + } else if constexpr (std::is_same_v) { + analyzeFormatSpec(std::get(stmt.t)); } else if constexpr (std::is_same_v) { - processIfLabel(std::get>(stmt.u)); + if (const auto *specList = + std::get_if>(&stmt.u)) + analyzeSpecs(*specList); } else if constexpr (common::HasMember) { - processIfLabel(stmt.v); + analyzeSpecs(stmt.v); } else { // Always crash if this is instantiated static_assert(!std::is_same_v, @@ -365,16 +559,15 @@ class PFTBuilder { void markBranchTarget(lower::pft::Evaluation &sourceEvaluation, lower::pft::Evaluation &targetEvaluation) { sourceEvaluation.isUnstructured = true; - if (!sourceEvaluation.controlSuccessor) { + if (!sourceEvaluation.controlSuccessor) sourceEvaluation.controlSuccessor = &targetEvaluation; - } targetEvaluation.isNewBlock = true; // If this is a branch into the body of a construct (usually illegal, // but allowed in some legacy cases), then the targetEvaluation and its // ancestors must be marked as unstructured. auto *sourceConstruct = sourceEvaluation.parentConstruct; auto *targetConstruct = targetEvaluation.parentConstruct; - if (targetEvaluation.isConstructStmt() && + if (targetConstruct && &targetConstruct->getFirstNestedEvaluation() == &targetEvaluation) // A branch to an initial constructStmt is a branch to the construct. targetConstruct = targetConstruct->parentConstruct; @@ -423,16 +616,15 @@ class PFTBuilder { parser::TypeGuardStmt, parser::WhereConstructStmt>; if constexpr (common::HasMember) { - if (auto name{std::get>(stmt.t)}) + if (auto name = std::get>(stmt.t)) return name->ToString(); } // These statements have several std::optional if constexpr (std::is_same_v || std::is_same_v) { - if (auto name{std::get<0>(stmt.t)}) { + if (auto name = std::get<0>(stmt.t)) return name->ToString(); - } } return {}; } @@ -442,10 +634,9 @@ class PFTBuilder { template void insertConstructName(const A &stmt, lower::pft::Evaluation *parentConstruct) { - std::string name{getConstructName(stmt)}; - if (!name.empty()) { + std::string name = getConstructName(stmt); + if (!name.empty()) constructNameMap[name] = parentConstruct; - } } /// Insert branch links for a list of Evaluations. @@ -453,24 +644,23 @@ class PFTBuilder { /// top-level statements of a program. void analyzeBranches(lower::pft::Evaluation *parentConstruct, std::list &evaluationList) { - lower::pft::Evaluation *lastConstructStmtEvaluation{nullptr}; - lower::pft::Evaluation *lastIfStmtEvaluation{nullptr}; + lower::pft::Evaluation *lastConstructStmtEvaluation{}; for (auto &eval : evaluationList) { eval.visit(common::visitors{ - // Action statements + // Action statements (except I/O statements) [&](const parser::CallStmt &s) { // Look for alternate return specifiers. - const auto &args{std::get>(s.v.t)}; + const auto &args = + std::get>(s.v.t); for (const auto &arg : args) { - const auto &actual{std::get(arg.t)}; - if (const auto *altReturn{ - std::get_if(&actual.u)}) { + const auto &actual = std::get(arg.t); + if (const auto *altReturn = + std::get_if(&actual.u)) markBranchTarget(eval, altReturn->v); - } } }, [&](const parser::CycleStmt &s) { - std::string name{getConstructName(s)}; + std::string name = getConstructName(s); lower::pft::Evaluation *construct{name.empty() ? doConstructStack.back() : constructNameMap[name]}; @@ -478,7 +668,7 @@ class PFTBuilder { markBranchTarget(eval, construct->evaluationList->back()); }, [&](const parser::ExitStmt &s) { - std::string name{getConstructName(s)}; + std::string name = getConstructName(s); lower::pft::Evaluation *construct{name.empty() ? doConstructStack.back() : constructNameMap[name]}; @@ -486,7 +676,10 @@ class PFTBuilder { markBranchTarget(eval, *construct->constructExit); }, [&](const parser::GotoStmt &s) { markBranchTarget(eval, s.v); }, - [&](const parser::IfStmt &) { lastIfStmtEvaluation = &eval; }, + [&](const parser::IfStmt &) { + eval.lexicalSuccessor->isNewBlock = true; + lastConstructStmtEvaluation = &eval; + }, [&](const parser::ReturnStmt &) { eval.isUnstructured = true; if (eval.lexicalSuccessor->lexicalSuccessor) @@ -498,20 +691,13 @@ class PFTBuilder { markSuccessorAsNewBlock(eval); }, [&](const parser::ComputedGotoStmt &s) { - for (auto &label : std::get>(s.t)) { + for (auto &label : std::get>(s.t)) markBranchTarget(eval, label); - } }, [&](const parser::ArithmeticIfStmt &s) { markBranchTarget(eval, std::get<1>(s.t)); markBranchTarget(eval, std::get<2>(s.t)); markBranchTarget(eval, std::get<3>(s.t)); - if (semantics::ExprHasTypeCategory( - *semantics::GetExpr(std::get(s.t)), - common::TypeCategory::Real)) { - // Real expression evaluation uses an additional local block. - eval.localBlocks.emplace_back(nullptr); - } }, [&](const parser::AssignStmt &s) { // legacy label assignment auto &label = std::get(s.t); @@ -520,9 +706,8 @@ class PFTBuilder { lower::pft::Evaluation *target{ labelEvaluationMap->find(label)->second}; assert(target && "missing branch target evaluation"); - if (!target->isA()) { + if (!target->isA()) target->isNewBlock = true; - } auto iter = assignSymbolLabelMap->find(*sym); if (iter == assignSymbolLabelMap->end()) { lower::pft::LabelSet labelSet{}; @@ -569,60 +754,47 @@ class PFTBuilder { [&](const parser::NonLabelDoStmt &s) { insertConstructName(s, parentConstruct); doConstructStack.push_back(parentConstruct); - auto &control{std::get>(s.t)}; - // eval.block is the loop preheader block, which will be set - // elsewhere if the NonLabelDoStmt is itself a target. - // eval.localBlocks[0] is the loop header block. - eval.localBlocks.emplace_back(nullptr); - if (!control.has_value()) { + const auto &loopControl = + std::get>(s.t); + if (!loopControl.has_value()) { eval.isUnstructured = true; // infinite loop return; } eval.nonNopSuccessor().isNewBlock = true; eval.controlSuccessor = &evaluationList.back(); - if (std::holds_alternative(control->u)) { + if (const auto *bounds = + std::get_if(&loopControl->u)) { + if (bounds->name.thing.symbol->GetType()->IsNumeric( + common::TypeCategory::Real)) + eval.isUnstructured = true; // real-valued loop control + } else if (std::get_if( + &loopControl->u)) { eval.isUnstructured = true; // while loop } - // Defer additional processing for an unstructured concurrent loop - // to the EndDoStmt, when the loop is known to be unstructured. }, [&](const parser::EndDoStmt &) { - lower::pft::Evaluation &doEval{evaluationList.front()}; + lower::pft::Evaluation &doEval = evaluationList.front(); eval.controlSuccessor = &doEval; doConstructStack.pop_back(); - if (parentConstruct->lowerAsStructured()) { + if (parentConstruct->lowerAsStructured()) return; - } - // Now that the loop is known to be unstructured, finish concurrent - // loop processing, using NonLabelDoStmt information. + // The loop is unstructured, which wasn't known for all cases when + // visiting the NonLabelDoStmt. parentConstruct->constructExit->isNewBlock = true; - const auto &doStmt{doEval.getIf()}; - assert(doStmt && "missing NonLabelDoStmt"); - auto &control{ - std::get>(doStmt->t)}; - if (!control.has_value()) { + const auto &doStmt = *doEval.getIf(); + const auto &loopControl = + std::get>(doStmt.t); + if (!loopControl.has_value()) return; // infinite loop - } - const auto *concurrent{ - std::get_if(&control->u)}; - if (!concurrent) { - return; - } - // Unstructured concurrent loop. NonLabelDoStmt code accounts - // for one concurrent loop dimension. Reserve preheader, - // header, and latch blocks for the remaining dimensions, and - // one block for a mask expression. - const auto &header{ - std::get(concurrent->t)}; - auto dims{std::get>(header.t) - .size()}; - for (; dims > 1; --dims) { - doEval.localBlocks.emplace_back(nullptr); // preheader - doEval.localBlocks.emplace_back(nullptr); // header - eval.localBlocks.emplace_back(nullptr); // latch - } - if (std::get>(header.t)) { - doEval.localBlocks.emplace_back(nullptr); // mask + if (const auto *concurrent = + std::get_if( + &loopControl->u)) { + // If there is a mask, the EndDoStmt starts a new block. + const auto &header = + std::get(concurrent->t); + eval.isNewBlock |= + std::get>(header.t) + .has_value(); } }, [&](const parser::IfThenStmt &s) { @@ -642,9 +814,8 @@ class PFTBuilder { lastConstructStmtEvaluation = nullptr; }, [&](const parser::EndIfStmt &) { - if (parentConstruct->lowerAsUnstructured()) { + if (parentConstruct->lowerAsUnstructured()) parentConstruct->constructExit->isNewBlock = true; - } if (lastConstructStmtEvaluation) { lastConstructStmtEvaluation->controlSuccessor = parentConstruct->constructExit; @@ -689,37 +860,22 @@ class PFTBuilder { eval.isUnstructured = true; }, + // Default - Common analysis for I/O statements; otherwise nop. [&](const auto &stmt) { using A = std::decay_t; - using IoStmts = std::tuple; - if constexpr (common::HasMember) { + using IoStmts = std::tuple< + parser::BackspaceStmt, parser::CloseStmt, parser::EndfileStmt, + parser::FlushStmt, parser::InquireStmt, parser::OpenStmt, + parser::PrintStmt, parser::ReadStmt, parser::RewindStmt, + parser::WaitStmt, parser::WriteStmt>; + if constexpr (common::HasMember) analyzeIoBranches(eval, stmt); - } - - /* do nothing */ }, }); // Analyze construct evaluations. - if (eval.evaluationList) { + if (eval.evaluationList) analyzeBranches(&eval, *eval.evaluationList); - } - - // Insert branch links for an unstructured IF statement. - if (lastIfStmtEvaluation && lastIfStmtEvaluation != &eval) { - // eval is the action substatement of an IfStmt. - if (eval.lowerAsUnstructured()) { - eval.isNewBlock = true; - markSuccessorAsNewBlock(eval); - lastIfStmtEvaluation->isUnstructured = true; - } - lastIfStmtEvaluation->controlSuccessor = &eval.nonNopSuccessor(); - lastIfStmtEvaluation = nullptr; - } // Set the successor of the last statement in an IF or SELECT block. if (!eval.controlSuccessor && eval.lexicalSuccessor && @@ -729,141 +885,184 @@ class PFTBuilder { } // Propagate isUnstructured flag to enclosing construct. - if (parentConstruct && eval.isUnstructured) { + if (parentConstruct && eval.isUnstructured) parentConstruct->isUnstructured = true; - } // The successor of a branch starts a new block. if (eval.controlSuccessor && eval.isActionStmt() && - eval.lowerAsUnstructured()) { + eval.lowerAsUnstructured()) markSuccessorAsNewBlock(eval); + } + } + + /// For multiple entry subprograms, build a list of the dummy arguments that + /// appear in some, but not all entry points. For those that are functions, + /// also find one of the largest function results, since a single result + /// container holds the result for all entries. + void processEntryPoints() { + auto *unit = evaluationListStack.back()->front().getOwningProcedure(); + int entryCount = unit->entryPointList.size(); + if (entryCount == 1) + return; + llvm::DenseMap dummyCountMap; + for (int entryIndex = 0; entryIndex < entryCount; ++entryIndex) { + unit->setActiveEntry(entryIndex); + const auto &details = + unit->getSubprogramSymbol().get(); + for (auto *arg : details.dummyArgs()) { + if (!arg) + continue; // alternate return specifier (no actual argument) + const auto iter = dummyCountMap.find(arg); + if (iter == dummyCountMap.end()) + dummyCountMap.try_emplace(arg, 1); + else + ++iter->second; + } + if (details.isFunction()) { + const auto *resultSym = &details.result(); + assert(resultSym && "missing result symbol"); + if (!unit->primaryResult || + unit->primaryResult->size() < resultSym->size()) + unit->primaryResult = resultSym; } } + unit->setActiveEntry(0); + for (auto arg : dummyCountMap) + if (arg.second < entryCount) + unit->nonUniversalDummyArguments.push_back(arg.first); } std::unique_ptr pgm; - std::vector parentVariantStack; + std::vector pftParentStack; const semantics::SemanticsContext &semanticsContext; /// functionList points to the internal or module procedure function list /// of a FunctionLikeUnit or a ModuleLikeUnit. It may be null. - std::list *functionList{nullptr}; + std::list *functionList{}; std::vector constructAndDirectiveStack{}; std::vector doConstructStack{}; /// evaluationListStack is the current nested construct evaluationList state. std::vector evaluationListStack{}; - llvm::DenseMap *labelEvaluationMap{ - nullptr}; - lower::pft::SymbolLabelMap *assignSymbolLabelMap{nullptr}; + llvm::DenseMap *labelEvaluationMap{}; + lower::pft::SymbolLabelMap *assignSymbolLabelMap{}; std::map constructNameMap{}; - lower::pft::Evaluation *lastLexicalEvaluation{nullptr}; + lower::pft::Evaluation *lastLexicalEvaluation{}; }; class PFTDumper { public: - void dumpPFT(llvm::raw_ostream &outputStream, lower::pft::Program &pft) { + void dumpPFT(llvm::raw_ostream &outputStream, + const lower::pft::Program &pft) { for (auto &unit : pft.getUnits()) { std::visit(common::visitors{ - [&](lower::pft::BlockDataUnit &unit) { + [&](const lower::pft::BlockDataUnit &unit) { outputStream << getNodeIndex(unit) << " "; outputStream << "BlockData: "; - outputStream << "\nEndBlockData\n\n"; + outputStream << "\nEnd BlockData\n\n"; }, - [&](lower::pft::FunctionLikeUnit &func) { + [&](const lower::pft::FunctionLikeUnit &func) { dumpFunctionLikeUnit(outputStream, func); }, - [&](lower::pft::ModuleLikeUnit &unit) { + [&](const lower::pft::ModuleLikeUnit &unit) { dumpModuleLikeUnit(outputStream, unit); }, + [&](const lower::pft::CompilerDirectiveUnit &unit) { + dumpCompilerDirectiveUnit(outputStream, unit); + }, }, unit); } } - llvm::StringRef evaluationName(lower::pft::Evaluation &eval) { - return eval.visit(common::visitors{ - [](const auto &parseTreeNode) { - return parser::ParseTreeDumper::GetNodeName(parseTreeNode); - }, + llvm::StringRef evaluationName(const lower::pft::Evaluation &eval) { + return eval.visit([](const auto &parseTreeNode) { + return parser::ParseTreeDumper::GetNodeName(parseTreeNode); }); } - void dumpEvaluationList(llvm::raw_ostream &outputStream, - lower::pft::EvaluationList &evaluationList, - int indent = 1) { - static const std::string white{" ++"}; - std::string indentString{white.substr(0, indent * 2)}; - for (lower::pft::Evaluation &eval : evaluationList) { - llvm::StringRef name{evaluationName(eval)}; - std::string bang{eval.isUnstructured ? "!" : ""}; - if (eval.isConstruct() || eval.isDirective()) { - outputStream << indentString << "<<" << name << bang << ">>"; - if (eval.constructExit) { - outputStream << " -> " << eval.constructExit->printIndex; - } - outputStream << '\n'; - dumpEvaluationList(outputStream, *eval.evaluationList, indent + 1); - outputStream << indentString << "<>\n"; - continue; - } - outputStream << indentString; - if (eval.printIndex) { - outputStream << eval.printIndex << ' '; - } - if (eval.isNewBlock) { - outputStream << '^'; - } - if (eval.localBlocks.size()) { - outputStream << '*'; - } - outputStream << name << bang; - if (eval.isActionStmt() || eval.isConstructStmt()) { - if (eval.controlSuccessor) { - outputStream << " -> " << eval.controlSuccessor->printIndex; - } - } - if (eval.position.size()) { - outputStream << ": " << eval.position.ToString(); - } + void dumpEvaluation(llvm::raw_ostream &outputStream, + const lower::pft::Evaluation &eval, + const std::string &indentString, int indent = 1) { + llvm::StringRef name = evaluationName(eval); + std::string bang = eval.isUnstructured ? "!" : ""; + if (eval.isConstruct() || eval.isDirective()) { + outputStream << indentString << "<<" << name << bang << ">>"; + if (eval.constructExit) + outputStream << " -> " << eval.constructExit->printIndex; outputStream << '\n'; + dumpEvaluationList(outputStream, *eval.evaluationList, indent + 1); + outputStream << indentString << "<>\n"; + return; } + outputStream << indentString; + if (eval.printIndex) + outputStream << eval.printIndex << ' '; + if (eval.isNewBlock) + outputStream << '^'; + outputStream << name << bang; + if (eval.isActionStmt() || eval.isConstructStmt()) { + if (eval.negateCondition) + outputStream << " [negate]"; + if (eval.controlSuccessor) + outputStream << " -> " << eval.controlSuccessor->printIndex; + } else if (eval.isA() && eval.lexicalSuccessor) { + outputStream << " -> " << eval.lexicalSuccessor->printIndex; + } + if (!eval.position.empty()) + outputStream << ": " << eval.position.ToString(); + outputStream << '\n'; + } + + void dumpEvaluation(llvm::raw_ostream &ostream, + const lower::pft::Evaluation &eval) { + dumpEvaluation(ostream, eval, ""); + } + + void dumpEvaluationList(llvm::raw_ostream &outputStream, + const lower::pft::EvaluationList &evaluationList, + int indent = 1) { + static const auto white = " ++"s; + auto indentString = white.substr(0, indent * 2); + for (const auto &eval : evaluationList) + dumpEvaluation(outputStream, eval, indentString, indent); } - void dumpFunctionLikeUnit(llvm::raw_ostream &outputStream, - lower::pft::FunctionLikeUnit &functionLikeUnit) { + void + dumpFunctionLikeUnit(llvm::raw_ostream &outputStream, + const lower::pft::FunctionLikeUnit &functionLikeUnit) { outputStream << getNodeIndex(functionLikeUnit) << " "; - llvm::StringRef unitKind{}; - std::string name{}; - std::string header{}; + llvm::StringRef unitKind; + llvm::StringRef name; + llvm::StringRef header; if (functionLikeUnit.beginStmt) { functionLikeUnit.beginStmt->visit(common::visitors{ - [&](const parser::Statement &statement) { + [&](const parser::Statement &stmt) { unitKind = "Program"; - name = statement.statement.v.ToString(); + name = toStringRef(stmt.statement.v.source); }, - [&](const parser::Statement &statement) { + [&](const parser::Statement &stmt) { unitKind = "Function"; - name = std::get(statement.statement.t).ToString(); - header = statement.source.ToString(); + name = toStringRef(std::get(stmt.statement.t).source); + header = toStringRef(stmt.source); }, - [&](const parser::Statement &statement) { + [&](const parser::Statement &stmt) { unitKind = "Subroutine"; - name = std::get(statement.statement.t).ToString(); - header = statement.source.ToString(); + name = toStringRef(std::get(stmt.statement.t).source); + header = toStringRef(stmt.source); }, - [&](const parser::Statement &statement) { + [&](const parser::Statement &stmt) { unitKind = "MpSubprogram"; - name = statement.statement.v.ToString(); - header = statement.source.ToString(); + name = toStringRef(stmt.statement.v.source); + header = toStringRef(stmt.source); }, - [&](const auto &) {}, + [&](const auto &) { llvm_unreachable("not a valid begin stmt"); }, }); } else { unitKind = "Program"; name = ""; } outputStream << unitKind << ' ' << name; - if (header.size()) + if (!header.empty()) outputStream << ": " << header; outputStream << '\n'; dumpEvaluationList(outputStream, functionLikeUnit.evaluationList); @@ -871,28 +1070,38 @@ class PFTDumper { outputStream << "\nContains\n"; for (auto &func : functionLikeUnit.nestedFunctions) dumpFunctionLikeUnit(outputStream, func); - outputStream << "EndContains\n"; + outputStream << "End Contains\n"; } - outputStream << "End" << unitKind << ' ' << name << "\n\n"; + outputStream << "End " << unitKind << ' ' << name << "\n\n"; } void dumpModuleLikeUnit(llvm::raw_ostream &outputStream, - lower::pft::ModuleLikeUnit &moduleLikeUnit) { + const lower::pft::ModuleLikeUnit &moduleLikeUnit) { outputStream << getNodeIndex(moduleLikeUnit) << " "; outputStream << "ModuleLike: "; outputStream << "\nContains\n"; for (auto &func : moduleLikeUnit.nestedFunctions) dumpFunctionLikeUnit(outputStream, func); - outputStream << "EndContains\nEndModuleLike\n\n"; + outputStream << "End Contains\nEnd ModuleLike\n\n"; + } + + // Top level directives + void dumpCompilerDirectiveUnit( + llvm::raw_ostream &outputStream, + const lower::pft::CompilerDirectiveUnit &directive) { + outputStream << getNodeIndex(directive) << " "; + outputStream << "CompilerDirective: !"; + outputStream << directive.get() + .source.ToString(); + outputStream << "\nEnd CompilerDirective\n\n"; } template std::size_t getNodeIndex(const T &node) { - auto addr{static_cast(&node)}; - auto it{nodeIndexes.find(addr)}; - if (it != nodeIndexes.end()) { + auto addr = static_cast(&node); + auto it = nodeIndexes.find(addr); + if (it != nodeIndexes.end()) return it->second; - } nodeIndexes.try_emplace(addr, nextIndex); return nextIndex++; } @@ -919,12 +1128,9 @@ static lower::pft::ModuleLikeUnit::ModuleStatement getModuleStmt(const T &mod) { return result; } -static const semantics::Symbol *getSymbol( - std::optional &beginStmt) { - if (!beginStmt) - return nullptr; - - const auto *symbol = beginStmt->visit(common::visitors{ +template +static const semantics::Symbol *getSymbol(A &beginStmt) { + const auto *symbol = beginStmt.visit(common::visitors{ [](const parser::Statement &stmt) -> const semantics::Symbol * { return stmt.statement.v.symbol; }, [](const parser::Statement &stmt) @@ -937,8 +1143,14 @@ static const semantics::Symbol *getSymbol( }, [](const parser::Statement &stmt) -> const semantics::Symbol * { return stmt.statement.v.symbol; }, + [](const parser::Statement &stmt) + -> const semantics::Symbol * { return stmt.statement.v.symbol; }, + [](const parser::Statement &stmt) + -> const semantics::Symbol * { + return std::get(stmt.statement.t).symbol; + }, [](const auto &) -> const semantics::Symbol * { - llvm_unreachable("unknown FunctionLike beginStmt"); + llvm_unreachable("unknown FunctionLike or ModuleLike beginStmt"); return nullptr; }}); assert(symbol && "parser::Name must have resolved symbol"); @@ -955,13 +1167,25 @@ bool Fortran::lower::pft::Evaluation::lowerAsUnstructured() const { lower::pft::FunctionLikeUnit * Fortran::lower::pft::Evaluation::getOwningProcedure() const { - return parentVariant.visit(common::visitors{ + return parent.visit(common::visitors{ [](lower::pft::FunctionLikeUnit &c) { return &c; }, [&](lower::pft::Evaluation &c) { return c.getOwningProcedure(); }, [](auto &) -> lower::pft::FunctionLikeUnit * { return nullptr; }, }); } +bool Fortran::lower::definedInCommonBlock(const semantics::Symbol &sym) { + return semantics::FindCommonBlockContaining(sym); +} + +/// Is the symbol `sym` a global? +static bool symbolIsGlobal(const semantics::Symbol &sym) { + if (const auto *details = sym.detailsIf()) + if (details->init()) + return true; + return semantics::IsSaved(sym) || lower::definedInCommonBlock(sym); +} + namespace { /// This helper class is for sorting the symbols in the symbol table. We want /// the symbols in an order such that a symbol will be visited after those it @@ -969,26 +1193,112 @@ namespace { /// symbol table, which is sorted by name. struct SymbolDependenceDepth { explicit SymbolDependenceDepth( - std::vector> &vars) - : vars{vars} {} + std::vector> &vars, bool reentrant) + : vars{vars}, reentrant{reentrant} {} + + void analyzeAliasesInCurrentScope(const semantics::Scope &scope) { + for (const auto &iter : scope) { + const auto &ultimate = iter.second.get().GetUltimate(); + if (skipSymbol(ultimate)) + continue; + bool isDeclaration = scope != ultimate.owner(); + analyzeAliases(ultimate.owner(), isDeclaration); + } + // add all aggregate stores to the front of the work list + adjustSize(1); + // The copy in the loop matters, 'stores' will still be used. + for (auto st : stores) { + vars[0].emplace_back(std::move(st)); + } + } + // Analyze the equivalence sets. This analysis need not be performed when the + // scope has no equivalence sets. + void analyzeAliases(const semantics::Scope &scope, bool isDeclaration) { + if (scope.equivalenceSets().empty()) + return; + if (scopeAnlyzedForAliases.find(&scope) != scopeAnlyzedForAliases.end()) + return; + scopeAnlyzedForAliases.insert(&scope); + Fortran::lower::IntervalSet intervals; + llvm::DenseMap> + aliasSets; + llvm::DenseMap setIsGlobal; + + // 1. Construct the intervals. Determine each entity's interval, merging + // overlapping intervals into aggregates. + for (const auto &pair : scope) { + const auto &sym = pair.second.get(); + if (skipSymbol(sym)) + continue; + LLVM_DEBUG(llvm::dbgs() << "symbol: " << sym << '\n'); + intervals.merge(sym.offset(), sym.offset() + sym.size() - 1); + } + + // 2. Compute alias sets. Adds each entity to a set for the interval it + // appears to be mapped into. + for (const auto &pair : scope) { + const auto &sym = pair.second.get(); + if (skipSymbol(sym)) + continue; + auto iter = intervals.find(sym.offset()); + if (iter != intervals.end()) { + LLVM_DEBUG(llvm::dbgs() + << "symbol: " << toStringRef(sym.name()) << " on [" + << iter->first << ".." << iter->second << "]\n"); + aliasSets[iter->first].push_back(&sym); + if (symbolIsGlobal(sym)) + setIsGlobal.insert({iter->first, &sym}); + } + } + + // 3. For each alias set with more than 1 member, add an Interval to the + // stores. The Interval will be lowered into a single memory allocation, + // with the co-located, overlapping variables mapped into that memory range. + for (const auto &pair : aliasSets) { + if (pair.second.size() > 1) { + // Set contains more than 1 aliasing variable. + // 1. Mark the symbols as aliasing for lowering. + for (auto *sym : pair.second) + aliasSyms.insert(sym); + auto gvarIter = setIsGlobal.find(pair.first); + auto iter = intervals.find(pair.first); + auto ibgn = iter->first; + auto ilen = iter->second - ibgn + 1; + // 2. Add an Interval to the list of stores allocated for this unit. + lower::pft::Variable::Interval interval(ibgn, ilen); + if (gvarIter != setIsGlobal.end()) { + LLVM_DEBUG(llvm::dbgs() + << "interval [" << ibgn << ".." << ibgn + ilen + << ") added as global " << *gvarIter->second << '\n'); + stores.emplace_back(std::move(interval), scope, pair.second, + isDeclaration); + } else { + LLVM_DEBUG(llvm::dbgs() << "interval [" << ibgn << ".." << ibgn + ilen + << ") added\n"); + stores.emplace_back(std::move(interval), scope, isDeclaration); + } + } + } + } // Recursively visit each symbol to determine the height of its dependence on // other symbols. int analyze(const semantics::Symbol &sym) { auto done = seen.insert(&sym); + LLVM_DEBUG(llvm::dbgs() << "analyze symbol: " << sym << '\n'); if (!done.second) return 0; if (semantics::IsProcedure(sym)) { // TODO: add declaration? return 0; } - if (sym.has() || - sym.has() || - sym.has() || - sym.has()) { - // FIXME: do we want to do anything with any of these? + auto ultimate = sym.GetUltimate(); + if (!ultimate.has() && + !ultimate.has()) return 0; - } + + if (sym.has()) + llvm_unreachable("not yet implemented - derived type analysis"); // Symbol must be something lowering will have to allocate. bool global = semantics::IsSaved(sym); @@ -998,9 +1308,12 @@ struct SymbolDependenceDepth { // check CHARACTER's length if (symTy->category() == semantics::DeclTypeSpec::Character) - if (auto e = symTy->characterTypeSpec().length().GetExplicit()) + if (auto e = symTy->characterTypeSpec().length().GetExplicit()) { + // turn variable into a global if this unit is not reentrant + global = global || !reentrant; for (const auto &s : evaluate::CollectSymbols(*e)) depth = std::max(analyze(s) + 1, depth); + } if (const auto *details = sym.detailsIf()) { auto doExplicit = [&](const auto &bound) { @@ -1011,11 +1324,15 @@ struct SymbolDependenceDepth { } }; // handle any symbols in array bound declarations + if (!details->shape().empty()) + global = global || !reentrant; for (const auto &subs : details->shape()) { doExplicit(subs.lbound()); doExplicit(subs.ubound()); } // handle any symbols in coarray bound declarations + if (!details->coshape().empty()) + global = global || !reentrant; for (const auto &subs : details->coshape()) { doExplicit(subs.lbound()); doExplicit(subs.ubound()); @@ -1030,23 +1347,69 @@ struct SymbolDependenceDepth { } adjustSize(depth + 1); vars[depth].emplace_back(sym, global, depth); - if (Fortran::semantics::IsAllocatable(sym)) + if (semantics::IsAllocatable(sym)) vars[depth].back().setHeapAlloc(); - if (Fortran::semantics::IsPointer(sym)) + if (semantics::IsPointer(sym)) vars[depth].back().setPointer(); - if (sym.attrs().test(Fortran::semantics::Attr::TARGET)) + if (ultimate.attrs().test(semantics::Attr::TARGET)) vars[depth].back().setTarget(); + + // If there are alias sets, then link the participating variables to their + // aggregate stores when constructing the new variable on the list. + if (auto *store = findStoreIfAlias(sym)) { + vars[depth].back().setAlias(store->getOffset()); + } return depth; } - // Save the final list of symbols as a single vector and free the rest. + /// Save the final list of variable allocations as a single vector and free + /// the rest. void finalize() { for (int i = 1, end = vars.size(); i < end; ++i) vars[0].insert(vars[0].end(), vars[i].begin(), vars[i].end()); vars.resize(1); } + Fortran::lower::pft::Variable::AggregateStore * + findStoreIfAlias(const Fortran::evaluate::Symbol &sym) { + const auto &ultimate = sym.GetUltimate(); + const auto &scope = ultimate.owner(); + // Expect the total number of EQUIVALENCE sets to be small for a typical + // Fortran program. + if (aliasSyms.find(&ultimate) != aliasSyms.end()) { + LLVM_DEBUG(llvm::dbgs() << "symbol: " << ultimate << '\n'); + LLVM_DEBUG(llvm::dbgs() << "scope: " << scope << '\n'); + auto off = ultimate.offset(); + for (auto &v : stores) { + if (v.scope == &scope) { + auto bot = std::get<0>(v.interval); + if (off >= bot && off < bot + std::get<1>(v.interval)) + return &v; + } + } + // clang-format off + LLVM_DEBUG( + llvm::dbgs() << "looking for " << off << "\n{\n"; + for (auto v : stores) { + llvm::dbgs() << " in scope: " << v.scope << "\n"; + llvm::dbgs() << " i = [" << std::get<0>(v.interval) << ".." + << std::get<0>(v.interval) + std::get<1>(v.interval) + << "]\n"; + } + llvm::dbgs() << "}\n"); + // clang-format on + llvm_unreachable("the store must be present"); + } + return nullptr; + } + private: + /// Skip symbol in alias analysis. + bool skipSymbol(const semantics::Symbol &sym) { + return !sym.has() || + lower::definedInCommonBlock(sym); + } + // Make sure the table is of appropriate size. void adjustSize(std::size_t size) { if (vars.size() < size) @@ -1055,93 +1418,102 @@ struct SymbolDependenceDepth { llvm::SmallSet seen; std::vector> &vars; + llvm::SmallSet aliasSyms; + llvm::SmallSet scopeAnlyzedForAliases; + std::vector stores; + bool reentrant; }; } // namespace -void Fortran::lower::pft::FunctionLikeUnit::processSymbolTable( - const semantics::Scope &scope) { - // TODO: handle equivalence and common blocks - if (!scope.equivalenceSets().empty()) { - llvm::errs() << "TODO: equivalence not yet handled in lowering.\n" - << "note: equivalence used in " - << (scope.GetName() && !scope.GetName()->empty() - ? scope.GetName()->ToString() - : "unnamed program"s) - << "\n"; - exit(1); - } - SymbolDependenceDepth sdd{varList}; +static void processSymbolTable( + const semantics::Scope &scope, + std::vector> &varList, + bool reentrant) { + SymbolDependenceDepth sdd{varList, reentrant}; + sdd.analyzeAliasesInCurrentScope(scope); for (const auto &iter : scope) sdd.analyze(iter.second.get()); sdd.finalize(); } Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit( - const parser::MainProgram &func, const lower::pft::ParentVariant &parent, + const parser::MainProgram &func, const lower::pft::PftNode &parent, const semantics::SemanticsContext &semanticsContext) : ProgramUnit{func, parent}, endStmt{ getFunctionStmt( func)} { - const auto &ps{ - std::get>>(func.t)}; - if (ps.has_value()) { - FunctionStatement begin{ps.value()}; - beginStmt = begin; - symbol = getSymbol(beginStmt); - processSymbolTable(*symbol->scope()); + const auto &programStmt = + std::get>>(func.t); + if (programStmt.has_value()) { + beginStmt = FunctionStatement(programStmt.value()); + const auto *symbol = getSymbol(*beginStmt); + entryPointList[0].first = symbol; + processSymbolTable(*symbol->scope(), varList, isRecursive()); } else { - processSymbolTable(semanticsContext.FindScope( - std::get>(func.t).source)); + processSymbolTable( + semanticsContext.FindScope( + std::get>(func.t).source), + varList, isRecursive()); } } Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit( - const parser::FunctionSubprogram &func, - const lower::pft::ParentVariant &parent, + const parser::FunctionSubprogram &func, const lower::pft::PftNode &parent, const semantics::SemanticsContext &) : ProgramUnit{func, parent}, beginStmt{getFunctionStmt(func)}, - endStmt{getFunctionStmt(func)}, symbol{getSymbol( - beginStmt)} { - processSymbolTable(*symbol->scope()); + endStmt{getFunctionStmt(func)} { + const auto *symbol = getSymbol(*beginStmt); + entryPointList[0].first = symbol; + processSymbolTable(*symbol->scope(), varList, isRecursive()); } Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit( - const parser::SubroutineSubprogram &func, - const lower::pft::ParentVariant &parent, + const parser::SubroutineSubprogram &func, const lower::pft::PftNode &parent, const semantics::SemanticsContext &) : ProgramUnit{func, parent}, beginStmt{getFunctionStmt(func)}, - endStmt{getFunctionStmt(func)}, - symbol{getSymbol(beginStmt)} { - processSymbolTable(*symbol->scope()); + endStmt{getFunctionStmt(func)} { + const auto *symbol = getSymbol(*beginStmt); + entryPointList[0].first = symbol; + processSymbolTable(*symbol->scope(), varList, isRecursive()); } Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit( const parser::SeparateModuleSubprogram &func, - const lower::pft::ParentVariant &parent, - const semantics::SemanticsContext &) + const lower::pft::PftNode &parent, const semantics::SemanticsContext &) : ProgramUnit{func, parent}, beginStmt{getFunctionStmt(func)}, - endStmt{getFunctionStmt(func)}, - symbol{getSymbol(beginStmt)} { - processSymbolTable(*symbol->scope()); + endStmt{getFunctionStmt(func)} { + const auto *symbol = getSymbol(*beginStmt); + entryPointList[0].first = symbol; + processSymbolTable(*symbol->scope(), varList, isRecursive()); } Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit( - const parser::Module &m, const lower::pft::ParentVariant &parent) + const parser::Module &m, const lower::pft::PftNode &parent) : ProgramUnit{m, parent}, beginStmt{getModuleStmt(m)}, - endStmt{getModuleStmt(m)} {} + endStmt{getModuleStmt(m)} { + const auto *symbol = getSymbol(beginStmt); + processSymbolTable(*symbol->scope(), varList, /*reentrant=*/false); +} Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit( - const parser::Submodule &m, const lower::pft::ParentVariant &parent) + const parser::Submodule &m, const lower::pft::PftNode &parent) : ProgramUnit{m, parent}, beginStmt{getModuleStmt( m)}, - endStmt{getModuleStmt(m)} {} + endStmt{getModuleStmt(m)} { + const auto *symbol = getSymbol(beginStmt); + processSymbolTable(*symbol->scope(), varList, /*reentrant=*/false); +} Fortran::lower::pft::BlockDataUnit::BlockDataUnit( - const parser::BlockData &bd, const lower::pft::ParentVariant &parent) - : ProgramUnit{bd, parent} {} + const parser::BlockData &bd, const lower::pft::PftNode &parent, + const semantics::SemanticsContext &semanticsContext) + : ProgramUnit{bd, parent}, + symTab{semanticsContext.FindScope( + std::get>(bd.t).source)} { +} std::unique_ptr Fortran::lower::createPFT(const parser::Program &root, @@ -1151,9 +1523,67 @@ Fortran::lower::createPFT(const parser::Program &root, return walker.result(); } +// FIXME: FlangDriver +// This option should be integrated with the real driver as the default of +// RECURSIVE vs. NON_RECURSIVE may be changed by other command line options, +// etc., etc. +bool Fortran::lower::defaultRecursiveFunctionSetting() { + return !nonRecursiveProcedures; +} + void Fortran::lower::dumpPFT(llvm::raw_ostream &outputStream, - lower::pft::Program &pft) { + const lower::pft::Program &pft) { PFTDumper{}.dumpPFT(outputStream, pft); } -void Fortran::lower::pft::Program::dump() { dumpPFT(llvm::errs(), *this); } +void Fortran::lower::pft::Program::dump() const { + dumpPFT(llvm::errs(), *this); +} + +void Fortran::lower::pft::Evaluation::dump() const { + PFTDumper{}.dumpEvaluation(llvm::errs(), *this); +} + +void Fortran::lower::pft::Variable::dump() const { + if (auto *s = std::get_if(&var)) { + llvm::errs() << "symbol: " << s->symbol->name(); + llvm::errs() << " (depth: " << s->depth << ')'; + if (s->global) + llvm::errs() << ", global"; + if (s->heapAlloc) + llvm::errs() << ", allocatable"; + if (s->pointer) + llvm::errs() << ", pointer"; + if (s->target) + llvm::errs() << ", target"; + if (s->aliaser) + llvm::errs() << ", equivalence(" << s->aliasOffset << ')'; + } else if (auto *s = std::get_if(&var)) { + llvm::errs() << "interval[" << std::get<0>(s->interval) << ", " + << std::get<1>(s->interval) << "]:"; + if (s->isGlobal()) + llvm::errs() << ", global"; + if (s->vars.size()) { + llvm::errs() << ", vars: {"; + llvm::interleaveComma(s->vars, llvm::errs(), + [](auto *y) { llvm::errs() << *y; }); + llvm::errs() << '}'; + } + } else { + llvm_unreachable("not a Variable"); + } + llvm::errs() << '\n'; +} + +void Fortran::lower::pft::FunctionLikeUnit::dump() const { + PFTDumper{}.dumpFunctionLikeUnit(llvm::errs(), *this); +} + +void Fortran::lower::pft::ModuleLikeUnit::dump() const { + PFTDumper{}.dumpModuleLikeUnit(llvm::errs(), *this); +} + +/// The BlockDataUnit dump is just the associated symbol table. +void Fortran::lower::pft::BlockDataUnit::dump() const { + llvm::errs() << "block data {\n" << symTab << "\n}\n"; +} diff --git a/flang/lib/Optimizer/CMakeLists.txt b/flang/lib/Optimizer/CMakeLists.txt index 0a7286339e2e..b83d6a079db6 100644 --- a/flang/lib/Optimizer/CMakeLists.txt +++ b/flang/lib/Optimizer/CMakeLists.txt @@ -10,11 +10,16 @@ add_flang_library(FIROptimizer Support/InternalNames.cpp Support/KindMapping.cpp + CodeGen/CGOps.cpp + CodeGen/PreCGRewrite.cpp + Transforms/Inliner.cpp DEPENDS FIROpsIncGen + FIROptCodeGenPassIncGen FIROptTransformsPassIncGen + CGOpsIncGen ${dialect_libs} LINK_LIBS diff --git a/flang/lib/Optimizer/CodeGen/CGOps.cpp b/flang/lib/Optimizer/CodeGen/CGOps.cpp new file mode 100644 index 000000000000..527066ec5ccd --- /dev/null +++ b/flang/lib/Optimizer/CodeGen/CGOps.cpp @@ -0,0 +1,64 @@ +//===-- CGOps.cpp -- FIR codegen operations -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// + +#include "CGOps.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Dialect/FIRType.h" + +/// FIR codegen dialect constructor. +fir::FIRCodeGenDialect::FIRCodeGenDialect(mlir::MLIRContext *ctx) + : mlir::Dialect("fircg", ctx, mlir::TypeID::get()) { + addOperations< +#define GET_OP_LIST +#include "flang/Optimizer/CodeGen/CGOps.cpp.inc" + >(); +} + +// anchor the class vtable to this compilation unit +fir::FIRCodeGenDialect::~FIRCodeGenDialect() { + // do nothing +} + +#define GET_OP_CLASSES +#include "flang/Optimizer/CodeGen/CGOps.cpp.inc" + +unsigned fir::cg::XEmboxOp::getOutRank() { + if (slice().empty()) + return getRank(); + auto outRank = fir::SliceOp::getOutputRank(slice()); + assert(outRank >= 1); + return outRank; +} + +unsigned fir::cg::XReboxOp::getOutRank() { + if (auto seqTy = + fir::dyn_cast_ptrOrBoxEleTy(getType()).dyn_cast()) + return seqTy.getDimension(); + return 0; +} + +unsigned fir::cg::XReboxOp::getRank() { + if (auto seqTy = fir::dyn_cast_ptrOrBoxEleTy(box().getType()) + .dyn_cast()) + return seqTy.getDimension(); + return 0; +} + +unsigned fir::cg::XArrayCoorOp::getRank() { + auto memrefTy = memref().getType(); + if (memrefTy.isa()) + if (auto seqty = + fir::dyn_cast_ptrOrBoxEleTy(memrefTy).dyn_cast()) + return seqty.getDimension(); + return shape().size(); +} diff --git a/flang/lib/Optimizer/CodeGen/CGOps.h b/flang/lib/Optimizer/CodeGen/CGOps.h new file mode 100644 index 000000000000..f5f552c63376 --- /dev/null +++ b/flang/lib/Optimizer/CodeGen/CGOps.h @@ -0,0 +1,24 @@ +//===-- CGOps.h -------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// + +#ifndef OPTIMIZER_CODEGEN_CGOPS_H +#define OPTIMIZER_CODEGEN_CGOPS_H + +#include "flang/Optimizer/Dialect/FIRType.h" +#include "mlir/Dialect/StandardOps/IR/Ops.h" + +using namespace mlir; + +#define GET_OP_CLASSES +#include "flang/Optimizer/CodeGen/CGOps.h.inc" + +#endif diff --git a/flang/lib/Optimizer/CodeGen/PassDetail.h b/flang/lib/Optimizer/CodeGen/PassDetail.h new file mode 100644 index 000000000000..f7030131beff --- /dev/null +++ b/flang/lib/Optimizer/CodeGen/PassDetail.h @@ -0,0 +1,26 @@ +//===- PassDetail.h - Optimizer code gen Pass class details -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef OPTMIZER_CODEGEN_PASSDETAIL_H +#define OPTMIZER_CODEGEN_PASSDETAIL_H + +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/OpenMP/OpenMPDialect.h" +#include "mlir/IR/BuiltinDialect.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassRegistry.h" + +namespace fir { + +#define GEN_PASS_CLASSES +#include "flang/Optimizer/CodeGen/CGPasses.h.inc" + +} // namespace fir + +#endif // OPTMIZER_CODEGEN_PASSDETAIL_H diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp new file mode 100644 index 000000000000..37c6e43cb7ac --- /dev/null +++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp @@ -0,0 +1,263 @@ +//===-- PreCGRewrite.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// + +#include "CGOps.h" +#include "PassDetail.h" +#include "flang/Optimizer/CodeGen/CodeGen.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/Support/FIRContext.h" +#include "mlir/Transforms/DialectConversion.h" +#include "llvm/ADT/STLExtras.h" + +//===----------------------------------------------------------------------===// +// Codegen rewrite: rewriting of subgraphs of ops +//===----------------------------------------------------------------------===// + +using namespace fir; + +#define DEBUG_TYPE "flang-codegen-rewrite" + +static void populateShape(llvm::SmallVectorImpl &vec, + ShapeOp shape) { + vec.append(shape.extents().begin(), shape.extents().end()); +} + +// Operands of fir.shape_shift split into two vectors. +static void populateShapeAndShift(llvm::SmallVectorImpl &shapeVec, + llvm::SmallVectorImpl &shiftVec, + ShapeShiftOp shift) { + auto endIter = shift.pairs().end(); + for (auto i = shift.pairs().begin(); i != endIter;) { + shiftVec.push_back(*i++); + shapeVec.push_back(*i++); + } +} + +static void populateShift(llvm::SmallVectorImpl &vec, + ShiftOp shift) { + vec.append(shift.origins().begin(), shift.origins().end()); +} + +namespace { + +/// Convert fir.embox to the extended form where necessary. +/// +/// The embox operation can take arguments that specify multidimensional array +/// properties at runtime. These properties may be shared between distinct +/// objects that have the same properties. Before we lower these small DAGs to +/// LLVM-IR, we gather all the information into a single extended operation. For +/// example, +/// ``` +/// %1 = fir.shape_shift %4, %5 : (index, index) -> !fir.shapeshift<1> +/// %2 = fir.slice %6, %7, %8 : (index, index, index) -> !fir.slice<1> +/// %3 = fir.embox %0 (%1) [%2] : (!fir.ref>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box> +/// ``` +/// can be rewritten as +/// ``` +/// %1 = fircg.ext_embox %0(%5) origin %4[%6, %7, %8] : (!fir.ref>, index, index, index, index, index) -> !fir.box> +/// ``` +class EmboxConversion : public mlir::OpRewritePattern { +public: + using OpRewritePattern::OpRewritePattern; + + mlir::LogicalResult + matchAndRewrite(EmboxOp embox, + mlir::PatternRewriter &rewriter) const override { + auto shapeVal = embox.getShape(); + // If the embox does not include a shape, then do not convert it + if (shapeVal) + return rewriteDynamicShape(embox, rewriter, shapeVal); + if (auto boxTy = embox.getType().dyn_cast()) + if (auto seqTy = boxTy.getEleTy().dyn_cast()) + if (seqTy.hasConstantShape()) + return rewriteStaticShape(embox, rewriter, seqTy); + return mlir::failure(); + } + + mlir::LogicalResult rewriteStaticShape(EmboxOp embox, + mlir::PatternRewriter &rewriter, + SequenceType seqTy) const { + auto loc = embox.getLoc(); + llvm::SmallVector shapeOpers; + auto idxTy = rewriter.getIndexType(); + for (auto ext : seqTy.getShape()) { + auto iAttr = rewriter.getIndexAttr(ext); + auto extVal = rewriter.create(loc, idxTy, iAttr); + shapeOpers.push_back(extVal); + } + auto xbox = rewriter.create( + loc, embox.getType(), embox.memref(), shapeOpers, llvm::None, + llvm::None, llvm::None, embox.lenParams()); + LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n'); + rewriter.replaceOp(embox, xbox.getOperation()->getResults()); + return mlir::success(); + } + + mlir::LogicalResult rewriteDynamicShape(EmboxOp embox, + mlir::PatternRewriter &rewriter, + mlir::Value shapeVal) const { + auto loc = embox.getLoc(); + auto shapeOp = dyn_cast(shapeVal.getDefiningOp()); + llvm::SmallVector shapeOpers; + llvm::SmallVector shiftOpers; + if (shapeOp) { + populateShape(shapeOpers, shapeOp); + } else { + auto shiftOp = dyn_cast(shapeVal.getDefiningOp()); + assert(shiftOp && "shape is neither fir.shape nor fir.shape_shift"); + populateShapeAndShift(shapeOpers, shiftOpers, shiftOp); + } + llvm::SmallVector sliceOpers; + llvm::SmallVector subcompOpers; + if (auto s = embox.getSlice()) + if (auto sliceOp = dyn_cast_or_null(s.getDefiningOp())) { + sliceOpers.append(sliceOp.triples().begin(), sliceOp.triples().end()); + subcompOpers.append(sliceOp.fields().begin(), sliceOp.fields().end()); + } + auto xbox = rewriter.create( + loc, embox.getType(), embox.memref(), shapeOpers, shiftOpers, + sliceOpers, subcompOpers, embox.lenParams()); + LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n'); + rewriter.replaceOp(embox, xbox.getOperation()->getResults()); + return mlir::success(); + } +}; + +/// Convert fir.rebox to the extended form where necessary. +/// +/// For example, +/// ``` +/// %5 = fir.rebox %3(%1) : (!fir.box>, !fir.shapeshift<1>) -> !fir.box> +/// ``` +/// converted to +/// ``` +/// %5 = fircg.ext_rebox %3(%13) origin %12 : (!fir.box>, index, index) -> !fir.box> +/// ``` +class ReboxConversion : public mlir::OpRewritePattern { +public: + using OpRewritePattern::OpRewritePattern; + + mlir::LogicalResult + matchAndRewrite(ReboxOp rebox, + mlir::PatternRewriter &rewriter) const override { + auto loc = rebox.getLoc(); + llvm::SmallVector shapeOpers; + llvm::SmallVector shiftOpers; + if (auto shapeVal = rebox.shape()) { + if (auto shapeOp = dyn_cast(shapeVal.getDefiningOp())) + populateShape(shapeOpers, shapeOp); + else if (auto shiftOp = dyn_cast(shapeVal.getDefiningOp())) + populateShapeAndShift(shapeOpers, shiftOpers, shiftOp); + else if (auto shiftOp = dyn_cast(shapeVal.getDefiningOp())) + populateShift(shiftOpers, shiftOp); + else + return mlir::failure(); + } + llvm::SmallVector sliceOpers; + llvm::SmallVector subcompOpers; + if (auto s = rebox.slice()) + if (auto sliceOp = dyn_cast_or_null(s.getDefiningOp())) { + sliceOpers.append(sliceOp.triples().begin(), sliceOp.triples().end()); + subcompOpers.append(sliceOp.fields().begin(), sliceOp.fields().end()); + } + + auto xRebox = rewriter.create( + loc, rebox.getType(), rebox.box(), shapeOpers, shiftOpers, sliceOpers, + subcompOpers); + LLVM_DEBUG(llvm::dbgs() + << "rewriting " << rebox << " to " << xRebox << '\n'); + rewriter.replaceOp(rebox, xRebox.getOperation()->getResults()); + return mlir::success(); + } +}; + +/// Convert all fir.array_coor to the extended form. +/// +/// For example, +/// ``` +/// %4 = fir.array_coor %addr (%1) [%2] %0 : (!fir.ref>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref +/// ``` +/// converted to +/// ``` +/// %40 = fircg.ext_array_coor %addr(%9) origin %8[%4, %5, %6<%39> : (!fir.ref>, index, index, index, index, index, index) -> !fir.ref +/// ``` +class ArrayCoorConversion : public mlir::OpRewritePattern { +public: + using OpRewritePattern::OpRewritePattern; + + mlir::LogicalResult + matchAndRewrite(ArrayCoorOp arrCoor, + mlir::PatternRewriter &rewriter) const override { + auto loc = arrCoor.getLoc(); + llvm::SmallVector shapeOpers; + llvm::SmallVector shiftOpers; + if (auto shapeVal = arrCoor.shape()) { + if (auto shapeOp = dyn_cast(shapeVal.getDefiningOp())) + populateShape(shapeOpers, shapeOp); + else if (auto shiftOp = dyn_cast(shapeVal.getDefiningOp())) + populateShapeAndShift(shapeOpers, shiftOpers, shiftOp); + else if (auto shiftOp = dyn_cast(shapeVal.getDefiningOp())) + populateShift(shiftOpers, shiftOp); + else + return mlir::failure(); + } + llvm::SmallVector sliceOpers; + llvm::SmallVector subcompOpers; + if (auto s = arrCoor.slice()) + if (auto sliceOp = dyn_cast_or_null(s.getDefiningOp())) { + sliceOpers.append(sliceOp.triples().begin(), sliceOp.triples().end()); + subcompOpers.append(sliceOp.fields().begin(), sliceOp.fields().end()); + } + auto xArrCoor = rewriter.create( + loc, arrCoor.getType(), arrCoor.memref(), shapeOpers, shiftOpers, + sliceOpers, subcompOpers, arrCoor.indices(), arrCoor.lenParams()); + LLVM_DEBUG(llvm::dbgs() + << "rewriting " << arrCoor << " to " << xArrCoor << '\n'); + rewriter.replaceOp(arrCoor, xArrCoor.getOperation()->getResults()); + return mlir::success(); + } +}; + +class CodeGenRewrite : public CodeGenRewriteBase { +public: + void runOnOperation() override final { + auto op = getOperation(); + auto &context = getContext(); + mlir::OpBuilder rewriter(&context); + mlir::ConversionTarget target(context); + target.addLegalDialect(); + target.addIllegalOp(); + target.addIllegalOp(); + target.addDynamicallyLegalOp([](EmboxOp embox) { + return !(embox.getShape() || + embox.getType().cast().getEleTy().isa()); + }); + mlir::OwningRewritePatternList patterns(&context); + patterns.insert( + &context); + if (mlir::failed( + mlir::applyPartialConversion(op, target, std::move(patterns)))) { + mlir::emitError(mlir::UnknownLoc::get(&context), + "error in running the pre-codegen conversions"); + signalPassFailure(); + } + } +}; + +} // namespace + +std::unique_ptr fir::createFirCodeGenRewritePass() { + return std::make_unique(); +} diff --git a/flang/lib/Optimizer/Dialect/FIRAttr.cpp b/flang/lib/Optimizer/Dialect/FIRAttr.cpp index 035245dbe935..a2fdf7cd43d0 100644 --- a/flang/lib/Optimizer/Dialect/FIRAttr.cpp +++ b/flang/lib/Optimizer/Dialect/FIRAttr.cpp @@ -243,3 +243,12 @@ void fir::printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr, os << "<(unknown attribute)>"; } } + +//===----------------------------------------------------------------------===// +// FIROpsDialect +//===----------------------------------------------------------------------===// + +void FIROpsDialect::registerAttributes() { + addAttributes(); +} diff --git a/flang/lib/Optimizer/Dialect/FIRDialect.cpp b/flang/lib/Optimizer/Dialect/FIRDialect.cpp index 889b5ef55366..f80aa7d3380e 100644 --- a/flang/lib/Optimizer/Dialect/FIRDialect.cpp +++ b/flang/lib/Optimizer/Dialect/FIRDialect.cpp @@ -19,13 +19,8 @@ using namespace fir; fir::FIROpsDialect::FIROpsDialect(mlir::MLIRContext *ctx) : mlir::Dialect("fir", ctx, mlir::TypeID::get()) { - addTypes(); - addAttributes(); + registerTypes(); + registerAttributes(); addOperations< #define GET_OP_LIST #include "flang/Optimizer/Dialect/FIROps.cpp.inc" diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index f6ec7bb2cd99..38390d801134 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -68,15 +68,6 @@ static bool verifyRecordLenParams(mlir::Type inType, unsigned numLenParams) { return false; } -//===----------------------------------------------------------------------===// -// AddfOp -//===----------------------------------------------------------------------===// - -mlir::OpFoldResult fir::AddfOp::fold(llvm::ArrayRef opnds) { - return mlir::constFoldBinaryOp( - opnds, [](APFloat a, APFloat b) { return a + b; }); -} - //===----------------------------------------------------------------------===// // AllocaOp //===----------------------------------------------------------------------===// @@ -706,7 +697,7 @@ static bool isOne(mlir::Value v) { return checkIsIntegerConstant(v, 1); } template struct UndoComplexPattern : public mlir::RewritePattern { UndoComplexPattern(mlir::MLIRContext *ctx) - : mlir::RewritePattern("fir.insert_value", {}, 2, ctx) {} + : mlir::RewritePattern("fir.insert_value", 2, ctx) {} mlir::LogicalResult matchAndRewrite(mlir::Operation *op, @@ -746,8 +737,8 @@ struct UndoComplexPattern : public mlir::RewritePattern { void fir::InsertValueOp::getCanonicalizationPatterns( mlir::OwningRewritePatternList &results, mlir::MLIRContext *context) { - results.insert, - UndoComplexPattern>(context); + results.insert, + UndoComplexPattern>(context); } //===----------------------------------------------------------------------===// @@ -1227,15 +1218,6 @@ mlir::Value fir::DoLoopOp::blockArgToSourceOp(unsigned blockArgNum) { return {}; } -//===----------------------------------------------------------------------===// -// MulfOp -//===----------------------------------------------------------------------===// - -mlir::OpFoldResult fir::MulfOp::fold(llvm::ArrayRef opnds) { - return mlir::constFoldBinaryOp( - opnds, [](APFloat a, APFloat b) { return a * b; }); -} - //===----------------------------------------------------------------------===// // ReboxOp //===----------------------------------------------------------------------===// @@ -1761,15 +1743,6 @@ bool fir::StringLitOp::isWideValue() { return eleTy.cast().getFKind() != 1; } -//===----------------------------------------------------------------------===// -// SubfOp -//===----------------------------------------------------------------------===// - -mlir::OpFoldResult fir::SubfOp::fold(llvm::ArrayRef opnds) { - return mlir::constFoldBinaryOp( - opnds, [](APFloat a, APFloat b) { return a - b; }); -} - //===----------------------------------------------------------------------===// // IfOp //===----------------------------------------------------------------------===// diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp index eb347a963120..beab54e4f1f8 100644 --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -112,10 +112,16 @@ RecordType verifyDerived(mlir::DialectAsmParser &parser, RecordType derivedTy, mlir::Type fir::parseFirType(FIROpsDialect *dialect, mlir::DialectAsmParser &parser) { - llvm::StringRef typeNameLit; - if (mlir::failed(parser.parseKeyword(&typeNameLit))) + mlir::StringRef typeTag; + if (parser.parseKeyword(&typeTag)) return {}; - return generatedTypeParser(dialect->getContext(), parser, typeNameLit); + mlir::Type genType; + auto parseResult = generatedTypeParser(parser.getBuilder().getContext(), + parser, typeTag, genType); + if (parseResult.hasValue()) + return genType; + parser.emitError(parser.getNameLoc(), "unknown fir type: ") << typeTag; + return {}; } namespace fir { @@ -860,3 +866,15 @@ mlir::LogicalResult fir::VectorType::verify( bool fir::VectorType::isValidElementType(mlir::Type t) { return isa_real(t) || isa_integer(t); } + +//===----------------------------------------------------------------------===// +// FIROpsDialect +//===----------------------------------------------------------------------===// + +void FIROpsDialect::registerTypes() { + addTypes(); +} diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp index 81097b2d08d1..0afa2a94ac40 100644 --- a/flang/lib/Parser/parsing.cpp +++ b/flang/lib/Parser/parsing.cpp @@ -88,7 +88,7 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) { // message about nonstandard usage will have provenance. currentCooked_->Put('\n', range.start()); } - currentCooked_->Marshal(allSources); + currentCooked_->Marshal(allCooked_); if (options.needProvenanceRangeToCharBlockMappings) { currentCooked_->CompileProvenanceRangeToOffsetMappings(allSources); } diff --git a/flang/lib/Parser/provenance.cpp b/flang/lib/Parser/provenance.cpp index 14124a546d1e..2aa1a97ce557 100644 --- a/flang/lib/Parser/provenance.cpp +++ b/flang/lib/Parser/provenance.cpp @@ -442,11 +442,13 @@ std::optional CookedSource::GetCharBlock( std::size_t CookedSource::BufferedBytes() const { return buffer_.bytes(); } -void CookedSource::Marshal(AllSources &allSources) { +void CookedSource::Marshal(AllCookedSources &allCookedSources) { CHECK(provenanceMap_.SizeInBytes() == buffer_.bytes()); - provenanceMap_.Put(allSources.AddCompilerInsertion("(after end of source)")); + provenanceMap_.Put(allCookedSources.allSources().AddCompilerInsertion( + "(after end of source)")); data_ = buffer_.Marshal(); buffer_.clear(); + allCookedSources.Register(*this); } void CookedSource::CompileProvenanceRangeToOffsetMappings( @@ -534,6 +536,16 @@ CookedSource &AllCookedSources::NewCookedSource() { return cooked_.emplace_back(); } +const CookedSource *AllCookedSources::Find(CharBlock x) const { + auto pair{index_.equal_range(x)}; + for (auto iter{pair.first}; iter != pair.second; ++iter) { + if (iter->second.AsCharBlock().Contains(x)) { + return &iter->second; + } + } + return nullptr; +} + std::optional AllCookedSources::GetProvenanceRange( CharBlock cb) const { if (const CookedSource * c{Find(cb)}) { @@ -589,4 +601,26 @@ void AllCookedSources::Dump(llvm::raw_ostream &o) const { } } +bool AllCookedSources::Precedes(CharBlock x, CharBlock y) const { + if (const CookedSource * xSource{Find(x)}) { + if (xSource->AsCharBlock().Contains(y)) { + return x.begin() < y.begin(); + } else if (const CookedSource * ySource{Find(y)}) { + return xSource->number() < ySource->number(); + } else { + return true; // by fiat, all cooked source < anything outside + } + } else if (Find(y)) { + return false; + } else { + // Both names are compiler-created (SaveTempName). + return x < y; + } +} + +void AllCookedSources::Register(CookedSource &cooked) { + index_.emplace(cooked.AsCharBlock(), cooked); + cooked.set_number(static_cast(index_.size())); +} + } // namespace Fortran::parser diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 8adcc32b87af..eaa4c926068c 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -16,6 +16,7 @@ #include "flang/Parser/characters.h" #include "flang/Parser/parse-tree-visitor.h" #include "flang/Parser/parse-tree.h" +#include "flang/Parser/tools.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -48,6 +49,14 @@ class UnparseVisitor { Unparse(x); Post(x); return false; // Walk() does not visit descendents + } else if constexpr (HasTypedExpr::value) { + // Format the expression representation from semantics + if (asFortran_ && x.typedExpr) { + asFortran_->expr(out_, *x.typedExpr); + return false; + } else { + return true; + } } else { Before(x); return true; // there's no Unparse() defined here, Walk() the descendents @@ -816,15 +825,6 @@ class UnparseVisitor { } // R1001 - R1022 - bool Pre(const Expr &x) { - if (asFortran_ && x.typedExpr) { - // Format the expression representation from semantics - asFortran_->expr(out_, *x.typedExpr); - return false; - } else { - return true; - } - } void Unparse(const Expr::Parentheses &x) { Put('('), Walk(x.v), Put(')'); } void Before(const Expr::UnaryPlus &) { Put("+"); } void Before(const Expr::Negate &) { Put("-"); } diff --git a/flang/lib/Semantics/CMakeLists.txt b/flang/lib/Semantics/CMakeLists.txt index 4bab4b16149d..9e7c07b9c55f 100644 --- a/flang/lib/Semantics/CMakeLists.txt +++ b/flang/lib/Semantics/CMakeLists.txt @@ -1,4 +1,3 @@ - add_flang_library(FortranSemantics assignment.cpp attr.cpp diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp index 924b7c86ae9c..bf04091d7648 100644 --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -578,27 +578,27 @@ static void CheckProcedureArg(evaluate::ActualArgument &arg, "Actual argument associated with procedure %s is not a procedure"_err_en_US, dummyName); } - } else if (!(dummyIsPointer && IsNullPointer(*expr))) { + } else if (IsNullPointer(*expr)) { + if (!dummyIsPointer) { + messages.Say( + "Actual argument associated with procedure %s is a null pointer"_err_en_US, + dummyName); + } + } else { messages.Say( - "Actual argument associated with procedure %s is not a procedure"_err_en_US, + "Actual argument associated with procedure %s is typeless"_err_en_US, dummyName); } } - if (interface.HasExplicitInterface()) { - if (dummyIsPointer) { + if (interface.HasExplicitInterface() && dummyIsPointer && + proc.intent != common::Intent::In) { + const Symbol *last{GetLastSymbol(*expr)}; + if (!(last && IsProcedurePointer(*last))) { // 15.5.2.9(5) -- dummy procedure POINTER // Interface compatibility has already been checked above by comparison. - if (proc.intent != common::Intent::In && !IsVariable(*expr)) { - messages.Say( - "Actual argument associated with procedure pointer %s must be a POINTER unless INTENT(IN)"_err_en_US, - dummyName); - } - } else { // 15.5.2.9(4) -- dummy procedure is not POINTER - if (!argProcDesignator) { - messages.Say( - "Actual argument associated with non-POINTER procedure %s must be a procedure (and not a procedure pointer)"_err_en_US, - dummyName); - } + messages.Say( + "Actual argument associated with procedure pointer %s must be a POINTER unless INTENT(IN)"_err_en_US, + dummyName); } } } else { diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp index fccda8ce55a9..7dd0a7a273b9 100644 --- a/flang/lib/Semantics/check-data.cpp +++ b/flang/lib/Semantics/check-data.cpp @@ -66,10 +66,11 @@ class DataVarChecker : public evaluate::AllTraverse { : IsInBlankCommon(symbol) ? "Blank COMMON object" : IsProcedure(symbol) && !IsPointer(symbol) ? "Procedure" // remaining checks don't apply to components - : !isFirstSymbol ? nullptr - : IsHostAssociated(symbol, scope) ? "Host-associated object" - : IsUseAssociated(symbol, scope) ? "USE-associated object" - : nullptr}) { + : !isFirstSymbol ? nullptr + : IsHostAssociated(symbol, scope) ? "Host-associated object" + : IsUseAssociated(symbol, scope) ? "USE-associated object" + : symbol.has() ? "Construct association" + : nullptr}) { context_.Say(source_, "%s '%s' must not be initialized in a DATA statement"_err_en_US, whyNot, symbol.name()); diff --git a/flang/lib/Semantics/check-deallocate.cpp b/flang/lib/Semantics/check-deallocate.cpp index 92e197bbb322..03c2d6ebddda 100644 --- a/flang/lib/Semantics/check-deallocate.cpp +++ b/flang/lib/Semantics/check-deallocate.cpp @@ -34,8 +34,9 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) { } }, [&](const parser::StructureComponent &structureComponent) { - evaluate::ExpressionAnalyzer analyzer{context_}; - if (MaybeExpr checked{analyzer.Analyze(structureComponent)}) { + // Only perform structureComponent checks it was successfully + // analyzed in expression analysis. + if (GetExpr(allocateObject)) { if (!IsAllocatableOrPointer( *structureComponent.component.symbol)) { // C932 context_.Say(structureComponent.component.source, diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index cd35047681e3..69607c466e16 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -110,7 +110,8 @@ class CheckHelper { // that has a symbol. const Symbol *innermostSymbol_{nullptr}; // Cache of calls to Procedure::Characterize(Symbol) - std::map> characterizeCache_; + std::map, SymbolAddressCompare> + characterizeCache_; }; class DistinguishabilityHelper { @@ -1356,6 +1357,14 @@ void CheckHelper::CheckPassArg( : "Procedure binding '%s' with no dummy arguments" " must have NOPASS attribute"_err_en_US, name); + context_.SetError(*interface); + return; + } + Symbol *argSym{dummyArgs[0]}; + if (!argSym) { + messages_.Say(interface->name(), + "Cannot use an alternate return as the passed-object dummy " + "argument"_err_en_US); return; } passName = dummyArgs[0]->name(); @@ -1480,7 +1489,7 @@ void CheckHelper::CheckProcBinding( SayWithDeclaration(*overridden, "A type-bound procedure and its override must have compatible interfaces"_err_en_US); } - } else { + } else if (!context_.HasError(binding.symbol())) { int passIndex{bindingChars->FindPassIndex(binding.passName())}; int overriddenPassIndex{ overriddenChars->FindPassIndex(overriddenBinding->passName())}; @@ -1678,24 +1687,23 @@ void SubprogramMatchHelper::Check( : "Module subprogram '%s' does not have NON_RECURSIVE prefix but " "the corresponding interface body does"_err_en_US); } - MaybeExpr bindName1{details1.bindName()}; - MaybeExpr bindName2{details2.bindName()}; - if (bindName1.has_value() != bindName2.has_value()) { + const std::string *bindName1{details1.bindName()}; + const std::string *bindName2{details2.bindName()}; + if (!bindName1 && !bindName2) { + // OK - neither has a binding label + } else if (!bindName1) { Say(symbol1, symbol2, - bindName1.has_value() - ? "Module subprogram '%s' has a binding label but the corresponding" - " interface body does not"_err_en_US - : "Module subprogram '%s' does not have a binding label but the" - " corresponding interface body does"_err_en_US); - } else if (bindName1) { - std::string string1{bindName1->AsFortran()}; - std::string string2{bindName2->AsFortran()}; - if (string1 != string2) { - Say(symbol1, symbol2, - "Module subprogram '%s' has binding label %s but the corresponding" - " interface body has %s"_err_en_US, - string1, string2); - } + "Module subprogram '%s' does not have a binding label but the" + " corresponding interface body does"_err_en_US); + } else if (!bindName2) { + Say(symbol1, symbol2, + "Module subprogram '%s' has a binding label but the" + " corresponding interface body does not"_err_en_US); + } else if (*bindName1 != *bindName2) { + Say(symbol1, symbol2, + "Module subprogram '%s' has binding label '%s' but the corresponding" + " interface body has '%s'"_err_en_US, + *details1.bindName(), *details2.bindName()); } const Procedure *proc1{checkHelper.Characterize(symbol1)}; const Procedure *proc2{checkHelper.Characterize(symbol2)}; diff --git a/flang/lib/Semantics/check-directive-structure.h b/flang/lib/Semantics/check-directive-structure.h index 468aa07bd174..6ef60230cca5 100644 --- a/flang/lib/Semantics/check-directive-structure.h +++ b/flang/lib/Semantics/check-directive-structure.h @@ -123,6 +123,7 @@ class DirectiveStructureChecker : public virtual BaseChecker { : context_{context}, directiveClausesMap_(directiveClausesMap) {} virtual ~DirectiveStructureChecker() {} + using ClauseMapTy = std::multimap; struct DirectiveContext { DirectiveContext(parser::CharBlock source, D d) : directiveSource{source}, directive{d} {} @@ -136,7 +137,7 @@ class DirectiveStructureChecker : public virtual BaseChecker { common::EnumSet requiredClauses{}; const PC *clause{nullptr}; - std::multimap clauseInfo; + ClauseMapTy clauseInfo; std::list actualClauses; Symbol *loopIV{nullptr}; }; @@ -149,6 +150,11 @@ class DirectiveStructureChecker : public virtual BaseChecker { return dirContext_.back(); } + DirectiveContext &GetContextParent() { + CHECK(dirContext_.size() >= 2); + return dirContext_[dirContext_.size() - 2]; + } + void SetContextClause(const PC &clause) { GetContext().clauseSource = clause.source; GetContext().clause = &clause; @@ -197,6 +203,7 @@ class DirectiveStructureChecker : public virtual BaseChecker { GetContext().actualClauses.push_back(type); } + // Check if the given clause is present in the current context const PC *FindClause(C type) { auto it{GetContext().clauseInfo.find(type)}; if (it != GetContext().clauseInfo.end()) { @@ -205,6 +212,30 @@ class DirectiveStructureChecker : public virtual BaseChecker { return nullptr; } + // Check if the given clause is present in the parent context + const PC *FindClauseParent(C type) { + auto it{GetContextParent().clauseInfo.find(type)}; + if (it != GetContextParent().clauseInfo.end()) { + return it->second; + } + return nullptr; + } + + std::pair + FindClauses(C type) { + auto it{GetContext().clauseInfo.equal_range(type)}; + return it; + } + + DirectiveContext *GetEnclosingDirContext() { + CHECK(!dirContext_.empty()); + auto it{dirContext_.rbegin()}; + if (++it != dirContext_.rend()) { + return &(*it); + } + return nullptr; + } + void PushContext(const parser::CharBlock &source, D dir) { dirContext_.emplace_back(source, dir); } @@ -220,7 +251,7 @@ class DirectiveStructureChecker : public virtual BaseChecker { return nullptr; } - bool CurrentDirectiveIsNested() { return dirContext_.size() > 0; }; + bool CurrentDirectiveIsNested() { return dirContext_.size() > 1; }; void SetClauseSets(D dir) { dirContext_.back().allowedClauses = directiveClausesMap_[dir].allowed; diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp index d2f55eed539c..1532dea61ac5 100644 --- a/flang/lib/Semantics/check-do-forall.cpp +++ b/flang/lib/Semantics/check-do-forall.cpp @@ -548,9 +548,9 @@ class DoContext { // the names up in the scope that encloses the DO construct to avoid getting // the local versions of them. Then follow the host-, use-, and // construct-associations to get the root symbols - SymbolSet GatherLocals( + UnorderedSymbolSet GatherLocals( const std::list &localitySpecs) const { - SymbolSet symbols; + UnorderedSymbolSet symbols; const Scope &parentScope{ context_.FindScope(currentStatementSourcePosition_).parent()}; // Loop through the LocalitySpec::Local locality-specs @@ -568,8 +568,9 @@ class DoContext { return symbols; } - static SymbolSet GatherSymbolsFromExpression(const parser::Expr &expression) { - SymbolSet result; + static UnorderedSymbolSet GatherSymbolsFromExpression( + const parser::Expr &expression) { + UnorderedSymbolSet result; if (const auto *expr{GetExpr(expression)}) { for (const Symbol &symbol : evaluate::CollectSymbols(*expr)) { result.insert(ResolveAssociations(symbol)); @@ -580,8 +581,9 @@ class DoContext { // C1121 - procedures in mask must be pure void CheckMaskIsPure(const parser::ScalarLogicalExpr &mask) const { - SymbolSet references{GatherSymbolsFromExpression(mask.thing.thing.value())}; - for (const Symbol &ref : references) { + UnorderedSymbolSet references{ + GatherSymbolsFromExpression(mask.thing.thing.value())}; + for (const Symbol &ref : OrderBySourcePosition(references)) { if (IsProcedure(ref) && !IsPureProcedure(ref)) { context_.SayWithDecl(ref, parser::Unwrap(mask)->source, "%s mask expression may not reference impure procedure '%s'"_err_en_US, @@ -591,10 +593,10 @@ class DoContext { } } - void CheckNoCollisions(const SymbolSet &refs, const SymbolSet &uses, - parser::MessageFixedText &&errorMessage, + void CheckNoCollisions(const UnorderedSymbolSet &refs, + const UnorderedSymbolSet &uses, parser::MessageFixedText &&errorMessage, const parser::CharBlock &refPosition) const { - for (const Symbol &ref : refs) { + for (const Symbol &ref : OrderBySourcePosition(refs)) { if (uses.find(ref) != uses.end()) { context_.SayWithDecl(ref, refPosition, std::move(errorMessage), LoopKindName(), ref.name()); @@ -603,8 +605,8 @@ class DoContext { } } - void HasNoReferences( - const SymbolSet &indexNames, const parser::ScalarIntExpr &expr) const { + void HasNoReferences(const UnorderedSymbolSet &indexNames, + const parser::ScalarIntExpr &expr) const { CheckNoCollisions(GatherSymbolsFromExpression(expr.thing.thing.value()), indexNames, "%s limit expression may not reference index variable '%s'"_err_en_US, @@ -612,8 +614,8 @@ class DoContext { } // C1129, names in local locality-specs can't be in mask expressions - void CheckMaskDoesNotReferenceLocal( - const parser::ScalarLogicalExpr &mask, const SymbolSet &localVars) const { + void CheckMaskDoesNotReferenceLocal(const parser::ScalarLogicalExpr &mask, + const UnorderedSymbolSet &localVars) const { CheckNoCollisions(GatherSymbolsFromExpression(mask.thing.thing.value()), localVars, "%s mask expression references variable '%s'" @@ -623,8 +625,8 @@ class DoContext { // C1129, names in local locality-specs can't be in limit or step // expressions - void CheckExprDoesNotReferenceLocal( - const parser::ScalarIntExpr &expr, const SymbolSet &localVars) const { + void CheckExprDoesNotReferenceLocal(const parser::ScalarIntExpr &expr, + const UnorderedSymbolSet &localVars) const { CheckNoCollisions(GatherSymbolsFromExpression(expr.thing.thing.value()), localVars, "%s expression references variable '%s'" @@ -663,7 +665,7 @@ class DoContext { CheckMaskIsPure(*mask); } auto &controls{std::get>(header.t)}; - SymbolSet indexNames; + UnorderedSymbolSet indexNames; for (const parser::ConcurrentControl &control : controls) { const auto &indexName{std::get(control.t)}; if (indexName.symbol) { @@ -697,7 +699,7 @@ class DoContext { const auto &localitySpecs{ std::get>(concurrent.t)}; if (!localitySpecs.empty()) { - const SymbolSet &localVars{GatherLocals(localitySpecs)}; + const UnorderedSymbolSet &localVars{GatherLocals(localitySpecs)}; for (const auto &c : GetControls(control)) { CheckExprDoesNotReferenceLocal(std::get<1>(c.t), localVars); CheckExprDoesNotReferenceLocal(std::get<2>(c.t), localVars); @@ -733,7 +735,7 @@ class DoContext { void CheckForallIndexesUsed(const evaluate::Assignment &assignment) { SymbolVector indexVars{context_.GetIndexVars(IndexVarKind::FORALL)}; if (!indexVars.empty()) { - SymbolSet symbols{evaluate::CollectSymbols(assignment.lhs)}; + UnorderedSymbolSet symbols{evaluate::CollectSymbols(assignment.lhs)}; std::visit( common::visitors{ [&](const evaluate::Assignment::BoundsSpec &spec) { diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp index de19ed4d6d40..897b7fd6570a 100644 --- a/flang/lib/Semantics/check-io.cpp +++ b/flang/lib/Semantics/check-io.cpp @@ -550,7 +550,8 @@ void IoChecker::Enter(const parser::OutputItem &item) { flags_.set(Flag::DataList); if (const auto *x{std::get_if(&item.u)}) { if (const auto *expr{GetExpr(*x)}) { - if (IsProcedurePointer(*expr)) { + const Symbol *last{GetLastSymbol(*expr)}; + if (last && IsProcedurePointer(*last)) { context_.Say(parser::FindSourceLocation(*x), "Output item must not be a procedure pointer"_err_en_US); // C1233 } @@ -925,15 +926,19 @@ void IoChecker::CheckForProhibitedSpecifier( template void IoChecker::CheckForDefinableVariable( - const A &var, const std::string &s) const { - const Symbol *sym{ - GetFirstName(*parser::Unwrap(var)).symbol}; - if (auto whyNot{ - WhyNotModifiable(*sym, context_.FindScope(*context_.location()))}) { - auto at{parser::FindSourceLocation(var)}; - context_ - .Say(at, "%s variable '%s' must be definable"_err_en_US, s, sym->name()) - .Attach(at, std::move(*whyNot), sym->name()); + const A &variable, const std::string &s) const { + if (const auto *var{parser::Unwrap(variable)}) { + if (auto expr{AnalyzeExpr(context_, *var)}) { + auto at{var->GetSource()}; + if (auto whyNot{WhyNotModifiable(at, *expr, context_.FindScope(at), + true /*vectorSubscriptIsOk*/)}) { + const Symbol *base{GetFirstSymbol(*expr)}; + context_ + .Say(at, "%s variable '%s' must be definable"_err_en_US, s, + (base ? base->name() : at).ToString()) + .Attach(std::move(*whyNot)); + } + } } } diff --git a/flang/lib/Semantics/check-nullify.cpp b/flang/lib/Semantics/check-nullify.cpp index ff49a661e206..4c6e78e7f7e3 100644 --- a/flang/lib/Semantics/check-nullify.cpp +++ b/flang/lib/Semantics/check-nullify.cpp @@ -40,13 +40,12 @@ void NullifyChecker::Leave(const parser::NullifyStmt &nullifyStmt) { } }, [&](const parser::StructureComponent &structureComponent) { - evaluate::ExpressionAnalyzer analyzer{context_}; - if (MaybeExpr checked{analyzer.Analyze(structureComponent)}) { + if (const auto *checkedExpr{GetExpr(pointerObject)}) { if (!IsPointer(*structureComponent.component.symbol)) { // C951 messages.Say(structureComponent.component.source, "component in NULLIFY statement must have the POINTER attribute"_err_en_US); } else if (pure) { - if (const Symbol * symbol{GetFirstSymbol(checked)}) { + if (const Symbol * symbol{GetFirstSymbol(*checkedExpr)}) { CheckDefinabilityInPureScope( messages, *symbol, scope, *pure); } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index cbb77c567fbc..3ed86132cbea 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -131,7 +131,7 @@ bool OmpStructureChecker::HasInvalidWorksharingNesting( const parser::CharBlock &source, const OmpDirectiveSet &set) { // set contains all the invalid closely nested directives // for the given directive (`source` here) - if (CurrentDirectiveIsNested() && set.test(GetContext().directive)) { + if (CurrentDirectiveIsNested() && set.test(GetContextParent().directive)) { context_.Say(source, "A worksharing region may not be closely nested inside a " "worksharing, explicit task, taskloop, critical, ordered, atomic, or " @@ -158,9 +158,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) { CheckMatching(beginDir, endDir); } - if (beginDir.v != llvm::omp::Directive::OMPD_do) { - PushContextAndClauseSets(beginDir.source, beginDir.v); - } else { + PushContextAndClauseSets(beginDir.source, beginDir.v); + + if (beginDir.v == llvm::omp::Directive::OMPD_do) { // 2.7.1 do-clause -> private-clause | // firstprivate-clause | // lastprivate-clause | @@ -181,7 +181,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) { llvm::omp::Directive::OMPD_ordered, llvm::omp::Directive::OMPD_atomic, llvm::omp::Directive::OMPD_master}); - PushContextAndClauseSets(beginDir.source, llvm::omp::Directive::OMPD_do); } SetLoopInfo(x); @@ -318,15 +317,17 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { CheckMatching(beginDir, endDir); + PushContextAndClauseSets(beginDir.source, beginDir.v); + // TODO: This check needs to be extended while implementing nesting of regions // checks. if (beginDir.v == llvm::omp::Directive::OMPD_single) { HasInvalidWorksharingNesting( beginDir.source, {llvm::omp::Directive::OMPD_do}); } - CheckIfDoOrderedClause(beginDir); + if (CurrentDirectiveIsNested()) + CheckIfDoOrderedClause(beginDir); - PushContextAndClauseSets(beginDir.source, beginDir.v); CheckNoBranching(block, beginDir.v, beginDir.source); switch (beginDir.v) { @@ -342,12 +343,22 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { void OmpStructureChecker::CheckIfDoOrderedClause( const parser::OmpBlockDirective &blkDirective) { if (blkDirective.v == llvm::omp::OMPD_ordered) { - if (!FindClause(llvm::omp::Clause::OMPC_ordered)) { + // Loops + if (llvm::omp::doSet.test(GetContextParent().directive) && + !FindClauseParent(llvm::omp::Clause::OMPC_ordered)) { context_.Say(blkDirective.source, "The ORDERED clause must be present on the loop" " construct if any ORDERED region ever binds" " to a loop region arising from the loop construct."_err_en_US); } + // Other disallowed nestings, these directives do not support + // ordered clause in them, so no need to check + else if (llvm::omp::nestedOrderedErrSet.test( + GetContextParent().directive)) { + context_.Say(blkDirective.source, + "`ORDERED` region may not be closely nested inside of " + "`CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region."_err_en_US); + } } } @@ -390,6 +401,16 @@ void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) { } } +// TODO: Verify the popping of dirContext requirement after nowait +// implementation, as there is an implicit barrier at the end of the worksharing +// constructs unless a nowait clause is specified. Only OMPD_end_sections is +// popped becuase it is pushed while entering the EndSectionsDirective. +void OmpStructureChecker::Leave(const parser::OmpEndSectionsDirective &x) { + if (GetContext().directive == llvm::omp::Directive::OMPD_end_sections) { + dirContext_.pop_back(); + } +} + void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) { const auto &dir{std::get(x.t)}; PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_declare_simd); @@ -512,6 +533,18 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) { } } +// TODO: Verify the popping of dirContext requirement after nowait +// implementation, as there is an implicit barrier at the end of the worksharing +// constructs unless a nowait clause is specified. Only OMPD_end_single and +// end_workshareare popped as they are pushed while entering the +// EndBlockDirective. +void OmpStructureChecker::Leave(const parser::OmpEndBlockDirective &x) { + if ((GetContext().directive == llvm::omp::Directive::OMPD_end_single) || + (GetContext().directive == llvm::omp::Directive::OMPD_end_workshare)) { + dirContext_.pop_back(); + } +} + void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) { std::visit( common::visitors{ @@ -606,7 +639,24 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) { } } } - // TODO: A list-item cannot appear in more than one aligned clause + // A list-item cannot appear in more than one aligned clause + semantics::UnorderedSymbolSet alignedVars; + auto clauseAll = FindClauses(llvm::omp::Clause::OMPC_aligned); + for (auto itr = clauseAll.first; itr != clauseAll.second; ++itr) { + const auto &alignedClause{ + std::get(itr->second->u)}; + const auto &alignedNameList{ + std::get>(alignedClause.v.t)}; + for (auto const &var : alignedNameList) { + if (alignedVars.count(*(var.symbol)) == 1) { + context_.Say(itr->second->source, + "List item '%s' present at multiple ALIGNED clauses"_err_en_US, + var.ToString()); + break; + } + alignedVars.insert(*(var.symbol)); + } + } } // SIMD // 2.7.3 Single Construct Restriction @@ -660,7 +710,6 @@ CHECK_SIMPLE_CLAUSE(Nogroup, OMPC_nogroup) CHECK_SIMPLE_CLAUSE(Notinbranch, OMPC_notinbranch) CHECK_SIMPLE_CLAUSE(Nowait, OMPC_nowait) CHECK_SIMPLE_CLAUSE(ProcBind, OMPC_proc_bind) -CHECK_SIMPLE_CLAUSE(Reduction, OMPC_reduction) CHECK_SIMPLE_CLAUSE(Release, OMPC_release) CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed) CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst) @@ -678,6 +727,8 @@ CHECK_SIMPLE_CLAUSE(UsesAllocators, OMPC_uses_allocators) CHECK_SIMPLE_CLAUSE(Update, OMPC_update) CHECK_SIMPLE_CLAUSE(UseDeviceAddr, OMPC_use_device_addr) CHECK_SIMPLE_CLAUSE(Write, OMPC_write) +CHECK_SIMPLE_CLAUSE(Init, OMPC_init) +CHECK_SIMPLE_CLAUSE(Use, OMPC_use) CHECK_REQ_SCALAR_INT_CLAUSE(Allocator, OMPC_allocator) CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize) @@ -693,6 +744,156 @@ CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Simdlen, OMPC_simdlen) // Restrictions specific to each clause are implemented apart from the // generalized restrictions. +void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) { + CheckAllowed(llvm::omp::Clause::OMPC_reduction); + if (CheckReductionOperators(x)) { + CheckReductionTypeList(x); + } +} +bool OmpStructureChecker::CheckReductionOperators( + const parser::OmpClause::Reduction &x) { + + const auto &definedOp{std::get<0>(x.v.t)}; + bool ok = false; + std::visit( + common::visitors{ + [&](const parser::DefinedOperator &dOpr) { + const auto &intrinsicOp{ + std::get(dOpr.u)}; + ok = CheckIntrinsicOperator(intrinsicOp); + }, + [&](const parser::ProcedureDesignator &procD) { + const parser::Name *name{std::get_if(&procD.u)}; + if (name) { + if (name->source == "max" || name->source == "min" || + name->source == "iand" || name->source == "ior" || + name->source == "ieor") { + ok = true; + } else { + context_.Say(GetContext().clauseSource, + "Invalid reduction identifier in REDUCTION clause."_err_en_US, + ContextDirectiveAsFortran()); + } + } + }, + }, + definedOp.u); + + return ok; +} +bool OmpStructureChecker::CheckIntrinsicOperator( + const parser::DefinedOperator::IntrinsicOperator &op) { + + switch (op) { + case parser::DefinedOperator::IntrinsicOperator::Add: + case parser::DefinedOperator::IntrinsicOperator::Subtract: + case parser::DefinedOperator::IntrinsicOperator::Multiply: + case parser::DefinedOperator::IntrinsicOperator::AND: + case parser::DefinedOperator::IntrinsicOperator::OR: + case parser::DefinedOperator::IntrinsicOperator::EQV: + case parser::DefinedOperator::IntrinsicOperator::NEQV: + return true; + default: + context_.Say(GetContext().clauseSource, + "Invalid reduction operator in REDUCTION clause."_err_en_US, + ContextDirectiveAsFortran()); + } + return false; +} + +void OmpStructureChecker::CheckReductionTypeList( + const parser::OmpClause::Reduction &x) { + const auto &ompObjectList{std::get(x.v.t)}; + CheckIntentInPointerAndDefinable( + ompObjectList, llvm::omp::Clause::OMPC_reduction); + CheckReductionArraySection(ompObjectList); + CheckMultipleAppearanceAcrossContext(ompObjectList); +} + +void OmpStructureChecker::CheckIntentInPointerAndDefinable( + const parser::OmpObjectList &objectList, const llvm::omp::Clause clause) { + for (const auto &ompObject : objectList.v) { + if (const auto *name{parser::Unwrap(ompObject)}) { + if (const auto *symbol{name->symbol}) { + if (IsPointer(symbol->GetUltimate()) && + IsIntentIn(symbol->GetUltimate())) { + context_.Say(GetContext().clauseSource, + "Pointer '%s' with the INTENT(IN) attribute may not appear " + "in a %s clause"_err_en_US, + symbol->name(), + parser::ToUpperCaseLetters(getClauseName(clause).str())); + } + if (auto msg{ + WhyNotModifiable(*symbol, context_.FindScope(name->source))}) { + context_.Say(GetContext().clauseSource, + "Variable '%s' on the %s clause is not definable"_err_en_US, + symbol->name(), + parser::ToUpperCaseLetters(getClauseName(clause).str())); + } + } + } + } +} + +void OmpStructureChecker::CheckReductionArraySection( + const parser::OmpObjectList &ompObjectList) { + for (const auto &ompObject : ompObjectList.v) { + if (const auto *dataRef{parser::Unwrap(ompObject)}) { + if (const auto *arrayElement{ + parser::Unwrap(ompObject)}) { + if (arrayElement) { + CheckArraySection(*arrayElement, GetLastName(*dataRef), + llvm::omp::Clause::OMPC_reduction); + } + } + } + } +} + +void OmpStructureChecker::CheckMultipleAppearanceAcrossContext( + const parser::OmpObjectList &redObjectList) { + // TODO: Verify the assumption here that the immediately enclosing region is + // the parallel region to which the worksharing construct having reduction + // binds to. + if (auto *enclosingContext{GetEnclosingDirContext()}) { + for (auto it : enclosingContext->clauseInfo) { + llvmOmpClause type = it.first; + const auto *clause = it.second; + if (llvm::omp::privateReductionSet.test(type)) { + if (const auto *objList{GetOmpObjectList(*clause)}) { + for (const auto &ompObject : objList->v) { + if (const auto *name{parser::Unwrap(ompObject)}) { + if (const auto *symbol{name->symbol}) { + for (const auto &redOmpObject : redObjectList.v) { + if (const auto *rname{ + parser::Unwrap(redOmpObject)}) { + if (const auto *rsymbol{rname->symbol}) { + if (rsymbol->name() == symbol->name()) { + context_.Say(GetContext().clauseSource, + "%s variable '%s' is %s in outer context must" + " be shared in the parallel regions to which any" + " of the worksharing regions arising from the " + "worksharing" + " construct bind."_err_en_US, + parser::ToUpperCaseLetters( + getClauseName(llvm::omp::Clause::OMPC_reduction) + .str()), + symbol->name(), + parser::ToUpperCaseLetters( + getClauseName(type).str())); + } + } + } + } + } + } + } + } + } + } + } +} + void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) { CheckAllowed(llvm::omp::Clause::OMPC_ordered); // the parameter of ordered clause is optional @@ -721,22 +922,13 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) { void OmpStructureChecker::CheckIsVarPartOfAnotherVar( const parser::OmpObjectList &objList) { for (const auto &ompObject : objList.v) { - std::visit( - common::visitors{ - [&](const parser::Designator &designator) { - if (std::get_if(&designator.u)) { - if ((parser::Unwrap(ompObject)) || - (parser::Unwrap(ompObject))) { - context_.Say(GetContext().clauseSource, - "A variable that is part of another variable (as an " - "array or structure element)" - " cannot appear in a PRIVATE or SHARED clause."_err_en_US); - } - } - }, - [&](const parser::Name &name) {}, - }, - ompObject.u); + if ((parser::Unwrap(ompObject)) || + (parser::Unwrap(ompObject))) { + context_.Say(GetContext().clauseSource, + "A variable that is part of another variable (as an " + "array or structure element)" + " cannot appear in a PRIVATE or SHARED clause."_err_en_US); + } } } void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &x) { @@ -999,7 +1191,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) { if (const auto *arr{ std::get_if>( &dataRef->u)}) { - CheckDependArraySection(*arr, GetLastName(*dataRef)); + CheckArraySection(arr->value(), GetLastName(*dataRef), + llvm::omp::Clause::OMPC_depend); } } } @@ -1017,7 +1210,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) { DirectivesClauseTriple dirClauseTriple; SymbolSourceMap currSymbols; GetSymbolsInObjectList(x.v, currSymbols); - CheckDefinableObjects(currSymbols, llvm::omp::Clause::OMPC_lastprivate); + CheckDefinableObjects(currSymbols, GetClauseKindForParserClass(x)); // Check lastprivate variables in worksharing constructs dirClauseTriple.emplace(llvm::omp::Directive::OMPD_do, @@ -1028,7 +1221,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) { llvm::omp::Directive::OMPD_parallel, llvm::omp::privateReductionSet)); CheckPrivateSymbolsInOuterCxt( - currSymbols, dirClauseTriple, llvm::omp::Clause::OMPC_lastprivate); + currSymbols, dirClauseTriple, GetClauseKindForParserClass(x)); } llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) { @@ -1063,27 +1256,47 @@ void OmpStructureChecker::CheckDependList(const parser::DataRef &d) { d.u); } -void OmpStructureChecker::CheckDependArraySection( - const common::Indirection &arr, - const parser::Name &name) { - for (const auto &subscript : arr.value().subscripts) { - if (const auto *triplet{ - std::get_if(&subscript.u)}) { - if (std::get<2>(triplet->t)) { - context_.Say(GetContext().clauseSource, - "Stride should not be specified for array section in DEPEND " - "clause"_err_en_US); - } - const auto &lower{std::get<0>(triplet->t)}; - const auto &upper{std::get<1>(triplet->t)}; - if (lower && upper) { - const auto lval{GetIntValue(lower)}; - const auto uval{GetIntValue(upper)}; - if (lval && uval && *uval < *lval) { - context_.Say(GetContext().clauseSource, - "'%s' in DEPEND clause is a zero size array section"_err_en_US, - name.ToString()); - break; +// Called from both Reduction and Depend clause. +void OmpStructureChecker::CheckArraySection( + const parser::ArrayElement &arrayElement, const parser::Name &name, + const llvm::omp::Clause clause) { + if (!arrayElement.subscripts.empty()) { + for (const auto &subscript : arrayElement.subscripts) { + if (const auto *triplet{ + std::get_if(&subscript.u)}) { + if (std::get<0>(triplet->t) && std::get<1>(triplet->t)) { + const auto &lower{std::get<0>(triplet->t)}; + const auto &upper{std::get<1>(triplet->t)}; + if (lower && upper) { + const auto lval{GetIntValue(lower)}; + const auto uval{GetIntValue(upper)}; + if (lval && uval && *uval < *lval) { + context_.Say(GetContext().clauseSource, + "'%s' in %s clause" + " is a zero size array section"_err_en_US, + name.ToString(), + parser::ToUpperCaseLetters(getClauseName(clause).str())); + break; + } else if (std::get<2>(triplet->t)) { + const auto &strideExpr{std::get<2>(triplet->t)}; + if (strideExpr) { + if (clause == llvm::omp::Clause::OMPC_depend) { + context_.Say(GetContext().clauseSource, + "Stride should not be specified for array section in " + "DEPEND " + "clause"_err_en_US); + } + const auto stride{GetIntValue(strideExpr)}; + if ((stride && stride != 1)) { + context_.Say(GetContext().clauseSource, + "A list item that appears in a REDUCTION clause" + " should have a contiguous storage array section."_err_en_US, + ContextDirectiveAsFortran()); + break; + } + } + } + } } } } @@ -1152,40 +1365,11 @@ void OmpStructureChecker::CheckPrivateSymbolsInOuterCxt( if (auto *enclosingContext{GetEnclosingContextWithDir(enclosingDir)}) { for (auto it{enclosingContext->clauseInfo.begin()}; it != enclosingContext->clauseInfo.end(); ++it) { - // TODO: Replace the hard-coded clause names by using autogen checks or - // a function which maps parser::OmpClause:: to the corresponding - // llvm::omp::Clause::OMPC_ - std::visit(common::visitors{ - [&](const parser::OmpClause::Private &x) { - if (enclosingClauseSet.test( - llvm::omp::Clause::OMPC_private)) { - GetSymbolsInObjectList(x.v, enclosingSymbols); - } - }, - [&](const parser::OmpClause::Firstprivate &x) { - if (enclosingClauseSet.test( - llvm::omp::Clause::OMPC_firstprivate)) { - GetSymbolsInObjectList(x.v, enclosingSymbols); - } - }, - [&](const parser::OmpClause::Lastprivate &x) { - if (enclosingClauseSet.test( - llvm::omp::Clause::OMPC_lastprivate)) { - GetSymbolsInObjectList(x.v, enclosingSymbols); - } - }, - [&](const parser::OmpClause::Reduction &x) { - if (enclosingClauseSet.test( - llvm::omp::Clause::OMPC_reduction)) { - const auto &ompObjectList{ - std::get(x.v.t)}; - GetSymbolsInObjectList( - ompObjectList, enclosingSymbols); - } - }, - [&](const auto &) {}, - }, - it->second->u); + if (enclosingClauseSet.test(it->first)) { + if (const auto *ompObjectList{GetOmpObjectList(*it->second)}) { + GetSymbolsInObjectList(*ompObjectList, enclosingSymbols); + } + } } // Check if the symbols in current context are private in outer context @@ -1281,4 +1465,37 @@ void OmpStructureChecker::CheckWorkshareBlockStmts( } } +const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList( + const parser::OmpClause &clause) { + + // Clauses with OmpObjectList as its data member + using MemberObjectListClauses = std::tuple; + + // Clauses with OmpObjectList in the tuple + using TupleObjectListClauses = std::tuple; + + // TODO:: Generate the tuples using TableGen. + // Handle other constructs with OmpObjectList such as OpenMPThreadprivate. + return std::visit( + common::visitors{ + [&](const auto &x) -> const parser::OmpObjectList * { + using Ty = std::decay_t; + if constexpr (common::HasMember) { + return &x.v; + } else if constexpr (common::HasMember) { + return &(std::get(x.v.t)); + } else { + return nullptr; + } + }, + }, + clause.u); +} + } // namespace Fortran::semantics diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 9415311a923b..0d11f72b5bc8 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -73,6 +73,9 @@ static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_teams_distribute_simd}; static OmpDirectiveSet taskGeneratingSet{ OmpDirectiveSet{Directive::OMPD_task} | taskloopSet}; +static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, + Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, + Directive::OMPD_taskloop}; static OmpClauseSet privateSet{ Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate}; static OmpClauseSet privateReductionSet{ @@ -109,10 +112,12 @@ class OmpStructureChecker void Enter(const parser::OpenMPBlockConstruct &); void Leave(const parser::OpenMPBlockConstruct &); void Enter(const parser::OmpEndBlockDirective &); + void Leave(const parser::OmpEndBlockDirective &); void Enter(const parser::OpenMPSectionsConstruct &); void Leave(const parser::OpenMPSectionsConstruct &); void Enter(const parser::OmpEndSectionsDirective &); + void Leave(const parser::OmpEndSectionsDirective &); void Enter(const parser::OpenMPDeclareSimdConstruct &); void Leave(const parser::OpenMPDeclareSimdConstruct &); @@ -151,6 +156,13 @@ class OmpStructureChecker #define GEN_FLANG_CLAUSE_CHECK_ENTER #include "llvm/Frontend/OpenMP/OMP.inc" + // Get the OpenMP Clause Kind for the corresponding Parser class + template + llvm::omp::Clause GetClauseKindForParserClass(const A &) { +#define GEN_FLANG_CLAUSE_PARSER_KIND_MAP +#include "llvm/Frontend/OpenMP/OMP.inc" + } + private: bool HasInvalidWorksharingNesting( const parser::CharBlock &, const OmpDirectiveSet &); @@ -184,6 +196,18 @@ class OmpStructureChecker void CheckCycleConstraints(const parser::OpenMPLoopConstruct &x); std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x); void CheckIfDoOrderedClause(const parser::OmpBlockDirective &blkDirectiv); + bool CheckReductionOperators(const parser::OmpClause::Reduction &); + bool CheckIntrinsicOperator( + const parser::DefinedOperator::IntrinsicOperator &); + void CheckReductionTypeList(const parser::OmpClause::Reduction &); + void CheckReductionArraySection(const parser::OmpObjectList &ompObjectList); + void CheckIntentInPointerAndDefinable( + const parser::OmpObjectList &, const llvm::omp::Clause); + void CheckArraySection(const parser::ArrayElement &arrayElement, + const parser::Name &name, const llvm::omp::Clause clause); + void CheckMultipleAppearanceAcrossContext( + const parser::OmpObjectList &ompObjectList); + const parser::OmpObjectList *GetOmpObjectList(const parser::OmpClause &); }; } // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_ diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp index bb2f4d98a17d..4b1538ca785f 100644 --- a/flang/lib/Semantics/compute-offsets.cpp +++ b/flang/lib/Semantics/compute-offsets.cpp @@ -58,9 +58,10 @@ class ComputeOffsetsHelper { std::size_t offset_{0}; std::size_t alignment_{1}; // symbol -> symbol+offset that determines its location, from EQUIVALENCE - std::map dependents_; + std::map dependents_; // base symbol -> SizeAndAlignment for each distinct EQUIVALENCE block - std::map equivalenceBlock_; + std::map + equivalenceBlock_; }; void ComputeOffsetsHelper::Compute(Scope &scope) { diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 2c4ce6af989b..0b36de464129 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -1859,7 +1859,7 @@ static bool CheckCompatibleArgument(bool isElemental, }, [&](const characteristics::DummyProcedure &) { const auto *expr{actual.UnwrapExpr()}; - return expr && IsProcedurePointer(*expr); + return expr && IsProcedurePointerTarget(*expr); }, [&](const characteristics::AlternateReturn &) { return actual.isAlternateReturn(); @@ -2139,18 +2139,48 @@ template static const Symbol *AssumedTypeDummy(const A &x) { if (const auto *dataRef{ std::get_if(&designator->value().u)}) { if (const auto *name{std::get_if(&dataRef->u)}) { - if (const Symbol * symbol{name->symbol}) { - if (const auto *type{symbol->GetType()}) { - if (type->category() == semantics::DeclTypeSpec::TypeStar) { - return symbol; - } - } - } + return AssumedTypeDummy(*name); } } } return nullptr; } +template <> +const Symbol *AssumedTypeDummy(const parser::Name &name) { + if (const Symbol * symbol{name.symbol}) { + if (const auto *type{symbol->GetType()}) { + if (type->category() == semantics::DeclTypeSpec::TypeStar) { + return symbol; + } + } + } + return nullptr; +} +template +static const Symbol *AssumedTypePointerOrAllocatableDummy(const A &object) { + // It is illegal for allocatable of pointer objects to be TYPE(*), but at that + // point it is is not guaranteed that it has been checked the object has + // POINTER or ALLOCATABLE attribute, so do not assume nullptr can be directly + // returned. + return std::visit( + common::visitors{ + [&](const parser::StructureComponent &x) { + return AssumedTypeDummy(x.component); + }, + [&](const parser::Name &x) { return AssumedTypeDummy(x); }, + }, + object.u); +} +template <> +const Symbol *AssumedTypeDummy( + const parser::AllocateObject &x) { + return AssumedTypePointerOrAllocatableDummy(x); +} +template <> +const Symbol *AssumedTypeDummy( + const parser::PointerObject &x) { + return AssumedTypePointerOrAllocatableDummy(x); +} MaybeExpr ExpressionAnalyzer::Analyze(const parser::FunctionReference &funcRef, std::optional *structureConstructor) { @@ -2737,6 +2767,18 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::DataStmtConstant &x) { return ExprOrVariable(x, x.source); } +MaybeExpr ExpressionAnalyzer::Analyze(const parser::AllocateObject &x) { + parser::CharBlock source{parser::FindSourceLocation(x)}; + auto restorer{GetContextualMessages().SetLocation(source)}; + return ExprOrVariable(x, source); +} + +MaybeExpr ExpressionAnalyzer::Analyze(const parser::PointerObject &x) { + parser::CharBlock source{parser::FindSourceLocation(x)}; + auto restorer{GetContextualMessages().SetLocation(source)}; + return ExprOrVariable(x, source); +} + Expr ExpressionAnalyzer::AnalyzeKindSelector( TypeCategory category, const std::optional &selector) { diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index c3b95a7836a8..a60c8dd1cd02 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -54,8 +54,8 @@ static void PutEntity( static void PutInit(llvm::raw_ostream &, const Symbol &, const MaybeExpr &); static void PutInit(llvm::raw_ostream &, const MaybeIntExpr &); static void PutBound(llvm::raw_ostream &, const Bound &); -static llvm::raw_ostream &PutAttrs(llvm::raw_ostream &, Attrs, - const MaybeExpr & = std::nullopt, std::string before = ","s, +llvm::raw_ostream &PutAttrs(llvm::raw_ostream &, Attrs, + const std::string * = nullptr, std::string before = ","s, std::string after = ""s); static llvm::raw_ostream &PutAttr(llvm::raw_ostream &, Attr); @@ -81,8 +81,8 @@ class SubprogramSymbolCollector { const Scope &scope_; bool isInterface_{false}; SymbolVector need_; // symbols that are needed - SymbolSet needSet_; // symbols already in need_ - SymbolSet useSet_; // use-associations that might be needed + UnorderedSymbolSet needSet_; // symbols already in need_ + UnorderedSymbolSet useSet_; // use-associations that might be needed std::set imports_; // imports from host that are needed void DoSymbol(const Symbol &); @@ -346,7 +346,7 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) { if (isInterface) { os << (isAbstract ? "abstract " : "") << "interface\n"; } - PutAttrs(os, prefixAttrs, std::nullopt, ""s, " "s); + PutAttrs(os, prefixAttrs, nullptr, ""s, " "s); os << (details.isFunction() ? "function " : "subroutine "); os << symbol.name() << '('; int n = 0; @@ -498,7 +498,8 @@ void CollectSymbols( for (const auto &pair : scope.commonBlocks()) { sorted.push_back(*pair.second); } - std::sort(sorted.end() - commonSize, sorted.end()); + std::sort( + sorted.end() - commonSize, sorted.end(), SymbolSourcePositionCompare{}); } void PutEntity(llvm::raw_ostream &os, const Symbol &symbol) { @@ -635,26 +636,18 @@ void PutBound(llvm::raw_ostream &os, const Bound &x) { void PutEntity(llvm::raw_ostream &os, const Symbol &symbol, std::function writeType, Attrs attrs) { writeType(); - MaybeExpr bindName; - std::visit(common::visitors{ - [&](const SubprogramDetails &x) { bindName = x.bindName(); }, - [&](const ObjectEntityDetails &x) { bindName = x.bindName(); }, - [&](const ProcEntityDetails &x) { bindName = x.bindName(); }, - [&](const auto &) {}, - }, - symbol.details()); - PutAttrs(os, attrs, bindName); + PutAttrs(os, attrs, symbol.GetBindName()); os << "::" << symbol.name(); } // Put out each attribute to os, surrounded by `before` and `after` and // mapped to lower case. llvm::raw_ostream &PutAttrs(llvm::raw_ostream &os, Attrs attrs, - const MaybeExpr &bindName, std::string before, std::string after) { + const std::string *bindName, std::string before, std::string after) { attrs.set(Attr::PUBLIC, false); // no need to write PUBLIC attrs.set(Attr::EXTERNAL, false); // no need to write EXTERNAL if (bindName) { - bindName->AsFortran(os << before << "bind(c, name=") << ')' << after; + os << before << "bind(c, name=\"" << *bindName << "\")" << after; attrs.set(Attr::BIND_C, false); } for (std::size_t i{0}; i < Attr_enumSize; ++i) { diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 27311db28cc5..d5ba6a12995d 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -105,7 +105,7 @@ template class DirectiveAttributeVisitor { Symbol *DeclarePrivateAccessEntity(Symbol &, Symbol::Flag, Scope &); Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag); - SymbolSet dataSharingAttributeObjects_; // on one directive + UnorderedSymbolSet dataSharingAttributeObjects_; // on one directive SemanticsContext &context_; std::vector dirContext_; // used as a stack }; @@ -365,6 +365,32 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { x.u); return false; } + + bool Pre(const parser::OmpClause::Reduction &x) { + const parser::OmpReductionOperator &opr{ + std::get(x.v.t)}; + if (const auto *procD{parser::Unwrap(opr.u)}) { + if (const auto *name{parser::Unwrap(procD->u)}) { + if (!name->symbol) { + const auto namePair{currScope().try_emplace( + name->source, Attrs{}, ProcEntityDetails{})}; + auto &symbol{*namePair.first->second}; + name->symbol = &symbol; + name->symbol->set(Symbol::Flag::OmpReduction); + AddToContextObjectWithDSA(*name->symbol, Symbol::Flag::OmpReduction); + } + } + if (const auto *procRef{ + parser::Unwrap(procD->u)}) { + ResolveOmp(*procRef->v.thing.component.symbol, + Symbol::Flag::OmpReduction, currScope()); + } + } + const auto &objList{std::get(x.v.t)}; + ResolveOmpObjectList(objList, Symbol::Flag::OmpReduction); + return false; + } + bool Pre(const parser::OmpAlignedClause &x) { const auto &alignedNameList{std::get>(x.t)}; ResolveOmpNameList(alignedNameList, Symbol::Flag::OmpAligned); @@ -426,8 +452,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { Symbol::Flag::OmpCopyIn, Symbol::Flag::OmpCopyPrivate}; std::vector allocateNames_; // on one directive - SymbolSet privateDataSharingAttributeObjects_; // on one directive - SymbolSet stmtFunctionExprSymbols_; + UnorderedSymbolSet privateDataSharingAttributeObjects_; // on one directive + UnorderedSymbolSet stmtFunctionExprSymbols_; std::multimap>> sourceLabels_; diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index df358d880445..304a7b9449d0 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -681,7 +681,9 @@ class InterfaceVisitor : public virtual ScopeHandler { bool isAbstract() const; protected: - GenericDetails &GetGenericDetails(); + Symbol &GetGenericSymbol() { + return DEREF(genericInfo_.top().symbol); + } // Add to generic the symbol for the subprogram with the same name void CheckGenericProcedures(Symbol &); @@ -745,7 +747,7 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor { } funcInfo_; // Create a subprogram symbol in the current scope and push a new scope. - void CheckExtantExternal(const parser::Name &, Symbol::Flag); + void CheckExtantProc(const parser::Name &, Symbol::Flag); Symbol &PushSubprogramScope(const parser::Name &, Symbol::Flag); Symbol *GetSpecificFromGeneric(const parser::Name &); SubprogramDetails &PostSubprogramStmt(const parser::Name &); @@ -1528,19 +1530,26 @@ bool AttrsVisitor::SetPassNameOn(Symbol &symbol) { } bool AttrsVisitor::SetBindNameOn(Symbol &symbol) { - if (!bindName_) { + if (!attrs_ || !attrs_->test(Attr::BIND_C)) { return false; } - std::visit( - common::visitors{ - [&](EntityDetails &x) { x.set_bindName(std::move(bindName_)); }, - [&](ObjectEntityDetails &x) { x.set_bindName(std::move(bindName_)); }, - [&](ProcEntityDetails &x) { x.set_bindName(std::move(bindName_)); }, - [&](SubprogramDetails &x) { x.set_bindName(std::move(bindName_)); }, - [&](CommonBlockDetails &x) { x.set_bindName(std::move(bindName_)); }, - [](auto &) { common::die("unexpected bind name"); }, - }, - symbol.details()); + std::optional label{evaluate::GetScalarConstantValue< + evaluate::Type>(bindName_)}; + // 18.9.2(2): discard leading and trailing blanks, ignore if all blank + if (label) { + auto first{label->find_first_not_of(" ")}; + auto last{label->find_last_not_of(" ")}; + if (first == std::string::npos) { + Say(currStmtSource().value(), "Blank binding label ignored"_en_US); + label.reset(); + } else { + label = label->substr(first, last - first + 1); + } + } + if (!label) { + label = parser::ToLowerCaseLetters(symbol.name().ToString()); + } + symbol.SetBindName(std::move(*label)); return true; } @@ -2674,9 +2683,6 @@ bool InterfaceVisitor::isGeneric() const { bool InterfaceVisitor::isAbstract() const { return !genericInfo_.empty() && GetGenericInfo().isAbstract; } -GenericDetails &InterfaceVisitor::GetGenericDetails() { - return GetGenericInfo().symbol->get(); -} void InterfaceVisitor::AddSpecificProcs( const std::list &names, ProcedureKind kind) { @@ -2690,7 +2696,7 @@ void InterfaceVisitor::AddSpecificProcs( // this generic interface. Resolve those names to symbols. void InterfaceVisitor::ResolveSpecificsInGeneric(Symbol &generic) { auto &details{generic.get()}; - SymbolSet symbolsSeen; + UnorderedSymbolSet symbolsSeen; for (const Symbol &symbol : details.specificProcs()) { symbolsSeen.insert(symbol); } @@ -2878,7 +2884,9 @@ void SubprogramVisitor::Post(const parser::ImplicitPart &) { if (funcInfo_.parsedType) { messageHandler().set_currStmtSource(funcInfo_.source); if (const auto *type{ProcessTypeSpec(*funcInfo_.parsedType, true)}) { - funcInfo_.resultSymbol->SetType(*type); + if (!context().HasError(funcInfo_.resultSymbol)) { + funcInfo_.resultSymbol->SetType(*type); + } } } funcInfo_ = {}; @@ -2938,11 +2946,16 @@ void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) { funcResultName = &name; } // add function result to function scope - EntityDetails funcResultDetails; - funcResultDetails.set_funcResult(true); - funcInfo_.resultSymbol = - &MakeSymbol(*funcResultName, std::move(funcResultDetails)); - details.set_result(*funcInfo_.resultSymbol); + if (details.isFunction()) { + CHECK(context().HasError(currScope().symbol())); + } else { + // add function result to function scope + EntityDetails funcResultDetails; + funcResultDetails.set_funcResult(true); + funcInfo_.resultSymbol = + &MakeSymbol(*funcResultName, std::move(funcResultDetails)); + details.set_result(*funcInfo_.resultSymbol); + } // C1560. if (funcInfo_.resultName && funcInfo_.resultName->source == name.source) { @@ -3084,7 +3097,6 @@ void SubprogramVisitor::Post(const parser::EntryStmt &stmt) { Symbol::Flag subpFlag{ inFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine}; - CheckExtantExternal(name, subpFlag); Scope &outer{inclusiveScope.parent()}; // global or module scope if (Symbol * extant{FindSymbol(outer, name)}) { if (extant->has()) { @@ -3176,7 +3188,7 @@ bool SubprogramVisitor::BeginSubprogram( void SubprogramVisitor::EndSubprogram() { PopScope(); } -void SubprogramVisitor::CheckExtantExternal( +void SubprogramVisitor::CheckExtantProc( const parser::Name &name, Symbol::Flag subpFlag) { if (auto *prev{FindSymbol(name)}) { if (prev->attrs().test(Attr::EXTERNAL) && prev->has()) { @@ -3189,6 +3201,11 @@ void SubprogramVisitor::CheckExtantExternal( *prev, "Previous call of '%s'"_en_US); } EraseSymbol(name); + } else if (const auto *details{prev->detailsIf()}) { + if (!details->isDummy()) { + Say2(name, "Procedure '%s' was previously declared"_err_en_US, *prev, + "Previous declaration of '%s'"_en_US); + } } } } @@ -3197,7 +3214,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope( const parser::Name &name, Symbol::Flag subpFlag) { auto *symbol{GetSpecificFromGeneric(name)}; if (!symbol) { - CheckExtantExternal(name, subpFlag); + CheckExtantProc(name, subpFlag); symbol = &MakeSymbol(name, SubprogramDetails{}); } symbol->set(subpFlag); @@ -3212,7 +3229,13 @@ Symbol &SubprogramVisitor::PushSubprogramScope( MakeExternal(*symbol); } if (isGeneric()) { - GetGenericDetails().AddSpecificProc(*symbol, name.source); + Symbol &genericSymbol{GetGenericSymbol()}; + if (genericSymbol.has()) { + genericSymbol.get().AddSpecificProc( + *symbol, name.source); + } else { + CHECK(context().HasError(genericSymbol)); + } } set_inheritFromParent(false); } @@ -3248,7 +3271,12 @@ Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) { if (!specific) { specific = &currScope().MakeSymbol(name.source, Attrs{}, SubprogramDetails{}); - details->set_specific(Resolve(name, *specific)); + if (details->derivedType()) { + // A specific procedure with the same name as a derived type + SayAlreadyDeclared(name, *details->derivedType()); + } else { + details->set_specific(Resolve(name, *specific)); + } } else if (isGeneric()) { SayAlreadyDeclared(name, *specific); } @@ -3651,7 +3679,7 @@ Symbol &DeclarationVisitor::DeclareUnknownEntity( bool DeclarationVisitor::HasCycle( const Symbol &procSymbol, const ProcInterface &interface) { - SymbolSet procsInCycle; + OrderedSymbolSet procsInCycle; procsInCycle.insert(procSymbol); const ProcInterface *thisInterface{&interface}; bool haveInterface{true}; @@ -6393,7 +6421,7 @@ void ResolveNamesVisitor::FinishSpecificationPart( CheckPossibleBadForwardRef(symbol); } } - currScope().InstantiateDerivedTypes(context()); + currScope().InstantiateDerivedTypes(); for (const auto &decl : decls) { if (const auto *statement{std::get_if< parser::Statement>>( diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index 597f554abcb9..4faec3bd00cd 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -50,7 +50,7 @@ std::string EquivalenceObject::AsFortran() const { } Scope &Scope::MakeScope(Kind kind, Symbol *symbol) { - return children_.emplace_back(*this, kind, symbol); + return children_.emplace_back(*this, kind, symbol, context_); } template @@ -61,7 +61,7 @@ static std::vector> GetSortedSymbols( for (auto &pair : symbols) { result.push_back(*pair.second); } - std::sort(result.begin(), result.end()); + std::sort(result.begin(), result.end(), SymbolSourcePositionCompare{}); return result; } @@ -404,11 +404,11 @@ const Scope &Scope::GetDerivedTypeBase() const { return *child; } -void Scope::InstantiateDerivedTypes(SemanticsContext &context) { +void Scope::InstantiateDerivedTypes() { for (DeclTypeSpec &type : declTypeSpecs_) { if (type.category() == DeclTypeSpec::TypeDerived || type.category() == DeclTypeSpec::ClassDerived) { - type.derivedTypeSpec().Instantiate(*this, context); + type.derivedTypeSpec().Instantiate(*this, context_); } } } diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp index f299897603d9..24bc5e3ea816 100644 --- a/flang/lib/Semantics/semantics.cpp +++ b/flang/lib/Semantics/semantics.cpp @@ -185,8 +185,9 @@ SemanticsContext::SemanticsContext( : defaultKinds_{defaultKinds}, languageFeatures_{languageFeatures}, allCookedSources_{allCookedSources}, intrinsics_{evaluate::IntrinsicProcTable::Configure(defaultKinds_)}, - foldingContext_{ - parser::ContextualMessages{&messages_}, defaultKinds_, intrinsics_} {} + globalScope_{*this}, foldingContext_{ + parser::ContextualMessages{&messages_}, + defaultKinds_, intrinsics_} {} SemanticsContext::~SemanticsContext() {} diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp index edd2c84218c1..7d439df75c2e 100644 --- a/flang/lib/Semantics/symbol.cpp +++ b/flang/lib/Semantics/symbol.cpp @@ -14,6 +14,7 @@ #include "flang/Semantics/tools.h" #include "llvm/Support/raw_ostream.h" #include +#include namespace Fortran::semantics { @@ -84,7 +85,7 @@ void ModuleDetails::set_scope(const Scope *scope) { llvm::raw_ostream &operator<<( llvm::raw_ostream &os, const SubprogramDetails &x) { DumpBool(os, "isInterface", x.isInterface_); - DumpExpr(os, "bindName", x.bindName_); + DumpOptional(os, "bindName", x.bindName()); if (x.result_) { DumpType(os << " result:", x.result()); os << x.result_->name(); @@ -290,6 +291,33 @@ void Symbol::SetType(const DeclTypeSpec &type) { details_); } +template +constexpr bool HasBindName{std::is_convertible_v}; + +const std::string *Symbol::GetBindName() const { + return std::visit( + [&](auto &x) -> const std::string * { + if constexpr (HasBindName) { + return x.bindName(); + } else { + return nullptr; + } + }, + details_); +} + +void Symbol::SetBindName(std::string &&name) { + std::visit( + [&](auto &x) { + if constexpr (HasBindName) { + x.set_bindName(std::move(name)); + } else { + DIE("bind name not allowed on this kind of symbol"); + } + }, + details_); +} + bool Symbol::IsFuncResult() const { return std::visit( common::visitors{[](const EntityDetails &x) { return x.isFuncResult(); }, @@ -331,7 +359,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const EntityDetails &x) { if (x.type()) { os << " type: " << *x.type(); } - DumpExpr(os, "bindName", x.bindName_); + DumpOptional(os, "bindName", x.bindName()); return os; } @@ -361,7 +389,7 @@ llvm::raw_ostream &operator<<( } else { DumpType(os, x.interface_.type()); } - DumpExpr(os, "bindName", x.bindName()); + DumpOptional(os, "bindName", x.bindName()); DumpOptional(os, "passName", x.passName()); if (x.init()) { if (const Symbol * target{*x.init()}) { @@ -448,6 +476,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Details &details) { DumpSymbolVector(os, x.objects()); }, [&](const CommonBlockDetails &x) { + DumpOptional(os, "bindName", x.bindName()); if (x.alignment()) { os << " alignment=" << x.alignment(); } diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp index d93cb7434a8c..256a5cc1d317 100644 --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -374,17 +374,24 @@ static void CheckMissingAnalysis(bool absent, const T &x) { } } -const SomeExpr *GetExprHelper::Get(const parser::Expr &x) { +template static const SomeExpr *GetTypedExpr(const T &x) { CheckMissingAnalysis(!x.typedExpr, x); return common::GetPtrFromOptional(x.typedExpr->v); } +const SomeExpr *GetExprHelper::Get(const parser::Expr &x) { + return GetTypedExpr(x); +} const SomeExpr *GetExprHelper::Get(const parser::Variable &x) { - CheckMissingAnalysis(!x.typedExpr, x); - return common::GetPtrFromOptional(x.typedExpr->v); + return GetTypedExpr(x); } const SomeExpr *GetExprHelper::Get(const parser::DataStmtConstant &x) { - CheckMissingAnalysis(!x.typedExpr, x); - return common::GetPtrFromOptional(x.typedExpr->v); + return GetTypedExpr(x); +} +const SomeExpr *GetExprHelper::Get(const parser::AllocateObject &x) { + return GetTypedExpr(x); +} +const SomeExpr *GetExprHelper::Get(const parser::PointerObject &x) { + return GetTypedExpr(x); } const evaluate::Assignment *GetAssignment(const parser::AssignmentStmt &x) { @@ -434,17 +441,6 @@ const Symbol *FindSubprogram(const Symbol &symbol) { symbol.details()); } -const Symbol *FindFunctionResult(const Symbol &symbol) { - if (const Symbol * subp{FindSubprogram(symbol)}) { - if (const auto &subpDetails{subp->detailsIf()}) { - if (subpDetails->isFunction()) { - return &subpDetails->result(); - } - } - } - return nullptr; -} - const Symbol *FindOverriddenBinding(const Symbol &symbol) { if (symbol.has()) { if (const DeclTypeSpec * parentType{FindParentTypeSpec(symbol.owner())}) { @@ -841,9 +837,7 @@ std::optional WhyNotModifiable( // Modifiability checks for a data-ref std::optional WhyNotModifiable(parser::CharBlock at, const SomeExpr &expr, const Scope &scope, bool vectorSubscriptIsOk) { - if (!evaluate::IsVariable(expr)) { - return parser::Message{at, "Expression is not a variable"_en_US}; - } else if (auto dataRef{evaluate::ExtractDataRef(expr, true)}) { + if (auto dataRef{evaluate::ExtractDataRef(expr, true)}) { if (!vectorSubscriptIsOk && evaluate::HasVectorSubscript(expr)) { return parser::Message{at, "Variable has a vector subscript"_en_US}; } @@ -865,6 +859,9 @@ std::optional WhyNotModifiable(parser::CharBlock at, std::move(*maybeWhyFirst), first.name()}}; } } + } else if (!evaluate::IsVariable(expr)) { + return parser::Message{ + at, "'%s' is not a variable"_en_US, expr.AsFortran()}; } else { // reference to function returning POINTER } diff --git a/flang/runtime/allocatable.cpp b/flang/runtime/allocatable.cpp index 182f27110584..addc1b78d5d1 100644 --- a/flang/runtime/allocatable.cpp +++ b/flang/runtime/allocatable.cpp @@ -40,8 +40,8 @@ void RTNAME(AllocatableAssign)(Descriptor &to, const Descriptor & /*from*/) { } int RTNAME(MoveAlloc)(Descriptor &to, const Descriptor & /*from*/, - bool /*hasStat*/, Descriptor * /*errMsg*/, const char * /*sourceFile*/, - int /*sourceLine*/) { + bool /*hasStat*/, const Descriptor * /*errMsg*/, + const char * /*sourceFile*/, int /*sourceLine*/) { INTERNAL_CHECK(false); // MoveAlloc is not yet implemented return StatOk; } @@ -54,7 +54,7 @@ void RTNAME(AllocatableSetBounds)(Descriptor &descriptor, int zeroBasedDim, } int RTNAME(AllocatableAllocate)(Descriptor &descriptor, bool hasStat, - Descriptor *errMsg, const char *sourceFile, int sourceLine) { + const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!descriptor.IsAllocatable()) { return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat); @@ -66,7 +66,7 @@ int RTNAME(AllocatableAllocate)(Descriptor &descriptor, bool hasStat, } int RTNAME(AllocatableDeallocate)(Descriptor &descriptor, bool hasStat, - Descriptor *errMsg, const char *sourceFile, int sourceLine) { + const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!descriptor.IsAllocatable()) { return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat); diff --git a/flang/runtime/allocatable.h b/flang/runtime/allocatable.h index b5dcb10007bc..85334cbfb0bc 100644 --- a/flang/runtime/allocatable.h +++ b/flang/runtime/allocatable.h @@ -42,7 +42,7 @@ void RTNAME(AllocatableInitDerived)( // this API allows the error to be caught before descriptor is modified.) // Return 0 on success (deallocated state), else the STAT= value. int RTNAME(AllocatableCheckAllocated)(Descriptor &, - Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, + const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // For MOLD= allocation; sets bounds, cobounds, and length type @@ -72,7 +72,7 @@ void RTNAME(AllocatableSetDerivedLength)( // Returns 0 for success, or the STAT= value on failure with hasStat==true. int RTNAME(AllocatableCheckLengthParameter)(Descriptor &, int which /* 0 for CHARACTER length */, SubscriptValue other, - bool hasStat = false, Descriptor *errMsg = nullptr, + bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // Allocates an allocatable. The allocatable descriptor must have been @@ -85,10 +85,10 @@ int RTNAME(AllocatableCheckLengthParameter)(Descriptor &, // derived type, and is always initialized by AllocatableAllocateSource(). // Performs all necessary coarray synchronization and validation actions. int RTNAME(AllocatableAllocate)(Descriptor &, bool hasStat = false, - Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, + const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); int RTNAME(AllocatableAllocateSource)(Descriptor &, const Descriptor &source, - bool hasStat = false, Descriptor *errMsg = nullptr, + bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // Assigns to a whole allocatable, with automatic (re)allocation when the @@ -105,14 +105,14 @@ void RTNAME(AllocatableAssign)(Descriptor &to, const Descriptor &from); // with the other APIs for allocatables.) The destination descriptor // must be initialized. int RTNAME(MoveAlloc)(Descriptor &to, const Descriptor &from, - bool hasStat = false, Descriptor *errMsg = nullptr, + bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // Deallocates an allocatable. Finalizes elements &/or components as needed. // The allocatable is left in an initialized state suitable for reallocation // with the same bounds, cobounds, and length type parameters. int RTNAME(AllocatableDeallocate)(Descriptor &, bool hasStat = false, - Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, + const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); } } // namespace Fortran::runtime diff --git a/flang/runtime/buffer.h b/flang/runtime/buffer.h index c5bd5aedaaee..c601ee7c4be0 100644 --- a/flang/runtime/buffer.h +++ b/flang/runtime/buffer.h @@ -27,7 +27,24 @@ void LeftShiftBufferCircularly(char *, std::size_t bytes, std::size_t shift); // preserve read data that may be reused by means of Tn/TLn edit descriptors // without needing to position the file (which may not always be possible, // e.g. a socket) and a general desire to reduce system call counts. -template class FileFrame { +// +// Possible scenario with a tiny 32-byte buffer after a ReadFrame or +// WriteFrame with a file offset of 103 to access "DEF": +// +// fileOffset_ 100 --+ +-+ frame of interest (103:105) +// file: ............ABCDEFGHIJKLMNOPQRSTUVWXYZ.... +// buffer: [NOPQRSTUVWXYZ......ABCDEFGHIJKLM] (size_ == 32) +// | +-- frame_ == 3 +// +----- start_ == 19, length_ == 26 +// +// The buffer holds length_ == 26 bytes from file offsets 100:125. +// Those 26 bytes "wrap around" the end of the circular buffer, +// so file offsets 100:112 map to buffer offsets 19:31 ("A..M") and +// file offsets 113:125 map to buffer offsets 0:12 ("N..Z") +// The 3-byte frame of file offsets 103:105 is contiguous in the buffer +// at buffer offset (start_ + frame_) == 22 ("DEF"). + +template class FileFrame { public: using FileOffset = std::int64_t; @@ -50,28 +67,17 @@ template class FileFrame { FileOffset at, std::size_t bytes, IoErrorHandler &handler) { Flush(handler); Reallocate(bytes, handler); - if (at < fileOffset_ || at > fileOffset_ + length_) { + std::int64_t newFrame{at - fileOffset_}; + if (newFrame < 0 || newFrame > length_) { Reset(at); + } else { + frame_ = newFrame; } - frame_ = at - fileOffset_; + RUNTIME_CHECK(handler, at == fileOffset_ + frame_); if (static_cast(start_ + frame_ + bytes) > size_) { DiscardLeadingBytes(frame_, handler); - if (static_cast(start_ + bytes) > size_) { - // Frame would wrap around; shift current data (if any) to force - // contiguity. - RUNTIME_CHECK(handler, length_ < size_); - if (start_ + length_ <= size_) { - // [......abcde..] -> [abcde........] - std::memmove(buffer_, buffer_ + start_, length_); - } else { - // [cde........ab] -> [abcde........] - auto n{start_ + length_ - size_}; // 3 for cde - RUNTIME_CHECK(handler, length_ >= n); - std::memmove(buffer_ + n, buffer_ + start_, length_ - n); // cdeab - LeftShiftBufferCircularly(buffer_, length_, n); // abcde - } - start_ = 0; - } + MakeDataContiguous(handler, bytes); + RUNTIME_CHECK(handler, at == fileOffset_ + frame_); } while (FrameLength() < bytes) { auto next{start_ + length_}; @@ -81,7 +87,7 @@ template class FileFrame { auto got{Store().Read( fileOffset_ + length_, buffer_ + next, minBytes, maxBytes, handler)}; length_ += got; - RUNTIME_CHECK(handler, length_ < size_); + RUNTIME_CHECK(handler, length_ <= size_); if (got < minBytes) { break; // error or EOF & program can handle it } @@ -90,32 +96,38 @@ template class FileFrame { } void WriteFrame(FileOffset at, std::size_t bytes, IoErrorHandler &handler) { - if (!dirty_ || at < fileOffset_ || at > fileOffset_ + length_ || - start_ + (at - fileOffset_) + static_cast(bytes) > - size_) { + Reallocate(bytes, handler); + std::int64_t newFrame{at - fileOffset_}; + if (!dirty_ || newFrame < 0 || newFrame > length_) { Flush(handler); Reset(at); - Reallocate(bytes, handler); + } else if (start_ + newFrame + static_cast(bytes) > size_) { + // Flush leading data before "at", retain from "at" onward + Flush(handler, length_ - newFrame); + MakeDataContiguous(handler, bytes); + } else { + frame_ = newFrame; } + RUNTIME_CHECK(handler, at == fileOffset_ + frame_); dirty_ = true; - frame_ = at - fileOffset_; length_ = std::max(length_, frame_ + bytes); } - void Flush(IoErrorHandler &handler) { + void Flush(IoErrorHandler &handler, std::int64_t keep = 0) { if (dirty_) { - while (length_ > 0) { - std::size_t chunk{std::min(length_, size_ - start_)}; + while (length_ > keep) { + std::size_t chunk{ + std::min(length_ - keep, size_ - start_)}; std::size_t put{ Store().Write(fileOffset_, buffer_ + start_, chunk, handler)}; - length_ -= put; - start_ += put; - fileOffset_ += put; + DiscardLeadingBytes(put, handler); if (put < chunk) { break; } } - Reset(fileOffset_); + if (length_ == 0) { + Reset(fileOffset_); + } } } @@ -162,7 +174,24 @@ template class FileFrame { fileOffset_ += n; } - static constexpr std::size_t minBuffer{64 << 10}; + void MakeDataContiguous(IoErrorHandler &handler, std::size_t bytes) { + if (static_cast(start_ + bytes) > size_) { + // Frame would wrap around; shift current data (if any) to force + // contiguity. + RUNTIME_CHECK(handler, length_ < size_); + if (start_ + length_ <= size_) { + // [......abcde..] -> [abcde........] + std::memmove(buffer_, buffer_ + start_, length_); + } else { + // [cde........ab] -> [abcde........] + auto n{start_ + length_ - size_}; // 3 for cde + RUNTIME_CHECK(handler, length_ >= n); + std::memmove(buffer_ + n, buffer_ + start_, length_ - n); // cdeab + LeftShiftBufferCircularly(buffer_, length_, n); // abcde + } + start_ = 0; + } + } char *buffer_{nullptr}; std::int64_t size_{0}; // current allocated buffer size diff --git a/flang/runtime/character.cpp b/flang/runtime/character.cpp index 21a8bb8d99b1..8c9dfec390d6 100644 --- a/flang/runtime/character.cpp +++ b/flang/runtime/character.cpp @@ -235,11 +235,87 @@ static void LenTrimKind(Descriptor &result, const Descriptor &string, int kind, } } +// Utility for dealing with elemental LOGICAL arguments +static bool IsLogicalElementTrue( + const Descriptor &logical, const SubscriptValue at[]) { + // A LOGICAL value is false if and only if all of its bytes are zero. + const char *p{logical.Element(at)}; + for (std::size_t j{logical.ElementBytes()}; j-- > 0; ++p) { + if (*p) { + return true; + } + } + return false; +} + +// INDEX implementation +template +inline std::size_t Index(const CHAR *x, std::size_t xLen, const CHAR *want, + std::size_t wantLen, bool back) { + if (xLen < wantLen) { + return 0; + } + if (xLen == 0) { + return 1; // wantLen is also 0, so trivial match + } + if (back) { + // If wantLen==0, returns xLen + 1 per standard (and all other compilers) + std::size_t at{xLen - wantLen + 1}; + for (; at > 0; --at) { + std::size_t j{1}; + for (; j <= wantLen; ++j) { + if (x[at + j - 2] != want[j - 1]) { + break; + } + } + if (j > wantLen) { + return at; + } + } + return 0; + } + // Non-trivial forward substring search: use a simplified form of + // Boyer-Moore substring searching. + for (std::size_t at{1}; at + wantLen - 1 <= xLen;) { + // Compare x(at:at+wantLen-1) with want(1:wantLen). + // The comparison proceeds from the ends of the substrings forward + // so that we can skip ahead by multiple positions on a miss. + std::size_t j{wantLen}; + CHAR ch; + for (; j > 0; --j) { + ch = x[at + j - 2]; + if (ch != want[j - 1]) { + break; + } + } + if (j == 0) { + return at; // found a match + } + // Suppose we have at==2: + // "THAT FORTRAN THAT I RAN" <- the string (x) in which we search + // "THAT I RAN" <- the string (want) for which we search + // ^------------------ j==7, ch=='T' + // We can shift ahead 3 positions to at==5 to align the 'T's: + // "THAT FORTRAN THAT I RAN" + // "THAT I RAN" + std::size_t shift{1}; + for (; shift < j; ++shift) { + if (want[j - shift - 1] == ch) { + break; + } + } + at += shift; + } + return 0; +} + // SCAN and VERIFY implementation help. These intrinsic functions // do pretty much the same thing, so they're templatized with a // distinguishing flag. -template +enum class CharFunc { Index, Scan, Verify }; + +template inline std::size_t ScanVerify(const CHAR *x, std::size_t xLen, const CHAR *set, std::size_t setLen, bool back) { std::size_t at{back ? xLen : 1}; @@ -254,7 +330,7 @@ inline std::size_t ScanVerify(const CHAR *x, std::size_t xLen, const CHAR *set, break; } } - if (inSet != IS_VERIFY) { + if (inSet != (FUNC == CharFunc::Verify)) { return at; } } @@ -285,35 +361,25 @@ inline std::size_t ScanVerify(const char *x, std::size_t xLen, const char *set, return 0; } -static bool IsLogicalElementTrue( - const Descriptor &logical, const SubscriptValue at[]) { - // A LOGICAL value is false if and only if all of its bytes are zero. - const char *p{logical.Element(at)}; - for (std::size_t j{logical.ElementBytes()}; j-- > 0; ++p) { - if (*p) { - return true; - } - } - return false; -} - -template -static void ScanVerify(Descriptor &result, const Descriptor &string, - const Descriptor &set, const Descriptor *back, +template +static void GeneralCharFunc(Descriptor &result, const Descriptor &string, + const Descriptor &arg, const Descriptor *back, const Terminator &terminator) { int rank{string.rank() ? string.rank() - : set.rank() ? set.rank() : back ? back->rank() : 0}; - SubscriptValue lb[maxRank], ub[maxRank], stringAt[maxRank], setAt[maxRank], + : arg.rank() ? arg.rank() + : back ? back->rank() + : 0}; + SubscriptValue lb[maxRank], ub[maxRank], stringAt[maxRank], argAt[maxRank], backAt[maxRank]; SubscriptValue elements{1}; for (int j{0}; j < rank; ++j) { lb[j] = 1; - ub[j] = string.rank() - ? string.GetDimension(j).Extent() - : set.rank() ? set.GetDimension(j).Extent() - : back ? back->GetDimension(j).Extent() : 1; + ub[j] = string.rank() ? string.GetDimension(j).Extent() + : arg.rank() ? arg.GetDimension(j).Extent() + : back ? back->GetDimension(j).Extent() + : 1; elements *= ub[j]; - stringAt[j] = setAt[j] = backAt[j] = 1; + stringAt[j] = argAt[j] = backAt[j] = 1; } result.Establish(TypeCategory::Integer, sizeof(INT), nullptr, rank, ub, CFI_attribute_allocatable); @@ -321,44 +387,59 @@ static void ScanVerify(Descriptor &result, const Descriptor &string, terminator.Crash("SCAN/VERIFY: could not allocate storage for result"); } std::size_t stringElementChars{string.ElementBytes() >> shift}; - std::size_t setElementChars{set.ElementBytes() >> shift}; + std::size_t argElementChars{arg.ElementBytes() >> shift}; for (SubscriptValue resultAt{0}; elements-- > 0; resultAt += sizeof(INT), - string.IncrementSubscripts(stringAt), set.IncrementSubscripts(setAt), + string.IncrementSubscripts(stringAt), arg.IncrementSubscripts(argAt), back && back->IncrementSubscripts(backAt)) { - *result.OffsetElement(resultAt) = - ScanVerify(string.Element(stringAt), - stringElementChars, set.Element(setAt), setElementChars, - back && IsLogicalElementTrue(*back, backAt)); + if constexpr (FUNC == CharFunc::Index) { + *result.OffsetElement(resultAt) = + Index(string.Element(stringAt), stringElementChars, + arg.Element(argAt), argElementChars, + back && IsLogicalElementTrue(*back, backAt)); + } else if constexpr (FUNC == CharFunc::Scan) { + *result.OffsetElement(resultAt) = + ScanVerify(string.Element(stringAt), + stringElementChars, arg.Element(argAt), argElementChars, + back && IsLogicalElementTrue(*back, backAt)); + } else if constexpr (FUNC == CharFunc::Verify) { + *result.OffsetElement(resultAt) = + ScanVerify(string.Element(stringAt), + stringElementChars, arg.Element(argAt), argElementChars, + back && IsLogicalElementTrue(*back, backAt)); + } else { + static_assert(FUNC == CharFunc::Index || FUNC == CharFunc::Scan || + FUNC == CharFunc::Verify); + } } } -template -static void ScanVerifyKind(Descriptor &result, const Descriptor &string, - const Descriptor &set, const Descriptor *back, int kind, +template +static void GeneralCharFuncKind(Descriptor &result, const Descriptor &string, + const Descriptor &arg, const Descriptor *back, int kind, const Terminator &terminator) { switch (kind) { case 1: - ScanVerify( - result, string, set, back, terminator); + GeneralCharFunc( + result, string, arg, back, terminator); break; case 2: - ScanVerify( - result, string, set, back, terminator); + GeneralCharFunc( + result, string, arg, back, terminator); break; case 4: - ScanVerify( - result, string, set, back, terminator); + GeneralCharFunc( + result, string, arg, back, terminator); break; case 8: - ScanVerify( - result, string, set, back, terminator); + GeneralCharFunc( + result, string, arg, back, terminator); break; case 16: - ScanVerify( - result, string, set, back, terminator); + GeneralCharFunc( + result, string, arg, back, terminator); break; default: - terminator.Crash("SCAN/VERIFY: bad KIND=%d", kind); + terminator.Crash("INDEX/SCAN/VERIFY: bad KIND=%d", kind); } } @@ -750,6 +831,42 @@ void RTNAME(AdjustR)(Descriptor &result, const Descriptor &string, AdjustLR(result, string, sourceFile, sourceLine); } +std::size_t RTNAME(Index1)(const char *x, std::size_t xLen, const char *set, + std::size_t setLen, bool back) { + return Index(x, xLen, set, setLen, back); +} +std::size_t RTNAME(Index2)(const char16_t *x, std::size_t xLen, + const char16_t *set, std::size_t setLen, bool back) { + return Index(x, xLen, set, setLen, back); +} +std::size_t RTNAME(Index4)(const char32_t *x, std::size_t xLen, + const char32_t *set, std::size_t setLen, bool back) { + return Index(x, xLen, set, setLen, back); +} + +void RTNAME(Index)(Descriptor &result, const Descriptor &string, + const Descriptor &substring, const Descriptor *back, int kind, + const char *sourceFile, int sourceLine) { + Terminator terminator{sourceFile, sourceLine}; + switch (string.raw().type) { + case CFI_type_char: + GeneralCharFuncKind( + result, string, substring, back, kind, terminator); + break; + case CFI_type_char16_t: + GeneralCharFuncKind( + result, string, substring, back, kind, terminator); + break; + case CFI_type_char32_t: + GeneralCharFuncKind( + result, string, substring, back, kind, terminator); + break; + default: + terminator.Crash( + "INDEX: bad string type code %d", static_cast(string.raw().type)); + } +} + std::size_t RTNAME(LenTrim1)(const char *x, std::size_t chars) { return LenTrim(x, chars); } @@ -781,15 +898,15 @@ void RTNAME(LenTrim)(Descriptor &result, const Descriptor &string, int kind, std::size_t RTNAME(Scan1)(const char *x, std::size_t xLen, const char *set, std::size_t setLen, bool back) { - return ScanVerify(x, xLen, set, setLen, back); + return ScanVerify(x, xLen, set, setLen, back); } std::size_t RTNAME(Scan2)(const char16_t *x, std::size_t xLen, const char16_t *set, std::size_t setLen, bool back) { - return ScanVerify(x, xLen, set, setLen, back); + return ScanVerify(x, xLen, set, setLen, back); } std::size_t RTNAME(Scan4)(const char32_t *x, std::size_t xLen, const char32_t *set, std::size_t setLen, bool back) { - return ScanVerify(x, xLen, set, setLen, back); + return ScanVerify(x, xLen, set, setLen, back); } void RTNAME(Scan)(Descriptor &result, const Descriptor &string, @@ -798,14 +915,15 @@ void RTNAME(Scan)(Descriptor &result, const Descriptor &string, Terminator terminator{sourceFile, sourceLine}; switch (string.raw().type) { case CFI_type_char: - ScanVerifyKind(result, string, set, back, kind, terminator); + GeneralCharFuncKind( + result, string, set, back, kind, terminator); break; case CFI_type_char16_t: - ScanVerifyKind( + GeneralCharFuncKind( result, string, set, back, kind, terminator); break; case CFI_type_char32_t: - ScanVerifyKind( + GeneralCharFuncKind( result, string, set, back, kind, terminator); break; default: @@ -860,15 +978,15 @@ void RTNAME(Trim)(Descriptor &result, const Descriptor &string, std::size_t RTNAME(Verify1)(const char *x, std::size_t xLen, const char *set, std::size_t setLen, bool back) { - return ScanVerify(x, xLen, set, setLen, back); + return ScanVerify(x, xLen, set, setLen, back); } std::size_t RTNAME(Verify2)(const char16_t *x, std::size_t xLen, const char16_t *set, std::size_t setLen, bool back) { - return ScanVerify(x, xLen, set, setLen, back); + return ScanVerify(x, xLen, set, setLen, back); } std::size_t RTNAME(Verify4)(const char32_t *x, std::size_t xLen, const char32_t *set, std::size_t setLen, bool back) { - return ScanVerify(x, xLen, set, setLen, back); + return ScanVerify(x, xLen, set, setLen, back); } void RTNAME(Verify)(Descriptor &result, const Descriptor &string, @@ -877,13 +995,16 @@ void RTNAME(Verify)(Descriptor &result, const Descriptor &string, Terminator terminator{sourceFile, sourceLine}; switch (string.raw().type) { case CFI_type_char: - ScanVerifyKind(result, string, set, back, kind, terminator); + GeneralCharFuncKind( + result, string, set, back, kind, terminator); break; case CFI_type_char16_t: - ScanVerifyKind(result, string, set, back, kind, terminator); + GeneralCharFuncKind( + result, string, set, back, kind, terminator); break; case CFI_type_char32_t: - ScanVerifyKind(result, string, set, back, kind, terminator); + GeneralCharFuncKind( + result, string, set, back, kind, terminator); break; default: terminator.Crash( diff --git a/flang/runtime/character.h b/flang/runtime/character.h index 8879f3e25c37..6b813bfa34da 100644 --- a/flang/runtime/character.h +++ b/flang/runtime/character.h @@ -108,6 +108,16 @@ void RTNAME(CharacterMinLoc)(Descriptor &result, const Descriptor &x, int dim = 0, const Descriptor *mask = nullptr, int kind = sizeof(int), bool back = false, const char *sourceFile = nullptr, int sourceLine = 0); +std::size_t RTNAME(Index1)(const char *, std::size_t, const char *substring, + std::size_t, bool back = false); +std::size_t RTNAME(Index2)(const char16_t *, std::size_t, + const char16_t *substring, std::size_t, bool back = false); +std::size_t RTNAME(Index4)(const char32_t *, std::size_t, + const char32_t *substring, std::size_t, bool back = false); +void RTNAME(Index)(Descriptor &result, const Descriptor &string, + const Descriptor &substring, const Descriptor *back /*can be null*/, + int kind, const char *sourceFile = nullptr, int sourceLine = 0); + std::size_t RTNAME(Scan1)( const char *, std::size_t, const char *set, std::size_t, bool back = false); std::size_t RTNAME(Scan2)(const char16_t *, std::size_t, const char16_t *set, diff --git a/flang/runtime/descriptor.cpp b/flang/runtime/descriptor.cpp index efcd61b50c4f..b66874b924e6 100644 --- a/flang/runtime/descriptor.cpp +++ b/flang/runtime/descriptor.cpp @@ -31,9 +31,23 @@ void Descriptor::Establish(TypeCode t, std::size_t elementBytes, void *p, int rank, const SubscriptValue *extent, ISO::CFI_attribute_t attribute, bool addendum) { Terminator terminator{__FILE__, __LINE__}; + // Subtle: the standard CFI_establish() function doesn't allow a zero + // elem_len argument in cases where elem_len is not ignored; and when it + // returns an error code (CFI_INVALID_ELEM_LEN in this case), it must not + // modify the descriptor. That design makes sense, maybe, for actual + // C interoperability, but we need to work around it here. A zero + // incoming element length is replaced by 4 so that it will be valid + // for all CHARACTER kinds. + std::size_t workaroundElemLen{elementBytes ? elementBytes : 4}; RUNTIME_CHECK(terminator, - ISO::CFI_establish(&raw_, p, attribute, t.raw(), elementBytes, rank, + ISO::CFI_establish(&raw_, p, attribute, t.raw(), workaroundElemLen, rank, extent) == CFI_SUCCESS); + if (elementBytes == 0) { + raw_.elem_len = 0; + for (int j{0}; j < rank; ++j) { + GetDimension(j).SetByteStride(0); + } + } raw_.f18Addendum = addendum; DescriptorAddendum *a{Addendum()}; RUNTIME_CHECK(terminator, addendum == (a != nullptr)); diff --git a/flang/runtime/stat.cpp b/flang/runtime/stat.cpp index c8120f155836..f02053ad1d86 100644 --- a/flang/runtime/stat.cpp +++ b/flang/runtime/stat.cpp @@ -55,7 +55,7 @@ const char *StatErrorString(int stat) { } } -int ToErrmsg(Descriptor *errmsg, int stat) { +int ToErrmsg(const Descriptor *errmsg, int stat) { if (stat != StatOk && errmsg && errmsg->raw().base_addr && errmsg->type() == TypeCode(TypeCategory::Character, 1) && errmsg->rank() == 0) { @@ -63,7 +63,7 @@ int ToErrmsg(Descriptor *errmsg, int stat) { char *buffer{errmsg->OffsetElement()}; std::size_t bufferLength{errmsg->ElementBytes()}; std::size_t msgLength{std::strlen(msg)}; - if (msgLength <= bufferLength) { + if (msgLength >= bufferLength) { std::memcpy(buffer, msg, bufferLength); } else { std::memcpy(buffer, msg, msgLength); @@ -75,7 +75,7 @@ int ToErrmsg(Descriptor *errmsg, int stat) { } int ReturnError( - Terminator &terminator, int stat, Descriptor *errmsg, bool hasStat) { + Terminator &terminator, int stat, const Descriptor *errmsg, bool hasStat) { if (stat == StatOk || hasStat) { return ToErrmsg(errmsg, stat); } else if (const char *msg{StatErrorString(stat)}) { diff --git a/flang/runtime/stat.h b/flang/runtime/stat.h index ee1a5346e8d8..19098b9b0049 100644 --- a/flang/runtime/stat.h +++ b/flang/runtime/stat.h @@ -47,8 +47,8 @@ enum Stat { }; const char *StatErrorString(int); -int ToErrmsg(Descriptor *errmsg, int stat); // returns stat -int ReturnError( - Terminator &, int stat, Descriptor *errmsg = nullptr, bool hasStat = false); +int ToErrmsg(const Descriptor *errmsg, int stat); // returns stat +int ReturnError(Terminator &, int stat, const Descriptor *errmsg = nullptr, + bool hasStat = false); } // namespace Fortran::runtime #endif // FORTRAN_RUNTIME_STAT_H diff --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt index 7328afc7ba02..905d491708eb 100644 --- a/flang/test/CMakeLists.txt +++ b/flang/test/CMakeLists.txt @@ -5,8 +5,6 @@ llvm_canonicalize_cmake_booleans( FLANG_STANDALONE_BUILD ) -set(FLANG_INTRINSIC_MODULES_DIR ${FLANG_BINARY_DIR}/include/flang) - set(FLANG_TOOLS_DIR ${FLANG_BINARY_DIR}/bin) configure_lit_site_cfg( diff --git a/flang/test/Flang-Driver/Inputs/basic-header-one.h b/flang/test/Driver/Inputs/basic-header-one.h similarity index 100% rename from flang/test/Flang-Driver/Inputs/basic-header-one.h rename to flang/test/Driver/Inputs/basic-header-one.h diff --git a/flang/test/Flang-Driver/Inputs/basic-header-two.h b/flang/test/Driver/Inputs/basic-header-two.h similarity index 100% rename from flang/test/Flang-Driver/Inputs/basic-header-two.h rename to flang/test/Driver/Inputs/basic-header-two.h diff --git a/flang/test/Flang-Driver/Inputs/basictestmoduleone.mod b/flang/test/Driver/Inputs/basictestmoduleone.mod similarity index 100% rename from flang/test/Flang-Driver/Inputs/basictestmoduleone.mod rename to flang/test/Driver/Inputs/basictestmoduleone.mod diff --git a/flang/test/Flang-Driver/Inputs/fixed-form-test.f b/flang/test/Driver/Inputs/fixed-form-test.f similarity index 100% rename from flang/test/Flang-Driver/Inputs/fixed-form-test.f rename to flang/test/Driver/Inputs/fixed-form-test.f diff --git a/flang/test/Flang-Driver/Inputs/fixed-line-length-test.f b/flang/test/Driver/Inputs/fixed-line-length-test.f similarity index 100% rename from flang/test/Flang-Driver/Inputs/fixed-line-length-test.f rename to flang/test/Driver/Inputs/fixed-line-length-test.f diff --git a/flang/test/Flang-Driver/Inputs/free-form-test.f90 b/flang/test/Driver/Inputs/free-form-test.f90 similarity index 100% rename from flang/test/Flang-Driver/Inputs/free-form-test.f90 rename to flang/test/Driver/Inputs/free-form-test.f90 diff --git a/flang/test/Flang-Driver/Inputs/header-dir/basic-header-one.h b/flang/test/Driver/Inputs/header-dir/basic-header-one.h similarity index 100% rename from flang/test/Flang-Driver/Inputs/header-dir/basic-header-one.h rename to flang/test/Driver/Inputs/header-dir/basic-header-one.h diff --git a/flang/test/Flang-Driver/Inputs/header-dir/basic-header-two.h b/flang/test/Driver/Inputs/header-dir/basic-header-two.h similarity index 100% rename from flang/test/Flang-Driver/Inputs/header-dir/basic-header-two.h rename to flang/test/Driver/Inputs/header-dir/basic-header-two.h diff --git a/flang/test/Driver/Inputs/ieee_arithmetic.mod b/flang/test/Driver/Inputs/ieee_arithmetic.mod new file mode 100644 index 000000000000..30fd57801970 --- /dev/null +++ b/flang/test/Driver/Inputs/ieee_arithmetic.mod @@ -0,0 +1,7 @@ +! DUMMY module +! Added for testing purposes. The contents of this file are currently not relevant. +module ieee_arithmetic +type::ieee_round_type +integer(1),private::mode=0_1 +end type +end diff --git a/flang/test/Driver/Inputs/iso_fortran_env.mod b/flang/test/Driver/Inputs/iso_fortran_env.mod new file mode 100644 index 000000000000..689297d52027 --- /dev/null +++ b/flang/test/Driver/Inputs/iso_fortran_env.mod @@ -0,0 +1,7 @@ +! DUMMY module +! Added for testing purposes. The contents of this file are currently not relevant. +module iso_fortran_env +use __fortran_builtins,only:event_type=>__builtin_event_type +use __fortran_builtins,only:lock_type=>__builtin_lock_type +use __fortran_builtins,only:team_type=>__builtin_team_type +end diff --git a/flang/test/Driver/Inputs/module-dir/basictestmoduleone.mod b/flang/test/Driver/Inputs/module-dir/basictestmoduleone.mod new file mode 100644 index 000000000000..ec3dc19ec25e --- /dev/null +++ b/flang/test/Driver/Inputs/module-dir/basictestmoduleone.mod @@ -0,0 +1,3 @@ +!mod$ v1 sum:d380ce014c8955d8 +module basictestmoduleone +end diff --git a/flang/test/Driver/Inputs/module-dir/basictestmoduletwo.mod b/flang/test/Driver/Inputs/module-dir/basictestmoduletwo.mod new file mode 100644 index 000000000000..eb69f0ca211e --- /dev/null +++ b/flang/test/Driver/Inputs/module-dir/basictestmoduletwo.mod @@ -0,0 +1,5 @@ +!mod$ v1 sum:6c4101164527e745 +module basictestmoduletwo +type::t2 +end type +end diff --git a/flang/test/Flang-Driver/code-gen.f90 b/flang/test/Driver/code-gen.f90 similarity index 100% rename from flang/test/Flang-Driver/code-gen.f90 rename to flang/test/Driver/code-gen.f90 diff --git a/flang/test/Flang-Driver/debug-measure-parse-tree.f90 b/flang/test/Driver/debug-measure-parse-tree.f90 similarity index 100% rename from flang/test/Flang-Driver/debug-measure-parse-tree.f90 rename to flang/test/Driver/debug-measure-parse-tree.f90 diff --git a/flang/test/Driver/debug-parsing-log.f90 b/flang/test/Driver/debug-parsing-log.f90 new file mode 100644 index 000000000000..f658fa673e86 --- /dev/null +++ b/flang/test/Driver/debug-parsing-log.f90 @@ -0,0 +1,31 @@ +! RUN: %flang_fc1 -fdebug-dump-parsing-log %s 2>&1 | FileCheck %s + +!----------------- +! EXPECTED OUTPUT +!----------------- +! Below are just few lines extracted from the dump. The actual output is much _much_ bigger. + +! CHECK: {{.*}}/debug-parsing-log.f90:31:1: IMPLICIT statement +! CHECK-NEXT: END PROGRAM +! CHECK-NEXT: ^ +! CHECK-NEXT: fail 3 +! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: error: expected 'IMPLICIT NONE' +! CHECK-NEXT: END PROGRAM +! CHECK-NEXT: ^ +! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: IMPLICIT statement +! CHECK-NEXT: END PROGRAM +! CHECK-NEXT: ^ +! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: implicit part +! CHECK-NEXT: END PROGRAM +! CHECK-NEXT: ^ +! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: specification part +! CHECK-NEXT: END PROGRAM +! CHECK-NEXT: ^ +! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: main program +! CHECK-NEXT: END PROGRAM +! CHECK-NEXT: ^ + +!----------------- +! TEST INPUT +!----------------- +END PROGRAM diff --git a/flang/test/Flang-Driver/debug-provenance.f90 b/flang/test/Driver/debug-provenance.f90 similarity index 100% rename from flang/test/Flang-Driver/debug-provenance.f90 rename to flang/test/Driver/debug-provenance.f90 diff --git a/flang/test/Flang-Driver/driver-error-cc1.c b/flang/test/Driver/driver-error-cc1.c similarity index 100% rename from flang/test/Flang-Driver/driver-error-cc1.c rename to flang/test/Driver/driver-error-cc1.c diff --git a/flang/test/Flang-Driver/driver-error-cc1.cpp b/flang/test/Driver/driver-error-cc1.cpp similarity index 100% rename from flang/test/Flang-Driver/driver-error-cc1.cpp rename to flang/test/Driver/driver-error-cc1.cpp diff --git a/flang/test/Flang-Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 similarity index 92% rename from flang/test/Flang-Driver/driver-help-hidden.f90 rename to flang/test/Driver/driver-help-hidden.f90 index e6235037b1e7..e8b1141d00f4 100644 --- a/flang/test/Flang-Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -35,6 +35,8 @@ ! CHECK-NEXT: -ffree-form Process source files in free form ! CHECK-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! CHECK-NEXT: -finput-charset= Specify the default character set for source files +! CHECK-NEXT: -fintrinsic-modules-path +! CHECK-NEXT: Specify where to find the compiled intrinsic modules ! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations ! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics @@ -45,6 +47,8 @@ ! CHECK-NEXT: -I Add directory to the end of the list of include search paths ! CHECK-NEXT: -module-dir Put MODULE files in ! CHECK-NEXT: -o Write output to +! CHECK-NEXT: -pedantic Warn on language extensions +! CHECK-NEXT: -std= Language standard to compile for ! CHECK-NEXT: -U Undefine macro ! CHECK-NEXT: --version Print version information ! CHECK-NEXT: -Xflang Pass to the flang compiler diff --git a/flang/test/Flang-Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 similarity index 87% rename from flang/test/Flang-Driver/driver-help.f90 rename to flang/test/Driver/driver-help.f90 index d1d507868bb3..855d6f2b58d6 100644 --- a/flang/test/Flang-Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -35,6 +35,8 @@ ! HELP-NEXT: -ffree-form Process source files in free form ! HELP-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! HELP-NEXT: -finput-charset= Specify the default character set for source files +! HELP-NEXT: -fintrinsic-modules-path +! HELP-NEXT: Specify where to find the compiled intrinsic modules ! HELP-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! HELP-NEXT: -flogical-abbreviations Enable logical abbreviations ! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics @@ -45,6 +47,8 @@ ! HELP-NEXT: -I Add directory to the end of the list of include search paths ! HELP-NEXT: -module-dir Put MODULE files in ! HELP-NEXT: -o Write output to +! HELP-NEXT: -pedantic Warn on language extensions +! HELP-NEXT: -std= Language standard to compile for ! HELP-NEXT: -U Undefine macro ! HELP-NEXT: --version Print version information ! HELP-NEXT: -Xflang Pass to the flang compiler @@ -62,10 +66,13 @@ ! HELP-FC1-NEXT: Enable the old style PARAMETER statement ! HELP-FC1-NEXT: -fbackslash Specify that backslash in string introduces an escape character ! HELP-FC1-NEXT: -fdebug-dump-parse-tree Dump the parse tree +! HELP-FC1-NEXT: -fdebug-dump-parsing-log +! HELP-FC1-NEXT: Run instrumented parse and dump the parsing log ! HELP-FC1-NEXT: -fdebug-dump-provenance Dump provenance ! HELP-FC1-NEXT: -fdebug-dump-symbols Dump symbols after the semantic analysis ! HELP-FC1-NEXT: -fdebug-measure-parse-tree ! HELP-FC1-NEXT: Measure the parse tree +! HELP-FC1-NEXT: -fdebug-module-writer Enable debug messages while writing module files ! HELP-FC1-NEXT: -fdebug-pre-fir-tree Dump the pre-FIR tree ! HELP-FC1-NEXT: -fdebug-unparse-with-symbols ! HELP-FC1-NEXT: Unparse and stop. @@ -77,8 +84,11 @@ ! HELP-FC1-NEXT: -ffixed-line-length= ! HELP-FC1-NEXT: Use as character line width in fixed mode ! HELP-FC1-NEXT: -ffree-form Process source files in free form +! HELP-FC1-NEXT: -fget-symbols-sources Dump symbols and their source code locations ! HELP-FC1-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! HELP-FC1-NEXT: -finput-charset= Specify the default character set for source files +! HELP-FC1-NEXT: -fintrinsic-modules-path +! HELP-FC1-NEXT: Specify where to find the compiled intrinsic modules ! HELP-FC1-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! HELP-FC1-NEXT: -flogical-abbreviations Enable logical abbreviations ! HELP-FC1-NEXT: -fopenacc Enable OpenACC @@ -88,6 +98,8 @@ ! HELP-FC1-NEXT: -I Add directory to the end of the list of include search paths ! HELP-FC1-NEXT: -module-dir Put MODULE files in ! HELP-FC1-NEXT: -o Write output to +! HELP-FC1-NEXT: -pedantic Warn on language extensions +! HELP-FC1-NEXT: -std= Language standard to compile for ! HELP-FC1-NEXT: -test-io Run the InputOuputTest action. Use for development and testing only. ! HELP-FC1-NEXT: -U Undefine macro ! HELP-FC1-NEXT: --version Print version information diff --git a/flang/test/Flang-Driver/driver-version.f90 b/flang/test/Driver/driver-version.f90 similarity index 69% rename from flang/test/Flang-Driver/driver-version.f90 rename to flang/test/Driver/driver-version.f90 index 199770bd9e50..a504635ffeb7 100644 --- a/flang/test/Flang-Driver/driver-version.f90 +++ b/flang/test/Driver/driver-version.f90 @@ -3,9 +3,9 @@ ! REQUIRES: new-flang-driver -! CHECK:flang-new version -! CHECK-NEXT:Target: -! CHECK-NEXT:Thread model: -! CHECK-NEXT:InstalledDir: +! CHECK: flang-new version +! CHECK-NEXT: Target: +! CHECK-NEXT: Thread model: +! CHECK-NEXT: InstalledDir: ! ERROR: flang-new: error: unsupported option '--versions'; did you mean '--version'? diff --git a/flang/test/Flang-Driver/escaped-backslash.f90 b/flang/test/Driver/escaped-backslash.f90 similarity index 100% rename from flang/test/Flang-Driver/escaped-backslash.f90 rename to flang/test/Driver/escaped-backslash.f90 diff --git a/flang/test/Flang-Driver/fdefault.f90 b/flang/test/Driver/fdefault.f90 similarity index 100% rename from flang/test/Flang-Driver/fdefault.f90 rename to flang/test/Driver/fdefault.f90 diff --git a/flang/test/Flang-Driver/fixed-free-detection.f90 b/flang/test/Driver/fixed-free-detection.f90 similarity index 100% rename from flang/test/Flang-Driver/fixed-free-detection.f90 rename to flang/test/Driver/fixed-free-detection.f90 diff --git a/flang/test/Flang-Driver/fixed-free-flag.f90 b/flang/test/Driver/fixed-free-flag.f90 similarity index 100% rename from flang/test/Flang-Driver/fixed-free-flag.f90 rename to flang/test/Driver/fixed-free-flag.f90 diff --git a/flang/test/Flang-Driver/fixed-line-length.f90 b/flang/test/Driver/fixed-line-length.f90 similarity index 100% rename from flang/test/Flang-Driver/fixed-line-length.f90 rename to flang/test/Driver/fixed-line-length.f90 diff --git a/flang/test/Flang-Driver/flarge_sizes.f90 b/flang/test/Driver/flarge_sizes.f90 similarity index 100% rename from flang/test/Flang-Driver/flarge_sizes.f90 rename to flang/test/Driver/flarge_sizes.f90 diff --git a/flang/test/Flang-Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90 similarity index 100% rename from flang/test/Flang-Driver/frontend-forwarding.f90 rename to flang/test/Driver/frontend-forwarding.f90 diff --git a/flang/test/Driver/help.f90 b/flang/test/Driver/help-f18.f90 similarity index 100% rename from flang/test/Driver/help.f90 rename to flang/test/Driver/help-f18.f90 diff --git a/flang/test/Flang-Driver/implicit-none.f90 b/flang/test/Driver/implicit-none.f90 similarity index 100% rename from flang/test/Flang-Driver/implicit-none.f90 rename to flang/test/Driver/implicit-none.f90 diff --git a/flang/test/Flang-Driver/include-header.f90 b/flang/test/Driver/include-header.f90 similarity index 100% rename from flang/test/Flang-Driver/include-header.f90 rename to flang/test/Driver/include-header.f90 diff --git a/flang/test/Flang-Driver/input-from-stdin.f90 b/flang/test/Driver/input-from-stdin.f90 similarity index 56% rename from flang/test/Flang-Driver/input-from-stdin.f90 rename to flang/test/Driver/input-from-stdin.f90 index d95218abe278..606cc41520fe 100644 --- a/flang/test/Flang-Driver/input-from-stdin.f90 +++ b/flang/test/Driver/input-from-stdin.f90 @@ -3,27 +3,27 @@ ! REQUIRES: new-flang-driver !-------------------------- -! FLANG DRIVER (flang-new) +! FLANG DRIVER (flang) !-------------------------- ! Input type is implicit -! RUN: cat %s | flang-new -E - | FileCheck %s --check-prefix=PP-NOT-DEFINED -! RUN: cat %s | flang-new -DNEW -E - | FileCheck %s --check-prefix=PP-DEFINED +! RUN: cat %s | %flang -E - | FileCheck %s --check-prefix=PP-NOT-DEFINED +! RUN: cat %s | %flang -DNEW -E - | FileCheck %s --check-prefix=PP-DEFINED ! Input type is explicit -! RUN: cat %s | flang-new -E -x f95-cpp-input - | FileCheck %s --check-prefix=PP-NOT-DEFINED -! RUN: cat %s | flang-new -DNEW -E -x f95-cpp-input - | FileCheck %s --check-prefix=PP-DEFINED +! RUN: cat %s | %flang -E -x f95-cpp-input - | FileCheck %s --check-prefix=PP-NOT-DEFINED +! RUN: cat %s | %flang -DNEW -E -x f95-cpp-input - | FileCheck %s --check-prefix=PP-DEFINED !--------------------------------------- -! FLANG FRONTEND DRIVER (flang-new -fc1) +! FLANG FRONTEND DRIVER (flang -fc1) !--------------------------------------- ! Test `-E`: for the corresponding frontend actions the driver relies on the prescanner API to handle file I/O -! RUN: cat %s | flang-new -fc1 -E | FileCheck %s --check-prefix=PP-NOT-DEFINED -! RUN: cat %s | flang-new -fc1 -DNEW -E | FileCheck %s --check-prefix=PP-DEFINED +! RUN: cat %s | %flang -fc1 -E | FileCheck %s --check-prefix=PP-NOT-DEFINED +! RUN: cat %s | %flang -fc1 -DNEW -E | FileCheck %s --check-prefix=PP-DEFINED ! Test `-test-io`: for the corresponding frontend action (`InputOutputTestAction`) the driver handles the file I/O on its own ! the corresponding action (`PrintPreprocessedAction`) -! RUN: cat %s | flang-new -fc1 -test-io | FileCheck %s --check-prefix=IO --match-full-lines -! RUN: cat %s | flang-new -fc1 -DNEW -test-io | FileCheck %s --check-prefix=IO --match-full-lines +! RUN: cat %s | %flang -fc1 -test-io | FileCheck %s --check-prefix=IO --match-full-lines +! RUN: cat %s | %flang -fc1 -DNEW -test-io | FileCheck %s --check-prefix=IO --match-full-lines !------------------------- ! EXPECTED OUTPUT for `-E` diff --git a/flang/test/Driver/intrinsic_module_path.f90 b/flang/test/Driver/intrinsic_module_path.f90 new file mode 100644 index 000000000000..1105220b8456 --- /dev/null +++ b/flang/test/Driver/intrinsic_module_path.f90 @@ -0,0 +1,28 @@ +! Ensure argument -fintrinsic-modules-path works as expected. +! WITHOUT the option, the default location for the module is checked and no error generated. +! With the option GIVEN, the module with the same name is PREPENDED, and considered over the +! default one, causing a CHECKSUM error. + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT +! RUN: not %flang_fc1 -fsyntax-only -fintrinsic-modules-path %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=GIVEN + +!----------------------------------------- +! EXPECTED OUTPUT WITHOUT +!----------------------------------------- +! WITHOUT-NOT: 'ieee_arithmetic.mod' was not found +! WITHOUT-NOT: 'iso_fortran_env.mod' was not found + +!----------------------------------------- +! EXPECTED OUTPUT WITH +!----------------------------------------- +! GIVEN: error: Cannot read module file for module 'ieee_arithmetic': File has invalid checksum +! GIVEN: error: Cannot read module file for module 'iso_fortran_env': File has invalid checksum + + +program test_intrinsic_module_path + use ieee_arithmetic, only: ieee_round_type + use iso_fortran_env, only: team_type, event_type, lock_type +end program diff --git a/flang/test/Flang-Driver/macro-def-undef.f90 b/flang/test/Driver/macro-def-undef.f90 similarity index 100% rename from flang/test/Flang-Driver/macro-def-undef.f90 rename to flang/test/Driver/macro-def-undef.f90 diff --git a/flang/test/Flang-Driver/macro-multiline.f90 b/flang/test/Driver/macro-multiline.f90 similarity index 100% rename from flang/test/Flang-Driver/macro-multiline.f90 rename to flang/test/Driver/macro-multiline.f90 diff --git a/flang/test/Flang-Driver/missing-input.f90 b/flang/test/Driver/missing-input.f90 similarity index 100% rename from flang/test/Flang-Driver/missing-input.f90 rename to flang/test/Driver/missing-input.f90 diff --git a/flang/test/Driver/no-files.f90 b/flang/test/Driver/no-files.f90 deleted file mode 100644 index 718985dce4ca..000000000000 --- a/flang/test/Driver/no-files.f90 +++ /dev/null @@ -1,10 +0,0 @@ -! RUN: %f18 < %S/Inputs/hello.f90 | FileCheck %s - - -! CHECK: Enter Fortran source -! CHECK: Use EOF character (^D) to end file - -! CHECK: Parse tree comprises {{.*}} objects and occupies {{.*}} total bytes -! CHECK: PROGRAM hello -! CHECK: WRITE (*, *) "hello world" -! CHECK: END PROGRAM hello diff --git a/flang/test/Flang-Driver/parse-error.f95 b/flang/test/Driver/parse-error.f95 similarity index 100% rename from flang/test/Flang-Driver/parse-error.f95 rename to flang/test/Driver/parse-error.f95 diff --git a/flang/test/Flang-Driver/phases.f90 b/flang/test/Driver/phases.f90 similarity index 100% rename from flang/test/Flang-Driver/phases.f90 rename to flang/test/Driver/phases.f90 diff --git a/flang/test/Flang-Driver/predefined-macros-compiler-version.f90 b/flang/test/Driver/predefined-macros-compiler-version.f90 similarity index 100% rename from flang/test/Flang-Driver/predefined-macros-compiler-version.f90 rename to flang/test/Driver/predefined-macros-compiler-version.f90 diff --git a/flang/test/Flang-Driver/scanning-error.f95 b/flang/test/Driver/scanning-error.f95 similarity index 100% rename from flang/test/Flang-Driver/scanning-error.f95 rename to flang/test/Driver/scanning-error.f95 diff --git a/flang/test/Driver/std2018.f90 b/flang/test/Driver/std2018.f90 new file mode 100644 index 000000000000..acc063e5fe4b --- /dev/null +++ b/flang/test/Driver/std2018.f90 @@ -0,0 +1,28 @@ +! Ensure argument -std=f2018 works as expected. + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT +! RUN: %flang_fc1 -fsyntax-only -std=f2018 %s 2>&1 | FileCheck %s --check-prefix=GIVEN +! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s --check-prefix=GIVEN + +!----------------------------------------- +! EXPECTED OUTPUT WITHOUT +!----------------------------------------- +! WITHOUT-NOT: A DO loop should terminate with an END DO or CONTINUE + +!----------------------------------------- +! EXPECTED OUTPUT WITH +!----------------------------------------- +! GIVEN: A DO loop should terminate with an END DO or CONTINUE + +subroutine foo2() + do 01 m=1,2 + select case (m) + case default + print*, "default", m + case (1) + print*, "start" +01 end select +end subroutine diff --git a/flang/test/Driver/std2018_wrong.f90 b/flang/test/Driver/std2018_wrong.f90 new file mode 100644 index 000000000000..867d014c4c11 --- /dev/null +++ b/flang/test/Driver/std2018_wrong.f90 @@ -0,0 +1,12 @@ +! REQUIRES: new-flang-driver +! Ensure argument -std=f2018 works as expected. + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: not %flang_fc1 -std=90 %s 2>&1 | FileCheck %s --check-prefix=WRONG + +!----------------------------------------- +! EXPECTED OUTPUT WITH WRONG +!----------------------------------------- +! WRONG: Only -std=f2018 is allowed currently. diff --git a/flang/test/Flang-Driver/syntax-only.f90 b/flang/test/Driver/syntax-only.f90 similarity index 100% rename from flang/test/Flang-Driver/syntax-only.f90 rename to flang/test/Driver/syntax-only.f90 diff --git a/flang/test/Driver/use-module-error.f90 b/flang/test/Driver/use-module-error.f90 new file mode 100644 index 000000000000..5d19e9b1c385 --- /dev/null +++ b/flang/test/Driver/use-module-error.f90 @@ -0,0 +1,25 @@ +! Ensure that multiple module directories are not allowed + +! REQUIRES: new-flang-driver + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: not %flang -fsyntax-only -J %S/Inputs/module-dir -J %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE +! RUN: not %flang -fsyntax-only -J %S/Inputs/module-dir -module-dir %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE +! RUN: not %flang -fsyntax-only -module-dir %S/Inputs/module-dir -J%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: not %flang_fc1 -fsyntax-only -J %S/Inputs/module-dir -J %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE +! RUN: not %flang_fc1 -fsyntax-only -J %S/Inputs/module-dir -module-dir %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE +! RUN: not %flang_fc1 -fsyntax-only -module-dir %S/Inputs/module-dir -J%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE + +!----------------------------------------- +! EXPECTED OUTPUT FOR MISSING MODULE FILE +!----------------------------------------- +! DOUBLEINCLUDE:error: Only one '-module-dir/-J' option allowed + +program too_many_module_dirs +end diff --git a/flang/test/Driver/use-module.f90 b/flang/test/Driver/use-module.f90 new file mode 100644 index 000000000000..a481cabf8077 --- /dev/null +++ b/flang/test/Driver/use-module.f90 @@ -0,0 +1,60 @@ +! Checks that module search directories specified with `-J/-module-dir` and `-I` are handled correctly + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: %flang -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED --allow-empty +! RUN: %flang -fsyntax-only -I %S/Inputs -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED --allow-empty +! RUN: %flang -fsyntax-only -I %S/Inputs -module-dir %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED --allow-empty + +! RUN: not %flang -fsyntax-only -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=MISSING_MOD2 +! RUN: not %flang -fsyntax-only -J %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=MISSING_MOD2 +! RUN: not %flang -fsyntax-only -module-dir %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=MISSING_MOD2 + +! RUN: not %flang -fsyntax-only -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE +! RUN: not %flang -fsyntax-only -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE +! RUN: not %flang -fsyntax-only -module-dir %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: %flang_fc1 -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED --allow-empty +! RUN: %flang_fc1 -fsyntax-only -I %S/Inputs -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED --allow-empty +! RUN: %flang_fc1 -fsyntax-only -I %S/Inputs -module-dir %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED --allow-empty + +! RUN: not %flang_fc1 -fsyntax-only -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=MISSING_MOD2 +! RUN: not %flang_fc1 -fsyntax-only -J %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=MISSING_MOD2 +! RUN: not %flang_fc1 -fsyntax-only -module-dir %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=MISSING_MOD2 + +! RUN: not %flang_fc1 -fsyntax-only -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE +! RUN: not %flang_fc1 -fsyntax-only -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE +! RUN: not %flang_fc1 -fsyntax-only -module-dir %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE + +!------------------------------------ +! EXPECTED OUTPUT: all modules found +!------------------------------------ +! INCLUDED-NOT: error + +!------------------------------------------------------------------ +! EXPECTED OUTPUT: include dir for `basictestingmoduletwo` is missing +!------------------------------------------------------------------ +! MISSING_MOD2-NOT:error: Cannot read module file for module 'basictestmoduleone'' +! MISSING_MOD2-NOT:error: Derived type 't1' not found +! MISSING_MOD2:error: Cannot read module file for module 'basictestmoduletwo' +! MISSING_MOD2:error: Derived type 't2' not found + +!---------------------------------------------------------------------- +! EXPECTED OUTPUT: `Inputs` is not included, and hence `t1` is undefined +!--------------------------------------------------------------------- +! SINGLEINCLUDE-NOT:error: Cannot read module file for module 'basictestmoduleone' +! SINGLEINCLUDE:error: Derived type 't1' not found +! SINGLEINCLUDE-NOT:error: Cannot read module file for module 'basictestmoduletwo' +! SINGLEINCLUDE-NOT:error: Derived type 't2' not found + + +program test_search_dirs_for_mod_files + USE basictestmoduleone + USE basictestmoduletwo + type(t1) :: x1 ! t1 defined in Inputs/basictestmoduleone.mod + type(t2) :: x2 ! t2 defined in Inputs/module-dir/basictestmoduleone.mod +end diff --git a/flang/test/Driver/version-test.f90 b/flang/test/Driver/version-test.f90 deleted file mode 100644 index 79be3617cf4b..000000000000 --- a/flang/test/Driver/version-test.f90 +++ /dev/null @@ -1,10 +0,0 @@ -! Check that lit configuration works by checking the compiler version - -! VERSION-NOT:{{![[:space:]]}} -! VERSION:{{[[:space:]]}} -! VERSION-SAME:f18 compiler (under development), version {{[1-9][0-9]*.[0-9]*.[0-9]*}} -! VERSION-EMPTY: - -! RUN: %f18 -V 2>&1 | FileCheck -check-prefix=VERSION %s -! RUN: %f18 -v 2>&1 | FileCheck -check-prefix=VERSION %s -! RUN: %f18 --version 2>&1 | FileCheck -check-prefix=VERSION %s diff --git a/flang/test/Driver/write-module.f90 b/flang/test/Driver/write-module.f90 index 47c37d6c46fd..baa480e055b9 100644 --- a/flang/test/Driver/write-module.f90 +++ b/flang/test/Driver/write-module.f90 @@ -1,17 +1,28 @@ -! RUN: rm -rf %t && mkdir -p %t/mod-dir && cd %t && %f18 -fparse-only %s -! RUN: ls %t/testmodule.mod && not ls %t/mod-dir/testmodule.mod +! Checks that the module file: +! * is _saved_ +! * is saved in the _directory specified by the user_ +! We use `-fsyntax-only` as it stops after the semantic checks (the module file is generated when sema checks are run) -! RUN: rm -rf %t && mkdir -p %t/mod-dir && cd %t && %f18 -fparse-only -module mod-dir %s -! RUN: ls %t/mod-dir/testmodule.mod && not ls %t/testmodule.mod +!-------------------------- +! -module-dir +!-------------------------- +! RUN: rm -rf %t && mkdir -p %t/dir-flang +! RUN: cd %t && %flang -fsyntax-only -module-dir %t/dir-flang %s +! RUN: ls %t/dir-flang/testmodule.mod && not ls %t/testmodule.mod -! RUN: rm -rf %t && mkdir -p %t/mod-dir && cd %t && %f18 -fparse-only -module-dir mod-dir %s -! RUN: ls %t/mod-dir/testmodule.mod && not ls %t/testmodule.mod +!--------------------------- +! -J (i.e. with space) +!--------------------------- +! RUN: rm -rf %t && mkdir -p %t/dir-flang +! RUN: cd %t && %flang -fsyntax-only -J %t/dir-flang %s +! RUN: ls %t/dir-flang/testmodule.mod && not ls %t/testmodule.mod -! RUN: rm -rf %t && mkdir -p %t/mod-dir && cd %t && %f18 -fparse-only -J mod-dir %s -! RUN: ls %t/mod-dir/testmodule.mod && not ls %t/testmodule.mod - -! RUN: rm -rf %t && mkdir -p %t/mod-dir && cd %t && %f18 -fparse-only -Jmod-dir %s -! RUN: ls %t/mod-dir/testmodule.mod && not ls %t/testmodule.mod +!------------------------------ +! -J (i.e. without space) +!------------------------------ +! RUN: rm -rf %t && mkdir -p %t/dir-flang +! RUN: cd %t && %flang -fsyntax-only -J%t/dir-flang %s +! RUN: ls %t/dir-flang/testmodule.mod && not ls %t/testmodule.mod module testmodule type::t2 diff --git a/flang/test/Evaluate/folding01.f90 b/flang/test/Evaluate/folding01.f90 index 465b22752cec..b12c6a0e9aed 100644 --- a/flang/test/Evaluate/folding01.f90 +++ b/flang/test/Evaluate/folding01.f90 @@ -30,6 +30,9 @@ module m logical, parameter :: test_neqv3 = .NOT.(.false..NEQV..false.) logical, parameter :: test_neqv4 = .NOT.(.true..NEQV..true.) + logical, parameter :: test_logical1 = logical(logical(.true., 2)) + logical, parameter :: test_logical2 = .NOT.logical(logical(.false., 2)) + ! Check integer intrinsic operator folding ! Check integer relational intrinsic operation folding diff --git a/flang/test/Evaluate/folding05.f90 b/flang/test/Evaluate/folding05.f90 index aeccee04b5cb..f68ce124fa8f 100644 Binary files a/flang/test/Evaluate/folding05.f90 and b/flang/test/Evaluate/folding05.f90 differ diff --git a/flang/test/Fir/cg-ops.fir b/flang/test/Fir/cg-ops.fir new file mode 100644 index 000000000000..a138313eef94 --- /dev/null +++ b/flang/test/Fir/cg-ops.fir @@ -0,0 +1,30 @@ +// RUN: fir-opt --pass-pipeline="func(cg-rewrite),fir.global(cg-rewrite),cse" %s | FileCheck %s + +// CHECK-LABEL: func @codegen( +// CHECK-SAME: %[[arg:.*]]: !fir +func @codegen(%addr : !fir.ref>) { + // CHECK: %[[zero:.*]] = constant 0 : index + %0 = constant 0 : index + %1 = fir.shape_shift %0, %0 : (index, index) -> !fir.shapeshift<1> + %2 = fir.slice %0, %0, %0 : (index, index, index) -> !fir.slice<1> + // CHECK: %[[box:.*]] = fircg.ext_embox %[[arg]](%[[zero]]) origin %[[zero]][%[[zero]], %[[zero]], %[[zero]]] : (!fir.ref>, index, index, index, index, index) -> !fir.box> + %3 = fir.embox %addr (%1) [%2] : (!fir.ref>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box> + // CHECK: fircg.ext_array_coor %[[arg]](%[[zero]]) origin %[[zero]][%[[zero]], %[[zero]], %[[zero]]]<%[[zero]]> : (!fir.ref>, index, index, index, index, index, index) -> !fir.ref + %4 = fir.array_coor %addr (%1) [%2] %0 : (!fir.ref>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref + // CHECK: fircg.ext_rebox %[[box]](%[[zero]]) origin %[[zero]] : (!fir.box>, index, index) -> !fir.box> + %5 = fir.rebox %3(%1) : (!fir.box>, !fir.shapeshift<1>) -> !fir.box> + return +} + +// CHECK-LABEL: fir.global @box_global +fir.global @box_global : !fir.box> { + // CHECK: %[[arr:.*]] = fir.zero_bits !fir.ref + %arr = fir.zero_bits !fir.ref> + // CHECK: %[[zero:.*]] = constant 0 : index + %0 = constant 0 : index + %1 = fir.shape_shift %0, %0 : (index, index) -> !fir.shapeshift<1> + %2 = fir.slice %0, %0, %0 : (index, index, index) -> !fir.slice<1> + // CHECK: fircg.ext_embox %[[arr]](%[[zero]]) origin %[[zero]][%[[zero]], %[[zero]], %[[zero]]] : (!fir.ref>, index, index, index, index, index) -> !fir.box> + %3 = fir.embox %arr (%1) [%2] : (!fir.ref>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box> + fir.has_value %3 : !fir.box> +} diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir index 6b7602513124..775b09eb209f 100644 --- a/flang/test/Fir/fir-ops.fir +++ b/flang/test/Fir/fir-ops.fir @@ -442,44 +442,44 @@ fir.dispatch_table @dispatch_tbl { } // CHECK-LABEL: func @compare_real( -// CHECK-SAME: [[VAL_133:%.*]]: !fir.real<16>, [[VAL_134:%.*]]: !fir.real<16>) { -func @compare_real(%a : !fir.real<16>, %b : !fir.real<16>) { - -// CHECK: [[VAL_135:%.*]] = fir.cmpf "false", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_136:%.*]] = fir.cmpf "oeq", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_137:%.*]] = fir.cmpf "ogt", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_138:%.*]] = fir.cmpf "oge", [[VAL_133]], [[VAL_134]] : !fir.real<16> - %d0 = fir.cmpf "false", %a, %b : !fir.real<16> - %d1 = fir.cmpf "oeq", %a, %b : !fir.real<16> - %d2 = fir.cmpf "ogt", %a, %b : !fir.real<16> - %d3 = fir.cmpf "oge", %a, %b : !fir.real<16> - -// CHECK: [[VAL_139:%.*]] = fir.cmpf "olt", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_140:%.*]] = fir.cmpf "ole", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_141:%.*]] = fir.cmpf "one", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_142:%.*]] = fir.cmpf "ord", [[VAL_133]], [[VAL_134]] : !fir.real<16> - %a0 = fir.cmpf "olt", %a, %b : !fir.real<16> - %a1 = fir.cmpf "ole", %a, %b : !fir.real<16> - %a2 = fir.cmpf "one", %a, %b : !fir.real<16> - %a3 = fir.cmpf "ord", %a, %b : !fir.real<16> - -// CHECK: [[VAL_143:%.*]] = fir.cmpf "ueq", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_144:%.*]] = fir.cmpf "ugt", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_145:%.*]] = fir.cmpf "uge", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_146:%.*]] = fir.cmpf "ult", [[VAL_133]], [[VAL_134]] : !fir.real<16> - %b0 = fir.cmpf "ueq", %a, %b : !fir.real<16> - %b1 = fir.cmpf "ugt", %a, %b : !fir.real<16> - %b2 = fir.cmpf "uge", %a, %b : !fir.real<16> - %b3 = fir.cmpf "ult", %a, %b : !fir.real<16> - -// CHECK: [[VAL_147:%.*]] = fir.cmpf "ule", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_148:%.*]] = fir.cmpf "une", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_149:%.*]] = fir.cmpf "uno", [[VAL_133]], [[VAL_134]] : !fir.real<16> -// CHECK: [[VAL_150:%.*]] = fir.cmpf "true", [[VAL_133]], [[VAL_134]] : !fir.real<16> - %c0 = fir.cmpf "ule", %a, %b : !fir.real<16> - %c1 = fir.cmpf "une", %a, %b : !fir.real<16> - %c2 = fir.cmpf "uno", %a, %b : !fir.real<16> - %c3 = fir.cmpf "true", %a, %b : !fir.real<16> +// CHECK-SAME: [[VAL_133:%.*]]: f128, [[VAL_134:%.*]]: f128) { +func @compare_real(%a : f128, %b : f128) { + +// CHECK: [[VAL_135:%.*]] = fir.cmpf "false", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_136:%.*]] = fir.cmpf "oeq", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_137:%.*]] = fir.cmpf "ogt", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_138:%.*]] = fir.cmpf "oge", [[VAL_133]], [[VAL_134]] : f128 + %d0 = fir.cmpf "false", %a, %b : f128 + %d1 = fir.cmpf "oeq", %a, %b : f128 + %d2 = fir.cmpf "ogt", %a, %b : f128 + %d3 = fir.cmpf "oge", %a, %b : f128 + +// CHECK: [[VAL_139:%.*]] = fir.cmpf "olt", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_140:%.*]] = fir.cmpf "ole", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_141:%.*]] = fir.cmpf "one", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_142:%.*]] = fir.cmpf "ord", [[VAL_133]], [[VAL_134]] : f128 + %a0 = fir.cmpf "olt", %a, %b : f128 + %a1 = fir.cmpf "ole", %a, %b : f128 + %a2 = fir.cmpf "one", %a, %b : f128 + %a3 = fir.cmpf "ord", %a, %b : f128 + +// CHECK: [[VAL_143:%.*]] = fir.cmpf "ueq", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_144:%.*]] = fir.cmpf "ugt", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_145:%.*]] = fir.cmpf "uge", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_146:%.*]] = fir.cmpf "ult", [[VAL_133]], [[VAL_134]] : f128 + %b0 = fir.cmpf "ueq", %a, %b : f128 + %b1 = fir.cmpf "ugt", %a, %b : f128 + %b2 = fir.cmpf "uge", %a, %b : f128 + %b3 = fir.cmpf "ult", %a, %b : f128 + +// CHECK: [[VAL_147:%.*]] = fir.cmpf "ule", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_148:%.*]] = fir.cmpf "une", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_149:%.*]] = fir.cmpf "uno", [[VAL_133]], [[VAL_134]] : f128 +// CHECK: [[VAL_150:%.*]] = fir.cmpf "true", [[VAL_133]], [[VAL_134]] : f128 + %c0 = fir.cmpf "ule", %a, %b : f128 + %c1 = fir.cmpf "une", %a, %b : f128 + %c2 = fir.cmpf "uno", %a, %b : f128 + %c3 = fir.cmpf "true", %a, %b : f128 // CHECK: return // CHECK: } @@ -531,28 +531,28 @@ func @compare_complex(%a : !fir.complex<16>, %b : !fir.complex<16>) { } // CHECK-LABEL: func @arith_real( -// CHECK-SAME: [[VAL_169:%.*]]: !fir.real<16>, [[VAL_170:%.*]]: !fir.real<16>) -> !fir.real<16> { -func @arith_real(%a : !fir.real<16>, %b : !fir.real<16>) -> !fir.real<16> { +// CHECK-SAME: [[VAL_169:%.*]]: f128, [[VAL_170:%.*]]: f128) -> f128 { +func @arith_real(%a : f128, %b : f128) -> f128 { // CHECK: [[VAL_171:%.*]] = constant 1.0 -// CHECK: [[VAL_172:%.*]] = fir.convert [[VAL_171]] : (f32) -> !fir.real<16> -// CHECK: [[VAL_173:%.*]] = fir.negf [[VAL_169]] : !fir.real<16> -// CHECK: [[VAL_174:%.*]] = fir.addf [[VAL_172]], [[VAL_173]] : !fir.real<16> -// CHECK: [[VAL_175:%.*]] = fir.subf [[VAL_174]], [[VAL_170]] : !fir.real<16> -// CHECK: [[VAL_176:%.*]] = fir.mulf [[VAL_173]], [[VAL_175]] : !fir.real<16> -// CHECK: [[VAL_177:%.*]] = fir.divf [[VAL_176]], [[VAL_169]] : !fir.real<16> -// CHECK: [[VAL_178:%.*]] = fir.modf [[VAL_177]], [[VAL_170]] : !fir.real<16> +// CHECK: [[VAL_172:%.*]] = fir.convert [[VAL_171]] : (f32) -> f128 +// CHECK: [[VAL_173:%.*]] = fir.negf [[VAL_169]] : f128 +// CHECK: [[VAL_174:%.*]] = addf [[VAL_172]], [[VAL_173]] : f128 +// CHECK: [[VAL_175:%.*]] = subf [[VAL_174]], [[VAL_170]] : f128 +// CHECK: [[VAL_176:%.*]] = mulf [[VAL_173]], [[VAL_175]] : f128 +// CHECK: [[VAL_177:%.*]] = divf [[VAL_176]], [[VAL_169]] : f128 +// CHECK: [[VAL_178:%.*]] = fir.modf [[VAL_177]], [[VAL_170]] : f128 %c1 = constant 1.0 : f32 - %0 = fir.convert %c1 : (f32) -> !fir.real<16> - %1 = fir.negf %a : !fir.real<16> - %2 = fir.addf %0, %1 : !fir.real<16> - %3 = fir.subf %2, %b : !fir.real<16> - %4 = fir.mulf %1, %3 : !fir.real<16> - %5 = fir.divf %4, %a : !fir.real<16> - %6 = fir.modf %5, %b : !fir.real<16> -// CHECK: return [[VAL_178]] : !fir.real<16> + %0 = fir.convert %c1 : (f32) -> f128 + %1 = fir.negf %a : f128 + %2 = addf %0, %1 : f128 + %3 = subf %2, %b : f128 + %4 = mulf %1, %3 : f128 + %5 = divf %4, %a : f128 + %6 = fir.modf %5, %b : f128 +// CHECK: return [[VAL_178]] : f128 // CHECK: } - return %6 : !fir.real<16> + return %6 : f128 } // CHECK-LABEL: func @arith_complex( diff --git a/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduleone.mod b/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduleone.mod deleted file mode 100644 index 1140a8414fa3..000000000000 --- a/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduleone.mod +++ /dev/null @@ -1,5 +0,0 @@ -!mod$ v1 sum:449b70509dd4bce3 -module basictestmoduleone -type::t2 -end type -end diff --git a/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduletwo.mod b/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduletwo.mod deleted file mode 100644 index ea7d12d112ef..000000000000 --- a/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduletwo.mod +++ /dev/null @@ -1,3 +0,0 @@ -!mod$ v1 sum:563b9a1f049282d2 -module basictestmoduletwo -end diff --git a/flang/test/Flang-Driver/include-module.f90 b/flang/test/Flang-Driver/include-module.f90 deleted file mode 100644 index 26e26a154599..000000000000 --- a/flang/test/Flang-Driver/include-module.f90 +++ /dev/null @@ -1,56 +0,0 @@ -! Ensure argument -I works as expected with module files. - -! REQUIRES: new-flang-driver - -!-------------------------- -! FLANG DRIVER (flang-new) -!-------------------------- -! RUN: not %flang-new -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED -! RUN: not %flang-new -fsyntax-only -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE -! RUN: not %flang-new -fsyntax-only -I %S/Inputs -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED -! RUN: not %flang-new -fsyntax-only -J %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE -! RUN: not %flang-new -fsyntax-only -I %S/Inputs -module-dir %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED -! RUN: not %flang-new -fsyntax-only -module-dir %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE -! RUN: not %flang-new -fsyntax-only -J %S/Inputs/module-dir -J %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE -! RUN: not %flang-new -fsyntax-only -J %S/Inputs/module-dir -module-dir %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE -! RUN: not %flang-new -fsyntax-only -module-dir %S/Inputs/module-dir -J%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE - -!----------------------------------------- -! FRONTEND FLANG DRIVER (flang-new -fc1) -!----------------------------------------- -! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED -! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE -! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED -! RUN: not %flang-new -fc1 -fsyntax-only -J %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE -! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs -module-dir %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED -! RUN: not %flang-new -fc1 -fsyntax-only -module-dir %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE -! RUN: not %flang-new -fc1 -fsyntax-only -J %S/Inputs/module-dir -J %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE -! RUN: not %flang-new -fc1 -fsyntax-only -J %S/Inputs/module-dir -module-dir %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE -! RUN: not %flang-new -fc1 -fsyntax-only -module-dir %S/Inputs/module-dir -J%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE - -!----------------------------------------- -! EXPECTED OUTPUT FOR MISSING MODULE FILE -!----------------------------------------- -! SINGLEINCLUDE:error: Cannot read module file for module 'basictestmoduletwo' -! SINGLEINCLUDE-NOT:error: Cannot read module file for module 'basictestmoduletwo' -! SINGLEINCLUDE-NOT:error: Derived type 't1' not found -! SINGLEINCLUDE:error: Derived type 't2' not found - -!----------------------------------------- -! EXPECTED OUTPUT FOR MISSING MODULE FILE -!----------------------------------------- -! DOUBLEINCLUDE:error: Only one '-module-dir/-J' option allowed - -!--------------------------------------- -! EXPECTED OUTPUT FOR ALL MODULES FOUND -!--------------------------------------- -! INCLUDED-NOT:error: Cannot read module file -! INCLUDED-NOT:error: Derived type 't1' not found -! INCLUDED:error: Derived type 't2' not found - -program test_dash_I_with_mod_files - USE basictestmoduleone - USE basictestmoduletwo - type(t1) :: x1 ! t1 defined in Inputs/basictestmoduleone.mod - type(t2) :: x2 ! t2 defined in Inputs/module-dir/basictestmoduleone.mod -end diff --git a/flang/test/Flang-Driver/write-module.f90 b/flang/test/Flang-Driver/write-module.f90 deleted file mode 100644 index 5065be9a9bc0..000000000000 --- a/flang/test/Flang-Driver/write-module.f90 +++ /dev/null @@ -1,16 +0,0 @@ -! RUN: rm -rf %t && mkdir -p %t/dir-flang -! RUN: cd %t && %flang -fsyntax-only -module-dir %t/dir-flang %s -! RUN: ls %t/dir-flang/testmodule.mod && not ls %t/testmodule.mod - -! RUN: rm -rf %t && mkdir -p %t/dir-flang -! RUN: cd %t && %flang -fsyntax-only -J %t/dir-flang %s -! RUN: ls %t/dir-flang/testmodule.mod && not ls %t/testmodule.mod - -! RUN: rm -rf %t && mkdir -p %t/dir-flang -! RUN: cd %t && %flang -fsyntax-only -J%t/dir-flang %s -! RUN: ls %t/dir-flang/testmodule.mod && not ls %t/testmodule.mod - -module testmodule - type::t2 - end type -end diff --git a/flang/test/Lower/pre-fir-tree01.f90 b/flang/test/Lower/pre-fir-tree01.f90 index 23f9fd1deca4..707dbc1a86b5 100644 --- a/flang/test/Lower/pre-fir-tree01.f90 +++ b/flang/test/Lower/pre-fir-tree01.f90 @@ -20,8 +20,9 @@ subroutine foo() ! CHECK: EndDoStmt end do ! CHECK: <> +! CHECK: EndSubroutineStmt end subroutine -! CHECK: EndSubroutine foo +! CHECK: End Subroutine foo ! CHECK: BlockData block data @@ -29,7 +30,7 @@ subroutine foo() integer, dimension(n) :: a, b, c common /arrays/ a, b, c end -! CHECK: EndBlockData +! CHECK: End BlockData ! CHECK: ModuleLike module test_mod @@ -44,49 +45,57 @@ module subroutine dump() contains ! CHECK: Subroutine foo subroutine foo() + ! CHECK: EndSubroutineStmt contains ! CHECK: Subroutine subfoo subroutine subfoo() - end subroutine - ! CHECK: EndSubroutine subfoo + ! CHECK: EndSubroutineStmt + 9 end subroutine + ! CHECK: End Subroutine subfoo ! CHECK: Function subfoo2 function subfoo2() - end function - ! CHECK: EndFunction subfoo2 + ! CHECK: EndFunctionStmt + 9 end function + ! CHECK: End Function subfoo2 end subroutine - ! CHECK: EndSubroutine foo + ! CHECK: End Subroutine foo ! CHECK: Function foo2 function foo2(i, j) integer i, j, foo2 ! CHECK: AssignmentStmt foo2 = i + j + ! CHECK: EndFunctionStmt contains ! CHECK: Subroutine subfoo subroutine subfoo() + ! CHECK: EndSubroutineStmt end subroutine - ! CHECK: EndSubroutine subfoo + ! CHECK: End Subroutine subfoo end function - ! CHECK: EndFunction foo2 + ! CHECK: End Function foo2 end module -! CHECK: EndModuleLike +! CHECK: End ModuleLike ! CHECK: ModuleLike submodule (test_mod) test_mod_impl contains ! CHECK: Subroutine foo subroutine foo() + ! CHECK: EndSubroutineStmt contains ! CHECK: Subroutine subfoo subroutine subfoo() + ! CHECK: EndSubroutineStmt end subroutine - ! CHECK: EndSubroutine subfoo + ! CHECK: End Subroutine subfoo ! CHECK: Function subfoo2 function subfoo2() + ! CHECK: EndFunctionStmt end function - ! CHECK: EndFunction subfoo2 + ! CHECK: End Function subfoo2 end subroutine - ! CHECK: EndSubroutine foo + ! CHECK: End Subroutine foo ! CHECK: MpSubprogram dump module procedure dump ! CHECK: FormatStmt @@ -105,19 +114,34 @@ function subfoo2() ! CHECK: <> end procedure end submodule -! CHECK: EndModuleLike +! CHECK: End ModuleLike ! CHECK: BlockData block data named_block integer i, j, k common /indexes/ i, j, k end -! CHECK: EndBlockData +! CHECK: End BlockData ! CHECK: Function bar function bar() +! CHECK: EndFunctionStmt end function -! CHECK: EndFunction bar +! CHECK: End Function bar + +! Test top level directives +!DIR$ INTEGER=64 +! CHECK: CompilerDirective: +! CHECK: End CompilerDirective + +! Test nested directive +! CHECK: Subroutine test_directive +subroutine test_directive() + !DIR$ INTEGER=64 + ! CHECK: <> + ! CHECK: <> +end subroutine +! CHECK: EndSubroutine ! CHECK: Program ! check specification parts are not part of the PFT. @@ -127,4 +151,4 @@ function bar() ! CHECK: AllocateStmt allocate(x(foo2(10, 30))) end -! CHECK: EndProgram +! CHECK: End Program diff --git a/flang/test/Lower/pre-fir-tree02.f90 b/flang/test/Lower/pre-fir-tree02.f90 index 9e16c4ee7446..6f64b60b23ef 100644 --- a/flang/test/Lower/pre-fir-tree02.f90 +++ b/flang/test/Lower/pre-fir-tree02.f90 @@ -146,12 +146,15 @@ subroutine incr(i) ! CHECK: ModuleLike module test - type :: a_type - integer :: x - end type - type, extends(a_type) :: b_type - integer :: y - end type + !! When derived type processing is implemented, remove all instances of: + !! - !![disable] + !! - COM: + !![disable]type :: a_type + !![disable] integer :: x + !![disable]end type + !![disable]type, extends(a_type) :: b_type + !![disable] integer :: y + !![disable]end type contains ! CHECK: Function foo function foo(x) @@ -191,12 +194,12 @@ function bar(x) type is (integer) ! CHECK: AssignmentStmt bar = 0 - ! CHECK: TypeGuardStmt - class is (a_type) - ! CHECK: AssignmentStmt - bar = 1 - ! CHECK: ReturnStmt - return + !![disable]! COM: CHECK: TypeGuardStmt + !![disable]class is (a_type) + !![disable] ! COM: CHECK: AssignmentStmt + !![disable] bar = 1 + !![disable] ! COM: CHECK: ReturnStmt + !![disable] return ! CHECK: TypeGuardStmt class default ! CHECK: AssignmentStmt @@ -329,6 +332,5 @@ subroutine sub3() subroutine sub4() integer :: i print*, "test" - ! CHECK: DataStmt data i /1/ end subroutine diff --git a/flang/test/Lower/pre-fir-tree04.f90 b/flang/test/Lower/pre-fir-tree04.f90 index 3f2beaf5fb47..06fc88f76f54 100644 --- a/flang/test/Lower/pre-fir-tree04.f90 +++ b/flang/test/Lower/pre-fir-tree04.f90 @@ -1,4 +1,4 @@ -! RUN: %f18 -fdebug-pre-fir-tree -fsyntax-only %s | FileCheck %s +! RUN: %f18 -fsyntax-only -fdebug-pre-fir-tree %s | FileCheck %s ! Test Pre-FIR Tree captures all the coarray related statements diff --git a/flang/test/Lower/pre-fir-tree05.f90 b/flang/test/Lower/pre-fir-tree05.f90 index fb57663272e7..9096e3842385 100644 --- a/flang/test/Lower/pre-fir-tree05.f90 +++ b/flang/test/Lower/pre-fir-tree05.f90 @@ -27,9 +27,9 @@ subroutine foo() !$acc end parallel ! CHECK-NEXT: <> ! CHECK-NEXT: <> - ! CHECK-NEXT: ContinueStmt + ! CHECK-NEXT: EndSubroutineStmt end subroutine -! CHECK-NEXT: EndSubroutine foo +! CHECK-NEXT: End Subroutine foo ! CHECK: Subroutine foo subroutine foo2() @@ -43,7 +43,7 @@ subroutine foo2() end do !$acc end parallel loop ! CHECK-NEXT: <> - ! CHECK-NEXT: ContinueStmt + ! CHECK-NEXT: EndSubroutineStmt end subroutine -! CHECK-NEXT: EndSubroutine foo2 +! CHECK-NEXT: End Subroutine foo2 diff --git a/flang/test/Semantics/bindings01.f90 b/flang/test/Semantics/bindings01.f90 index 210530b5af26..b83804786c60 100644 --- a/flang/test/Semantics/bindings01.f90 +++ b/flang/test/Semantics/bindings01.f90 @@ -132,6 +132,87 @@ subroutine mp(x) end subroutine end module m1 +module m2 + type parent + real realField + contains + !ERROR: Procedure binding 'proc' with no dummy arguments must have NOPASS attribute + procedure proc + end type parent + type,extends(parent) :: child + contains + !ERROR: Procedure binding 'proc' with no dummy arguments must have NOPASS attribute + procedure proc + end type child +contains + subroutine proc + end subroutine +end module m2 + +module m3 + type t + contains + procedure b + end type +contains + !ERROR: Cannot use an alternate return as the passed-object dummy argument + subroutine b(*) + return 1 + end subroutine +end module m3 + +module m4 + type t + contains + procedure b + end type +contains + ! Check to see that alternate returns work with default PASS arguments + subroutine b(this, *) + class(t) :: this + return 1 + end subroutine +end module m4 + +module m5 + type t + contains + !ERROR: Passed-object dummy argument 'passarg' of procedure 'b' must be of type 't' but is 'INTEGER(4)' + procedure, pass(passArg) :: b + end type +contains + subroutine b(*, passArg) + integer :: passArg + return 1 + end subroutine +end module m5 + +module m6 + type t + contains + !ERROR: Passed-object dummy argument 'passarg' of procedure 'b' must be polymorphic because 't' is extensible + procedure, pass(passArg) :: b + end type +contains + subroutine b(*, passArg) + type(t) :: passArg + return 1 + end subroutine +end module m6 + +module m7 + type t + contains + ! Check to see that alternate returns work with PASS arguments + procedure, pass(passArg) :: b + end type +contains + subroutine b(*, passArg) + class(t) :: passArg + return 1 + end subroutine +end module m7 + program test use m1 type,extends(t) :: t2 diff --git a/flang/test/Semantics/call02.f90 b/flang/test/Semantics/call02.f90 index 4418837d61ea..1b0701a0c922 100644 --- a/flang/test/Semantics/call02.f90 +++ b/flang/test/Semantics/call02.f90 @@ -19,11 +19,9 @@ subroutine badsubr(dummy) call subr(cos) ! not an error !ERROR: Non-intrinsic ELEMENTAL procedure 'elem' may not be passed as an actual argument call subr(elem) ! C1533 - !ERROR: Actual argument associated with procedure dummy argument 'dummy=' is not a procedure - !ERROR: Actual argument associated with non-POINTER procedure dummy argument 'dummy=' must be a procedure (and not a procedure pointer) + !ERROR: Actual argument associated with procedure dummy argument 'dummy=' is a null pointer call subr(null()) - !ERROR: Actual argument associated with procedure dummy argument 'dummy=' is not a procedure - !ERROR: Actual argument associated with non-POINTER procedure dummy argument 'dummy=' must be a procedure (and not a procedure pointer) + !ERROR: Actual argument associated with procedure dummy argument 'dummy=' is typeless call subr(B"1010") end subroutine diff --git a/flang/test/Semantics/call09.f90 b/flang/test/Semantics/call09.f90 index 9db5887dc4e7..6f5547063ead 100644 --- a/flang/test/Semantics/call09.f90 +++ b/flang/test/Semantics/call09.f90 @@ -76,7 +76,7 @@ subroutine test1 ! 15.5.2.9(5) call s01(sin) ! ok !ERROR: Actual argument associated with procedure dummy argument 'p=' is not a procedure call s01(null(intPtr)) - !ERROR: Actual argument associated with procedure dummy argument 'p=' is not a procedure + !ERROR: Actual argument associated with procedure dummy argument 'p=' is typeless call s01(B"0101") !ERROR: Actual procedure argument has an implicit interface which is not known to be compatible with dummy argument 'p=' which has an explicit interface call s01(extfunc) diff --git a/flang/test/Semantics/call18.f90 b/flang/test/Semantics/call18.f90 new file mode 100644 index 000000000000..95c850d61a3f --- /dev/null +++ b/flang/test/Semantics/call18.f90 @@ -0,0 +1,26 @@ +! RUN: %S/test_errors.sh %s %t %f18 +! Ensure that references to functions that return pointers can serve as +! "variables" in actual arguments. All of these uses are conforming and +! no errors should be reported. +module m + integer, target :: x = 1 + contains + function get() result(p) + integer, pointer :: p + p => x + end function get + subroutine increment(n) + integer, intent(inout) :: n + n = n + 1 + end subroutine increment +end module m + +use m +integer, pointer :: q +get() = 2 +call increment(get()) +q => get() +read(*) get() +open(file='file',newunit=get()) +allocate(q,stat=get()) +end diff --git a/flang/test/Semantics/getsymbols01.f90 b/flang/test/Semantics/getsymbols01.f90 index d26aa774ace4..9a52ee7cbf2a 100644 --- a/flang/test/Semantics/getsymbols01.f90 +++ b/flang/test/Semantics/getsymbols01.f90 @@ -15,7 +15,7 @@ recursive pure function f() result(x) end function end module -! RUN: %f18 -fget-symbols-sources -fsyntax-only %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fsyntax-only -fget-symbols-sources %s 2>&1 | FileCheck %s ! CHECK-COUNT-1:f:{{.*}}getsymbols01.f90, 12, 26-27 ! CHECK-COUNT-1:mm1:{{.*}}getsymbols01.f90, 2, 8-11 ! CHECK-COUNT-1:s:{{.*}}getsymbols01.f90, 5, 18-19 diff --git a/flang/test/Semantics/getsymbols02.f90 b/flang/test/Semantics/getsymbols02.f90 index 1667548f81c3..32929904fb7a 100644 --- a/flang/test/Semantics/getsymbols02.f90 +++ b/flang/test/Semantics/getsymbols02.f90 @@ -7,8 +7,8 @@ PROGRAM helloworld i = callget5() ENDPROGRAM -! RUN: %f18 -fsyntax-only %S/Inputs/getsymbols02-a.f90 -! RUN: %f18 -fsyntax-only %S/Inputs/getsymbols02-b.f90 -! RUN: %f18 -fget-symbols-sources -fsyntax-only %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fsyntax-only %S/Inputs/getsymbols02-a.f90 +! RUN: %flang_fc1 -fsyntax-only %S/Inputs/getsymbols02-b.f90 +! RUN: %flang_fc1 -fsyntax-only -fget-symbols-sources %s 2>&1 | FileCheck %s ! CHECK: callget5: .{{[/\\]}}mm2b.mod, ! CHECK: get5: .{{[/\\]}}mm2a.mod, diff --git a/flang/test/Semantics/getsymbols03-a.f90 b/flang/test/Semantics/getsymbols03-a.f90 index fddf513bcc51..0bc19b4fe8d0 100644 --- a/flang/test/Semantics/getsymbols03-a.f90 +++ b/flang/test/Semantics/getsymbols03-a.f90 @@ -7,7 +7,7 @@ program main x = f end program -! RUN: %f18 -fget-symbols-sources -fsyntax-only %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fsyntax-only -fget-symbols-sources %s 2>&1 | FileCheck %s ! CHECK:f:{{.*}}getsymbols03-b.f90, 2, 12-13 ! CHECK:main:{{.*}}getsymbols03-a.f90, 4, 9-13 ! CHECK:mm3:{{.*}}getsymbols03-a.f90, 5, 6-9 diff --git a/flang/test/Semantics/getsymbols04.f90 b/flang/test/Semantics/getsymbols04.f90 index ac8f2d0a7e44..28027ea759b6 100644 --- a/flang/test/Semantics/getsymbols04.f90 +++ b/flang/test/Semantics/getsymbols04.f90 @@ -6,7 +6,7 @@ program main x = y end program -! RUN: %f18 -fget-symbols-sources -fsyntax-only %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fsyntax-only -fget-symbols-sources %s 2>&1 | FileCheck %s ! CHECK:x:{{.*}}getsymbols04.f90, 3, 14-15 ! CHECK:x:{{.*}}getsymbols04.f90, 5, 11-12 ! CHECK:y:{{.*}}getsymbols04.f90, 4, 14-15 diff --git a/flang/test/Semantics/getsymbols05.f90 b/flang/test/Semantics/getsymbols05.f90 index 6b07678e42d0..99771e227c3f 100644 --- a/flang/test/Semantics/getsymbols05.f90 +++ b/flang/test/Semantics/getsymbols05.f90 @@ -9,7 +9,7 @@ program main x = y end program -! RUN: %f18 -fget-symbols-sources -fsyntax-only %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fsyntax-only -fget-symbols-sources %s 2>&1 | FileCheck %s ! CHECK:x:{{.*}}getsymbols05.f90, 3, 14-15 ! CHECK:x:{{.*}}getsymbols05.f90, 6, 16-17 ! CHECK:y:{{.*}}getsymbols05.f90, 4, 14-15 diff --git a/flang/test/Semantics/init01.f90 b/flang/test/Semantics/init01.f90 index f896943acce1..2492051cdb74 100644 --- a/flang/test/Semantics/init01.f90 +++ b/flang/test/Semantics/init01.f90 @@ -82,4 +82,15 @@ subroutine components end type type(t2(3,3)) :: o1 type(t2(2,2)) :: o2 + type :: t3 + real :: x + end type + type(t3), save, target :: o3 + real, pointer :: p10 => o3%x + associate (a1 => o3, a2 => o3%x) + block + real, pointer :: p11 => a1 + real, pointer :: p12 => a2 + end block + end associate end subroutine diff --git a/flang/test/Semantics/mod-file-rewriter.f90 b/flang/test/Semantics/mod-file-rewriter.f90 index 2856dd6dbdf3..2d393dfeca50 100644 --- a/flang/test/Semantics/mod-file-rewriter.f90 +++ b/flang/test/Semantics/mod-file-rewriter.f90 @@ -1,8 +1,8 @@ ! RUN: rm -fr %t && mkdir %t && cd %t -! RUN: %f18 -fsyntax-only -fdebug-module-writer %s 2>&1 | FileCheck %s --check-prefix CHECK_CHANGED -! RUN: %f18 -fsyntax-only -fdebug-module-writer %s 2>&1 | FileCheck %s --check-prefix CHECK_UNCHANGED -! RUN: %f18 -fsyntax-only -fdebug-module-writer %p/Inputs/mod-file-unchanged.f90 2>&1 | FileCheck %s --check-prefix CHECK_UNCHANGED -! RUN: %f18 -fsyntax-only -fdebug-module-writer %p/Inputs/mod-file-changed.f90 2>&1 | FileCheck %s --check-prefix CHECK_CHANGED +! RUN: %flang_fc1 -fsyntax-only -fdebug-module-writer %s 2>&1 | FileCheck %s --check-prefix CHECK_CHANGED +! RUN: %flang_fc1 -fsyntax-only -fdebug-module-writer %s 2>&1 | FileCheck %s --check-prefix CHECK_UNCHANGED +! RUN: %flang_fc1 -fsyntax-only -fdebug-module-writer %p/Inputs/mod-file-unchanged.f90 2>&1 | FileCheck %s --check-prefix CHECK_UNCHANGED +! RUN: %flang_fc1 -fsyntax-only -fdebug-module-writer %p/Inputs/mod-file-changed.f90 2>&1 | FileCheck %s --check-prefix CHECK_CHANGED module m real :: x(10) diff --git a/flang/test/Semantics/modfile04.f90 b/flang/test/Semantics/modfile04.f90 index bc4d8d4895ad..9312b756513c 100644 --- a/flang/test/Semantics/modfile04.f90 +++ b/flang/test/Semantics/modfile04.f90 @@ -6,7 +6,7 @@ module m1 end type contains - pure subroutine s(x, y) bind(c) + pure subroutine Ss(x, y) bind(c) logical x intent(inout) y intent(in) x @@ -53,7 +53,7 @@ end module m3 !type::t !end type !contains -!pure subroutine s(x,y) bind(c) +!pure subroutine ss(x,y) bind(c, name="ss") !logical(4),intent(in)::x !real(4),intent(inout)::y !end diff --git a/flang/test/Semantics/modfile21.f90 b/flang/test/Semantics/modfile21.f90 index d7b45f70c00d..73cf59f827a2 100644 --- a/flang/test/Semantics/modfile21.f90 +++ b/flang/test/Semantics/modfile21.f90 @@ -26,10 +26,10 @@ module m ! real(4)::v ! complex(4)::w ! real(4)::cb -! common//t,w,u,v ! common/cb/x,y,z ! bind(c, name="CB")::/cb/ ! common/cb2/a,b,c -! bind(c)::/cb2/ +! bind(c, name="cb2")::/cb2/ ! common/b/cb +! common//t,w,u,v !end diff --git a/flang/test/Semantics/modifiable01.f90 b/flang/test/Semantics/modifiable01.f90 index dfa9396565e0..ad81e027932b 100644 --- a/flang/test/Semantics/modifiable01.f90 +++ b/flang/test/Semantics/modifiable01.f90 @@ -46,7 +46,7 @@ subroutine test1(dummy) read(internal,*) a ! ok end associate !CHECK: error: Input variable 'j3' must be definable - !CHECK: 'j3' is not a variable + !CHECK: '666_4' is not a variable read(internal,*) j3 !CHECK: error: Left-hand side of assignment is not modifiable !CHECK: 't2var' is an entity with either an EVENT_TYPE or LOCK_TYPE diff --git a/flang/test/Semantics/omp-ordered-simd.f90 b/flang/test/Semantics/omp-ordered-simd.f90 new file mode 100644 index 000000000000..d597191650e7 --- /dev/null +++ b/flang/test/Semantics/omp-ordered-simd.f90 @@ -0,0 +1,95 @@ +! RUN: %S/test_errors.sh %s %t %flang -fopenmp +! OpenMP Version 4.5 +! Various checks with the ordered construct + +SUBROUTINE WORK(I) + INTEGER I +END SUBROUTINE WORK + +SUBROUTINE ORDERED_GOOD(N) + INTEGER N, I, A(10), B(10), C(10) + !$OMP SIMD + DO I = 1,N + IF (I <= 10) THEN + !$OMP ORDERED SIMD + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END SIMD +END SUBROUTINE ORDERED_GOOD + +SUBROUTINE ORDERED_BAD(N) + INTEGER N, I, A(10), B(10), C(10) + + !$OMP DO SIMD + DO I = 1,N + IF (I <= 10) THEN + !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END DO SIMD + + !$OMP PARALLEL DO + DO I = 1,N + IF (I <= 10) THEN + !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END PARALLEL DO + + !$OMP CRITICAL + DO I = 1,N + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END CRITICAL + + !$OMP CRITICAL + WRITE(*,*) I + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + !$OMP END CRITICAL + + !$OMP ORDERED + WRITE(*,*) I + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + !$OMP END ORDERED + + !$OMP TASK + C = C - A * B + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + !$OMP END TASK + + !$OMP TASKLOOP + DO I = 1,N + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END TASKLOOP + +END SUBROUTINE ORDERED_BAD diff --git a/flang/test/Semantics/omp-reduction01.f90 b/flang/test/Semantics/omp-reduction01.f90 new file mode 100644 index 000000000000..f518583fd5f0 --- /dev/null +++ b/flang/test/Semantics/omp-reduction01.f90 @@ -0,0 +1,14 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + integer :: i + integer :: k = 10 + + !ERROR: Invalid reduction operator in REDUCTION clause. + !$omp parallel do reduction(**:k) + do i = 1, 10 + k = k ** 1 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/Semantics/omp-reduction02.f90 b/flang/test/Semantics/omp-reduction02.f90 new file mode 100644 index 000000000000..1ffbac3a845f --- /dev/null +++ b/flang/test/Semantics/omp-reduction02.f90 @@ -0,0 +1,37 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + + integer :: i + integer :: k = 10 + integer :: j = 10 + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:k), reduction(-:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:k), reduction(-:j), reduction(+:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:j), reduction(-:k), reduction(+:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:j), reduction(-:k), private(k) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/Semantics/omp-reduction03.f90 b/flang/test/Semantics/omp-reduction03.f90 new file mode 100644 index 000000000000..d2876566a95c --- /dev/null +++ b/flang/test/Semantics/omp-reduction03.f90 @@ -0,0 +1,18 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause + +subroutine omp_target(p) + integer, pointer, intent(in) :: p + + integer :: i + integer :: k = 10 + + !ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a REDUCTION clause + !$omp parallel do reduction(+:p) + do i = 1, 10 + k= k + 1 + end do + !$omp end parallel do + +end subroutine omp_target diff --git a/flang/test/Semantics/omp-reduction04.f90 b/flang/test/Semantics/omp-reduction04.f90 new file mode 100644 index 000000000000..5441b2baccd0 --- /dev/null +++ b/flang/test/Semantics/omp-reduction04.f90 @@ -0,0 +1,22 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_Reduction + integer :: i + integer, parameter :: k = 10 + common /c/ a, b + + !ERROR: Variable 'k' on the REDUCTION clause is not definable + !$omp parallel do reduction(+:k) + do i = 1, 10 + l = k + 1 + end do + !$omp end parallel do + + !ERROR: Variable 'c' on the REDUCTION clause is not definable + !$omp parallel do reduction(-:/c/) + do i = 1, 10 + l = k + 1 + end do + !$omp end parallel do +end program omp_Reduction diff --git a/flang/test/Semantics/omp-reduction05.f90 b/flang/test/Semantics/omp-reduction05.f90 new file mode 100644 index 000000000000..bccd9300e59f --- /dev/null +++ b/flang/test/Semantics/omp-reduction05.f90 @@ -0,0 +1,38 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause + +program omp_reduction + + integer :: i + integer :: k = 10 + integer :: a(10),b(10,10,10) + + !ERROR: 'a' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:a(1:0:2)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'a' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:a(1:0)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'b' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:b(1:6,5,1:0)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'b' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:b(1:6,1:0:5,1:10)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/Semantics/omp-reduction06.f90 b/flang/test/Semantics/omp-reduction06.f90 new file mode 100644 index 000000000000..9d9ad2405e69 --- /dev/null +++ b/flang/test/Semantics/omp-reduction06.f90 @@ -0,0 +1,31 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause + +program omp_reduction + + integer :: i + integer :: k = 10 + integer :: a(10), b(10,10,10) + + !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !$omp parallel do reduction(+:a(1:10:3)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !$omp parallel do reduction(+:b(1:10:3,1:8:1,1:5:1)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !$omp parallel do reduction(+:b(1:10:1,1:8:2,1:5:1)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/Semantics/omp-reduction07.f90 b/flang/test/Semantics/omp-reduction07.f90 new file mode 100644 index 000000000000..30dc5c5de3a4 --- /dev/null +++ b/flang/test/Semantics/omp-reduction07.f90 @@ -0,0 +1,113 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + + integer :: i,j,l + integer :: k = 10 + !$omp parallel private(k) + !ERROR: REDUCTION variable 'k' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(+:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end do + !$omp end parallel + + + !$omp parallel private(j),reduction(-:k) + !ERROR: REDUCTION variable 'k' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(+:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end do + !$omp end parallel + + !$omp parallel private(j),firstprivate(k) + !ERROR: REDUCTION variable 'k' is FIRSTPRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(min:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end do + !$omp end parallel + + + !$omp parallel private(l,j),firstprivate(k) + !ERROR: REDUCTION variable 'k' is FIRSTPRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !ERROR: REDUCTION variable 'j' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp sections reduction(ior:k) reduction(-:j) + do i = 1, 10 + k = k + 1 + end do + !$omp end sections + !$omp end parallel + +!$omp sections private(k) + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !ERROR: REDUCTION variable 'k' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(+:k) reduction(max:j) + do i = 1, 10 + k = k + 1 + end do + !$omp end do +!$omp end sections + +!$omp parallel reduction(+:a) +!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. +!$omp sections reduction(-:a) +a = 10 +!$omp end sections +!$omp end parallel + +!$omp parallel reduction(-:a) +!$omp end parallel + + +!$omp parallel reduction(+:a) +!ERROR: REDUCTION clause is not allowed on the WORKSHARE directive +!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. +!$omp workshare reduction(-:a) +a = 10 +!$omp end workshare +!$omp end parallel + +!$omp parallel reduction(-:a) +!$omp end parallel + + +!$omp parallel reduction(+:a) +!ERROR: REDUCTION clause is not allowed on the SINGLE directive +!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. +!$omp single reduction(-:a) +a = 10 +!$omp end single +!$omp end parallel + +!$omp parallel reduction(-:a) +!$omp end parallel + + +!$omp parallel reduction(+:a) +!ERROR: REDUCTION clause is not allowed on the SINGLE directive +!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. +!$omp single reduction(iand:a) +a = 10 +!$omp end single +!$omp end parallel + +!$omp parallel reduction(iand:a) +!$omp end parallel + +!$omp parallel reduction(ieor:a) +!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. +!$omp sections reduction(-:a) +a = 10 +!$omp end sections +!$omp end parallel + +!$omp parallel reduction(ieor:a) +!$omp end parallel + +end program omp_reduction diff --git a/flang/test/Semantics/omp-reduction08.f90 b/flang/test/Semantics/omp-reduction08.f90 new file mode 100644 index 000000000000..c2c2d4975782 --- /dev/null +++ b/flang/test/Semantics/omp-reduction08.f90 @@ -0,0 +1,63 @@ +! RUN: %S/test_symbols.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause Positive cases + +!DEF: /omp_reduction MainProgram +program omp_reduction + !DEF: /omp_reduction/i ObjectEntity INTEGER(4) + integer i + !DEF: /omp_reduction/k ObjectEntity INTEGER(4) + integer :: k = 10 + !DEF: /omp_reduction/m ObjectEntity INTEGER(4) + integer :: m = 12 + !$omp parallel do reduction(max:k) + !DEF: /omp_reduction/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block1/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/max ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = max(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(min:k) + !DEF: /omp_reduction/Block2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block2/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/min ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = min(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(iand:k) + !DEF: /omp_reduction/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block3/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/iand ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = iand(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(ior:k) + !DEF: /omp_reduction/Block4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block4/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/ior ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = ior(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(ieor:k) + !DEF: /omp_reduction/Block5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block5/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/ieor ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = ieor(k,m) + end do + !$omp end parallel do + +end program omp_reduction diff --git a/flang/test/Semantics/omp-reduction09.f90 b/flang/test/Semantics/omp-reduction09.f90 new file mode 100644 index 000000000000..5612d1a0b8f6 --- /dev/null +++ b/flang/test/Semantics/omp-reduction09.f90 @@ -0,0 +1,86 @@ +! RUN: %S/test_symbols.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause Positive cases. +!DEF: /omp_reduction MainProgram +program omp_reduction + !DEF: /omp_reduction/i ObjectEntity INTEGER(4) + integer i + !DEF: /omp_reduction/k ObjectEntity INTEGER(4) + integer :: k = 10 + !DEF: /omp_reduction/a ObjectEntity INTEGER(4) + integer a(10) + !DEF: /omp_reduction/b ObjectEntity INTEGER(4) + integer b(10,10,10) + + !$omp parallel shared(k) + !$omp do reduction(+:k) + !DEF: /omp_reduction/Block1/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block1/Block1/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + !$omp end parallel + + + !$omp parallel do reduction(+:a(10)) + !DEF: /omp_reduction/Block2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + + !$omp parallel do reduction(+:a(1:10:1)) + !DEF: /omp_reduction/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + !$omp parallel do reduction(+:b(1:10:1,1:5,2)) + !DEF: /omp_reduction/Block4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + !$omp parallel do reduction(+:b(1:10:1,1:5,2:5:1)) + !DEF: /omp_reduction/Block5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + !$omp parallel private(i) + !$omp do reduction(+:k) reduction(+:j) + !DEF: /omp_reduction/Block6/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block6/Block1/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + !$omp end parallel + + !$omp do reduction(-:k) reduction(*:j) reduction(-:l) + !DEF: /omp_reduction/Block7/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block7/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + + + !$omp do reduction(.and.:k) reduction(.or.:j) reduction(.eqv.:l) + !DEF: /omp_reduction/Block8/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/Block8/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + +end program omp_reduction diff --git a/flang/test/Semantics/omp-reduction10.f90 b/flang/test/Semantics/omp-reduction10.f90 new file mode 100644 index 000000000000..cecbf54222fa --- /dev/null +++ b/flang/test/Semantics/omp-reduction10.f90 @@ -0,0 +1,15 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + + integer :: i + integer :: k = 10 + + !ERROR: Invalid reduction identifier in REDUCTION clause. + !$omp parallel do reduction(foo:k) + do i = 1, 10 + k = foo(k) + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/Semantics/omp-simd-aligned.f90 b/flang/test/Semantics/omp-simd-aligned.f90 new file mode 100644 index 000000000000..5626608114d5 --- /dev/null +++ b/flang/test/Semantics/omp-simd-aligned.f90 @@ -0,0 +1,54 @@ +! RUN: %S/test_errors.sh %s %t %flang -fopenmp + +! OpenMP Version 4.5 +! 2.8.1 simd Construct +! Semantic error for correct test case + +program omp_simd + integer i, j, k + integer, allocatable :: a(:), b(:) + + allocate(a(10)) + allocate(b(10)) + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a, a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !ERROR: List item 'b' present at multiple ALIGNED clauses + !$omp simd aligned(a,a) aligned(b) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) aligned(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !$omp simd aligned(a) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) private(a) aligned(a) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + print *, a + +end program omp_simd diff --git a/flang/test/Semantics/omp-symbol08.f90 b/flang/test/Semantics/omp-symbol08.f90 index 1fb2a866dd17..233e36733556 100644 --- a/flang/test/Semantics/omp-symbol08.f90 +++ b/flang/test/Semantics/omp-symbol08.f90 @@ -143,7 +143,7 @@ subroutine dotprod (b, c, n, block_size, num_teams, block_threads) !REF: /dotprod/block_size !REF: /dotprod/n do i=i0,min(i0+block_size, n) - !REF: /dotprod/sum + !DEF: /dotprod/Block1/Block1/Block1/Block1/sum (OmpReduction) HostAssoc REAL(4) !REF: /dotprod/b !REF: /dotprod/Block1/Block1/Block1/Block1/i !REF: /dotprod/c diff --git a/flang/test/Semantics/resolve18.f90 b/flang/test/Semantics/resolve18.f90 index 94b217e248f0..334bb71c4f08 100644 --- a/flang/test/Semantics/resolve18.f90 +++ b/flang/test/Semantics/resolve18.f90 @@ -63,6 +63,15 @@ module m4b function foo(x) end end +module m4c + type :: foo + end type + interface foo + !ERROR: 'foo' is already declared in this scoping unit + real function foo() + end function foo + end interface foo +end ! Use associating a name that is a generic and a derived type module m5a @@ -85,3 +94,91 @@ subroutine s5 use m5b type(g) :: y end + +module m6 + real :: f6 + interface g6 + !ERROR: Procedure 'f6' was previously declared + real function f6() + end function f6 + end interface g6 +end module m6 + +module m7 + integer :: f7 + interface g7 + !ERROR: Procedure 'f7' was previously declared + real function f7() + end function f7 + end interface g7 +end module m7 + +module m8 + real :: f8 + interface g8 + !ERROR: Procedure 'f8' was previously declared + subroutine f8() + end subroutine f8 + end interface g8 +end module m8 + +module m9 + type f9 + end type f9 + !ERROR: 'f9' is already declared in this scoping unit + interface f9 + real function f9() + end function f9 + end interface f9 +contains + function f9(x) + end function f9 +end module m9 + +module m10 + type :: t10 + end type t10 + interface f10 + function f10() + end function f10 + end interface f10 +contains + !ERROR: 'f10' is already declared in this scoping unit + function f10(x) + end function f10 +end module m10 + +module m11 + type :: t11 + end type t11 + interface i11 + function f11() + end function f11 + end interface i11 +contains + !ERROR: 'f11' is already declared in this scoping unit + function f11(x) + end function f11 +end module m11 + +module m12 + interface f12 + function f12() + end function f12 + end interface f12 +contains + !ERROR: 'f12' is already declared in this scoping unit + function f12(x) + end function f12 +end module m12 + +module m13 + interface f13 + function f13() + end function f13 + end interface f13 +contains + !ERROR: 'f13' is already declared in this scoping unit + function f13() + end function f13 +end module m13 diff --git a/flang/test/Semantics/separate-mp02.f90 b/flang/test/Semantics/separate-mp02.f90 index 6d620e71118b..3dd717dbc90a 100644 --- a/flang/test/Semantics/separate-mp02.f90 +++ b/flang/test/Semantics/separate-mp02.f90 @@ -136,6 +136,12 @@ module subroutine s2() bind(c, name="s2") end module subroutine s3() bind(c, name="s3") end + module subroutine s4() bind(c, name=" s4") + end + module subroutine s5() bind(c) + end + module subroutine s6() bind(c) + end end interface end @@ -148,9 +154,16 @@ module subroutine s1() bind(c, name="s1") !ERROR: Module subprogram 's2' does not have a binding label but the corresponding interface body does module subroutine s2() end - !ERROR: Module subprogram 's3' has binding label "s3_xxx" but the corresponding interface body has "s3" + !ERROR: Module subprogram 's3' has binding label 's3_xxx' but the corresponding interface body has 's3' module subroutine s3() bind(c, name="s3" // suffix) end + module subroutine s4() bind(c, name="s4 ") + end + module subroutine s5() bind(c, name=" s5") + end + !ERROR: Module subprogram 's6' has binding label 'not_s6' but the corresponding interface body has 's6' + module subroutine s6() bind(c, name="not_s6") + end end diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py index 4392da680e7f..7c99d6f7636d 100644 --- a/flang/test/lit.cfg.py +++ b/flang/test/lit.cfg.py @@ -64,7 +64,6 @@ # the build directory holding that tool. tools = [ ToolSubst('%f18', command=FindTool('f18'), - extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir], unresolved='fatal') ] @@ -75,10 +74,8 @@ extra_args=['-fc1'], unresolved='fatal')) else: tools.append(ToolSubst('%flang', command=FindTool('f18'), - extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir], unresolved='fatal')) tools.append(ToolSubst('%flang_fc1', command=FindTool('f18'), - extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir], unresolved='fatal')) if config.flang_standalone_build: diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt index 41237fe06003..fc84bbf09c59 100644 --- a/flang/tools/f18/CMakeLists.txt +++ b/flang/tools/f18/CMakeLists.txt @@ -30,7 +30,6 @@ set(MODULES "__fortran_type_info" ) -set(include ${FLANG_BINARY_DIR}/include/flang) target_include_directories(f18 PRIVATE ${CMAKE_CURRENT_BINARY_DIR} @@ -38,27 +37,25 @@ target_include_directories(f18 # Create module files directly from the top-level module source directory foreach(filename ${MODULES}) + set(base ${FLANG_INTRINSIC_MODULES_DIR}/${filename}) if(${filename} MATCHES "__fortran_type_info") set(depends "") elseif(${filename} MATCHES "__fortran_builtins") - set(depends ${include}/__fortran_type_info.mod) + set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_type_info.mod) else() - set(depends ${include}/__fortran_builtins.mod) + set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_builtins.mod) endif() - add_custom_command(OUTPUT ${include}/${filename}.mod - COMMAND f18 -fsyntax-only -I${include} + add_custom_command(OUTPUT ${base}.mod + COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR} + COMMAND f18 -fsyntax-only -module-dir ${FLANG_INTRINSIC_MODULES_DIR} ${FLANG_SOURCE_DIR}/module/${filename}.f90 - WORKING_DIRECTORY ${include} DEPENDS f18 ${FLANG_SOURCE_DIR}/module/${filename}.f90 ${depends} ) - add_custom_command(OUTPUT ${include}/${filename}.f18.mod - DEPENDS ${include}/${filename}.mod - COMMAND ${CMAKE_COMMAND} -E - copy ${include}/${filename}.mod ${include}/${filename}.f18.mod) - list(APPEND MODULE_FILES ${include}/${filename}.mod) - list(APPEND MODULE_FILES ${include}/${filename}.f18.mod) - install(FILES ${include}/${filename}.mod DESTINATION include/flang) - install(FILES ${include}/${filename}.f18.mod DESTINATION include/flang) + add_custom_command(OUTPUT ${base}.f18.mod + DEPENDS ${base}.mod + COMMAND ${CMAKE_COMMAND} -E copy ${base}.mod ${base}.f18.mod) + list(APPEND MODULE_FILES ${base}.mod ${base}.f18.mod) + install(FILES ${base}.mod ${base}.f18.mod DESTINATION include/flang) endforeach() add_custom_target(module_files ALL DEPENDS ${MODULE_FILES}) diff --git a/flang/tools/f18/f18.cpp b/flang/tools/f18/f18.cpp index f43813e56f4b..9c5e6c9802fb 100644 --- a/flang/tools/f18/f18.cpp +++ b/flang/tools/f18/f18.cpp @@ -27,6 +27,7 @@ #include "flang/Version.inc" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" #include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" @@ -395,6 +396,16 @@ int printVersion() { return exitStatus; } +// Generate the path to look for intrinsic modules +static std::string getIntrinsicDir() { + // TODO: Find a system independent API + llvm::SmallString<128> driverPath; + driverPath.assign(llvm::sys::fs::getMainExecutable(nullptr, nullptr)); + llvm::sys::path::remove_filename(driverPath); + driverPath.append("/../include/flang/"); + return std::string(driverPath); +} + int main(int argc, char *const argv[]) { atexit(CleanUpAtExit); @@ -431,6 +442,10 @@ int main(int argc, char *const argv[]) { std::vector fortranSources, otherSources; bool anyFiles{false}; + // Add the default intrinsic module directory to the list of search + // directories + driver.searchDirectories.push_back(getIntrinsicDir()); + while (!args.empty()) { std::string arg{std::move(args.front())}; auto dot{arg.rfind(".")}; @@ -487,7 +502,8 @@ int main(int argc, char *const argv[]) { options.features.Enable( Fortran::common::LanguageFeature::BackslashEscapes, true); } else if (arg == "-Mstandard" || arg == "-std=f95" || - arg == "-std=f2003" || arg == "-std=f2008" || arg == "-std=legacy") { + arg == "-std=f2003" || arg == "-std=f2008" || arg == "-std=legacy" || + arg == "-std=f2018" || arg == "-pedantic") { driver.warnOnNonstandardUsage = true; } else if (arg == "-fopenacc") { options.features.Enable(Fortran::common::LanguageFeature::OpenACC); @@ -537,7 +553,8 @@ int main(int argc, char *const argv[]) { driver.debugModuleWriter = true; } else if (arg == "-fdebug-measure-parse-tree") { driver.measureTree = true; - } else if (arg == "-fdebug-instrumented-parse") { + } else if (arg == "-fdebug-instrumented-parse" || + arg == "-fdebug-dump-parsing-log") { options.instrumentedParse = true; } else if (arg == "-fdebug-no-semantics") { driver.debugNoSemantics = true; @@ -601,8 +618,11 @@ int main(int argc, char *const argv[]) { } else if (arg == "-module-suffix") { driver.moduleFileSuffix = args.front(); args.pop_front(); - } else if (arg == "-intrinsic-module-directory") { - driver.searchDirectories.push_back(args.front()); + } else if (arg == "-intrinsic-module-directory" || + arg == "-fintrinsic-modules-path") { + // prepend to the list of search directories + driver.searchDirectories.insert( + driver.searchDirectories.begin(), args.front()); args.pop_front(); } else if (arg == "-futf-8") { driver.encoding = Fortran::parser::Encoding::UTF_8; diff --git a/flang/tools/f18/flang b/flang/tools/f18/flang index 7109cd7f547a..81fac7b28345 100644 --- a/flang/tools/f18/flang +++ b/flang/tools/f18/flang @@ -8,11 +8,7 @@ #===------------------------------------------------------------------------===# wd=$(cd $(dirname "$0")/.. && pwd) -module_dir=$wd/include/flang -if [[ ! -d $module_dir ]]; then - module_dir=$wd/tools/flang/include/flang -fi -opts="-module-suffix .f18.mod -intrinsic-module-directory $module_dir" +opts="-module-suffix .f18.mod " if ! $wd/bin/f18 $opts "$@" then status=$? echo flang: in $PWD, f18 failed with exit status $status: $wd/bin/f18 $opts "$@" >&2 diff --git a/flang/tools/fir-opt/fir-opt.cpp b/flang/tools/fir-opt/fir-opt.cpp index b2d383c06682..b66294339f1a 100644 --- a/flang/tools/fir-opt/fir-opt.cpp +++ b/flang/tools/fir-opt/fir-opt.cpp @@ -17,9 +17,9 @@ using namespace mlir; int main(int argc, char **argv) { - fir::support::registerFIRPasses(); + fir::support::registerMLIRPassesForFortranTools(); DialectRegistry registry; fir::support::registerDialects(registry); return failed(MlirOptMain(argc, argv, "FIR modular optimizer driver\n", - registry, /*preloadDialectsInContext*/ false)); + registry, /*preloadDialectsInContext=*/false)); } diff --git a/flang/tools/tco/tco.cpp b/flang/tools/tco/tco.cpp index a67b1453fc28..62e31fe47ed1 100644 --- a/flang/tools/tco/tco.cpp +++ b/flang/tools/tco/tco.cpp @@ -106,7 +106,7 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) { } int main(int argc, char **argv) { - fir::support::registerFIRPasses(); + fir::support::registerMLIRPassesForFortranTools(); [[maybe_unused]] InitLLVM y(argc, argv); mlir::registerPassManagerCLOptions(); mlir::PassPipelineCLParser passPipe("", "Compiler passes to run"); diff --git a/flang/unittests/Evaluate/intrinsics.cpp b/flang/unittests/Evaluate/intrinsics.cpp index 52507b8ef8b6..a36dbf581822 100644 --- a/flang/unittests/Evaluate/intrinsics.cpp +++ b/flang/unittests/Evaluate/intrinsics.cpp @@ -24,7 +24,7 @@ class CookedStrings { offsets_[s] = cooked_.Put(s); cooked_.PutProvenance(allSources_.AddCompilerInsertion(s)); } - void Marshal() { cooked_.Marshal(allSources_); } + void Marshal() { cooked_.Marshal(allCookedSources_); } parser::CharBlock operator()(const std::string &s) { return {cooked_.AsCharBlock().begin() + offsets_[s], s.size()}; } diff --git a/flang/unittests/Runtime/CMakeLists.txt b/flang/unittests/Runtime/CMakeLists.txt index b80eceac7446..cc7ac7277183 100644 --- a/flang/unittests/Runtime/CMakeLists.txt +++ b/flang/unittests/Runtime/CMakeLists.txt @@ -23,11 +23,6 @@ add_flang_nongtest_unittest(format FortranRuntime ) -add_flang_nongtest_unittest(hello - RuntimeTesting - FortranRuntime -) - # This test is not run by default as it requires input. add_executable(external-hello-world external-hello.cpp @@ -46,3 +41,8 @@ add_flang_nongtest_unittest(list-input RuntimeTesting FortranRuntime ) + +add_flang_nongtest_unittest(buffer + RuntimeTesting + FortranRuntime +) diff --git a/flang/unittests/Runtime/buffer.cpp b/flang/unittests/Runtime/buffer.cpp new file mode 100644 index 000000000000..f5eca0338939 --- /dev/null +++ b/flang/unittests/Runtime/buffer.cpp @@ -0,0 +1,115 @@ +#include "../../runtime/buffer.h" +#include "testing.h" +#include +#include +#include +#include + +static constexpr std::size_t tinyBuffer{32}; +using FileOffset = std::int64_t; +using namespace Fortran::runtime; +using namespace Fortran::runtime::io; + +class Store : public FileFrame { +public: + explicit Store(std::size_t bytes = 65536) : bytes_{bytes} { + data_.reset(new char[bytes]); + std::memset(&data_[0], 0, bytes); + } + std::size_t bytes() const { return bytes_; } + void set_enforceSequence(bool yes = true) { enforceSequence_ = yes; } + void set_expect(FileOffset to) { expect_ = to; } + + std::size_t Read(FileOffset at, char *to, std::size_t minBytes, + std::size_t maxBytes, IoErrorHandler &handler) { + if (enforceSequence_ && at != expect_) { + handler.SignalError("Read(%d,%d,%d) not at expected %d", + static_cast(at), static_cast(minBytes), + static_cast(maxBytes), static_cast(expect_)); + } else if (at < 0 || at + minBytes > bytes_) { + handler.SignalError("Read(%d,%d,%d) is out of bounds", + static_cast(at), static_cast(minBytes), + static_cast(maxBytes)); + } + auto result{std::min(maxBytes, bytes_ - at)}; + std::memcpy(to, &data_[at], result); + expect_ = at + result; + return result; + } + std::size_t Write(FileOffset at, const char *from, std::size_t bytes, + IoErrorHandler &handler) { + if (enforceSequence_ && at != expect_) { + handler.SignalError("Write(%d,%d) not at expected %d", + static_cast(at), static_cast(bytes), + static_cast(expect_)); + } else if (at < 0 || at + bytes > bytes_) { + handler.SignalError("Write(%d,%d) is out of bounds", static_cast(at), + static_cast(bytes)); + } + std::memcpy(&data_[at], from, bytes); + expect_ = at + bytes; + return bytes; + } + +private: + std::size_t bytes_; + std::unique_ptr data_; + bool enforceSequence_{false}; + FileOffset expect_{0}; +}; + +inline int ChunkSize(int j, int most) { + // 31, 1, 29, 3, 27, ... + j %= tinyBuffer; + auto chunk{ + static_cast(((j % 2) ? j : (tinyBuffer - 1 - j)) % tinyBuffer)}; + return std::min(chunk, most); +} + +inline int ValueFor(int at) { return (at ^ (at >> 8)) & 0xff; } + +int main() { + StartTests(); + Terminator terminator{__FILE__, __LINE__}; + IoErrorHandler handler{terminator}; + Store store; + store.set_enforceSequence(true); + const auto bytes{static_cast(store.bytes())}; + // Fill with an assortment of chunks + int at{0}, j{0}; + while (at < bytes) { + auto chunk{ChunkSize(j, static_cast(bytes - at))}; + store.WriteFrame(at, chunk, handler); + char *to{store.Frame()}; + for (int k{0}; k < chunk; ++k) { + to[k] = ValueFor(at + k); + } + at += chunk; + ++j; + } + store.Flush(handler); + // Validate + store.set_expect(0); + at = 0; + while (at < bytes) { + auto chunk{ChunkSize(j, static_cast(bytes - at))}; + std::size_t frame{store.ReadFrame(at, chunk, handler)}; + if (frame < static_cast(chunk)) { + Fail() << "Badly-sized ReadFrame at " << at << ", chunk=" << chunk + << ", got " << frame << '\n'; + break; + } + const char *from{store.Frame()}; + for (int k{0}; k < chunk; ++k) { + auto expect{static_cast(ValueFor(at + k))}; + if (from[k] != expect) { + Fail() << "At " << at << '+' << k << '(' << (at + k) << "), read " + << (from[k] & 0xff) << ", expected " << static_cast(expect) + << '\n'; + } + } + at += chunk; + ++j; + } + return EndTests(); +} diff --git a/flang/unittests/Runtime/hello.cpp b/flang/unittests/Runtime/hello.cpp deleted file mode 100644 index d17c98e74c13..000000000000 --- a/flang/unittests/Runtime/hello.cpp +++ /dev/null @@ -1,526 +0,0 @@ -// Basic sanity tests of I/O API; exhaustive testing will be done in Fortran - -#include "testing.h" -#include "../../runtime/descriptor.h" -#include "../../runtime/io-api.h" -#include - -using namespace Fortran::runtime; -using namespace Fortran::runtime::io; - -static bool test(const char *format, const char *expect, std::string &&got) { - std::string want{expect}; - want.resize(got.length(), ' '); - if (got != want) { - Fail() << '\'' << format << "' failed;\n got '" << got - << "',\nexpected '" << want << "'\n"; - return false; - } - return true; -} - -static void hello() { - char buffer[32]; - const char *format{"(6HHELLO,,A6,2X,I3,1X,'0x',Z8,1X,L1)"}; - auto cookie{IONAME(BeginInternalFormattedOutput)( - buffer, sizeof buffer, format, std::strlen(format))}; - IONAME(OutputAscii)(cookie, "WORLD", 5); - IONAME(OutputInteger64)(cookie, 678); - IONAME(OutputInteger64)(cookie, 0xfeedface); - IONAME(OutputLogical)(cookie, true); - if (auto status{IONAME(EndIoStatement)(cookie)}) { - Fail() << "hello: '" << format << "' failed, status " - << static_cast(status) << '\n'; - } else { - test(format, "HELLO, WORLD 678 0xFEEDFACE T", - std::string{buffer, sizeof buffer}); - } -} - -static void multiline() { - char buffer[5][32]; - StaticDescriptor<1> staticDescriptor[2]; - Descriptor &whole{staticDescriptor[0].descriptor()}; - SubscriptValue extent[]{5}; - whole.Establish(TypeCode{CFI_type_char}, sizeof buffer[0], &buffer, 1, extent, - CFI_attribute_pointer); - whole.Dump(); - whole.Check(); - Descriptor §ion{staticDescriptor[1].descriptor()}; - SubscriptValue lowers[]{0}, uppers[]{4}, strides[]{1}; - section.Establish(whole.type(), whole.ElementBytes(), nullptr, 1, extent, - CFI_attribute_pointer); - if (auto error{ - CFI_section(§ion.raw(), &whole.raw(), lowers, uppers, strides)}) { - Fail() << "multiline: CFI_section failed: " << error << '\n'; - return; - } - section.Dump(); - section.Check(); - const char *format{ - "('?abcde,',T1,'>',T9,A,TL12,A,TR25,'<'//G0,17X,'abcd',1(2I4))"}; - auto cookie{IONAME(BeginInternalArrayFormattedOutput)( - section, format, std::strlen(format))}; - IONAME(OutputAscii)(cookie, "WORLD", 5); - IONAME(OutputAscii)(cookie, "HELLO", 5); - IONAME(OutputInteger64)(cookie, 789); - for (int j{666}; j <= 999; j += 111) { - IONAME(OutputInteger64)(cookie, j); - } - if (auto status{IONAME(EndIoStatement)(cookie)}) { - Fail() << "multiline: '" << format << "' failed, status " - << static_cast(status) << '\n'; - } else { - test(format, - ">HELLO, WORLD <" - " " - "789 abcd 666 777" - " 888 999 " - " ", - std::string{buffer[0], sizeof buffer}); - } -} - -static void listInputTest() { - static const char input[]{",1*,(5.,6..)"}; - auto cookie{IONAME(BeginInternalListInput)(input, sizeof input - 1)}; - float z[6]; - for (int j{0}; j < 6; ++j) { - z[j] = -(j + 1); - } - for (int j{0}; j < 6; j += 2) { - if (!IONAME(InputComplex32)(cookie, &z[j])) { - Fail() << "InputComplex32 failed\n"; - } - } - auto status{IONAME(EndIoStatement)(cookie)}; - if (status) { - Fail() << "Failed complex list-directed input, status " - << static_cast(status) << '\n'; - } else { - char output[33]; - output[32] = '\0'; - cookie = IONAME(BeginInternalListOutput)(output, 32); - for (int j{0}; j < 6; j += 2) { - if (!IONAME(OutputComplex32)(cookie, z[j], z[j + 1])) { - Fail() << "OutputComplex32 failed\n"; - } - } - status = IONAME(EndIoStatement)(cookie); - static const char expect[33]{" (-1.,-2.) (-3.,-4.) (5.,6.) "}; - if (status) { - Fail() << "Failed complex list-directed output, status " - << static_cast(status) << '\n'; - } else if (std::strncmp(output, expect, 33) != 0) { - Fail() << "Failed complex list-directed output, expected '" << expect - << "', but got '" << output << "'\n"; - } - } -} - -static void descrOutputTest() { - char buffer[9]; - // Formatted - const char *format{"(2A4)"}; - auto cookie{IONAME(BeginInternalFormattedOutput)( - buffer, sizeof buffer, format, std::strlen(format))}; - StaticDescriptor<1> staticDescriptor; - Descriptor &desc{staticDescriptor.descriptor()}; - SubscriptValue extent[]{2}; - char data[2][4]; - std::memcpy(data[0], "ABCD", 4); - std::memcpy(data[1], "EFGH", 4); - desc.Establish(TypeCode{CFI_type_char}, sizeof data[0], &data, 1, extent); - desc.Dump(); - desc.Check(); - IONAME(OutputDescriptor)(cookie, desc); - if (auto status{IONAME(EndIoStatement)(cookie)}) { - Fail() << "descrOutputTest: '" << format << "' failed, status " - << static_cast(status) << '\n'; - } else { - test("descrOutputTest(formatted)", "ABCDEFGH ", - std::string{buffer, sizeof buffer}); - } - // List-directed - cookie = IONAME(BeginInternalListOutput)(buffer, sizeof buffer); - IONAME(OutputDescriptor)(cookie, desc); - if (auto status{IONAME(EndIoStatement)(cookie)}) { - Fail() << "descrOutputTest: list-directed failed, status " - << static_cast(status) << '\n'; - } else { - test("descrOutputTest(list)", " ABCDEFGH", - std::string{buffer, sizeof buffer}); - } -} - -static void realTest(const char *format, double x, const char *expect) { - char buffer[800]; - auto cookie{IONAME(BeginInternalFormattedOutput)( - buffer, sizeof buffer, format, std::strlen(format))}; - IONAME(OutputReal64)(cookie, x); - if (auto status{IONAME(EndIoStatement)(cookie)}) { - Fail() << '\'' << format << "' failed, status " << static_cast(status) - << '\n'; - } else { - test(format, expect, std::string{buffer, sizeof buffer}); - } -} - -static void realInTest( - const char *format, const char *data, std::uint64_t want) { - auto cookie{IONAME(BeginInternalFormattedInput)( - data, std::strlen(data), format, std::strlen(format))}; - union { - double x; - std::uint64_t raw; - } u; - u.raw = 0; - IONAME(EnableHandlers)(cookie, true, true, true, true, true); - IONAME(InputReal64)(cookie, u.x); - char iomsg[65]; - iomsg[0] = '\0'; - iomsg[sizeof iomsg - 1] = '\0'; - IONAME(GetIoMsg)(cookie, iomsg, sizeof iomsg - 1); - auto status{IONAME(EndIoStatement)(cookie)}; - if (status) { - Fail() << '\'' << format << "' failed reading '" << data << "', status " - << static_cast(status) << " iomsg '" << iomsg << "'\n"; - } else if (u.raw != want) { - Fail() << '\'' << format << "' failed reading '" << data << "', want 0x"; - Fail().write_hex(want) << ", got 0x" << u.raw << '\n'; - } -} - -int main() { - StartTests(); - - hello(); - multiline(); - - static const char *zeroes[][2]{ - {"(E32.17,';')", " 0.00000000000000000E+00;"}, - {"(F32.17,';')", " 0.00000000000000000;"}, - {"(G32.17,';')", " 0.0000000000000000 ;"}, - {"(DC,E32.17,';')", " 0,00000000000000000E+00;"}, - {"(DC,F32.17,';')", " 0,00000000000000000;"}, - {"(DC,G32.17,';')", " 0,0000000000000000 ;"}, - {"(D32.17,';')", " 0.00000000000000000D+00;"}, - {"(E32.17E1,';')", " 0.00000000000000000E+0;"}, - {"(G32.17E1,';')", " 0.0000000000000000 ;"}, - {"(E32.17E0,';')", " 0.00000000000000000E+0;"}, - {"(G32.17E0,';')", " 0.0000000000000000 ;"}, - {"(1P,E32.17,';')", " 0.00000000000000000E+00;"}, - {"(1PE32.17,';')", " 0.00000000000000000E+00;"}, // no comma - {"(1P,F32.17,';')", " 0.00000000000000000;"}, - {"(1P,G32.17,';')", " 0.0000000000000000 ;"}, - {"(2P,E32.17,';')", " 00.0000000000000000E+00;"}, - {"(-1P,E32.17,';')", " 0.00000000000000000E+00;"}, - {"(G0,';')", "0.;"}, {}}; - for (int j{0}; zeroes[j][0]; ++j) { - realTest(zeroes[j][0], 0.0, zeroes[j][1]); - } - - static const char *ones[][2]{ - {"(E32.17,';')", " 0.10000000000000000E+01;"}, - {"(F32.17,';')", " 1.00000000000000000;"}, - {"(G32.17,';')", " 1.0000000000000000 ;"}, - {"(E32.17E1,';')", " 0.10000000000000000E+1;"}, - {"(G32.17E1,';')", " 1.0000000000000000 ;"}, - {"(E32.17E0,';')", " 0.10000000000000000E+1;"}, - {"(G32.17E0,';')", " 1.0000000000000000 ;"}, - {"(E32.17E4,';')", " 0.10000000000000000E+0001;"}, - {"(G32.17E4,';')", " 1.0000000000000000 ;"}, - {"(1P,E32.17,';')", " 1.00000000000000000E+00;"}, - {"(1PE32.17,';')", " 1.00000000000000000E+00;"}, // no comma - {"(1P,F32.17,';')", " 10.00000000000000000;"}, - {"(1P,G32.17,';')", " 1.0000000000000000 ;"}, - {"(ES32.17,';')", " 1.00000000000000000E+00;"}, - {"(2P,E32.17,';')", " 10.0000000000000000E-01;"}, - {"(2P,G32.17,';')", " 1.0000000000000000 ;"}, - {"(-1P,E32.17,';')", " 0.01000000000000000E+02;"}, - {"(-1P,G32.17,';')", " 1.0000000000000000 ;"}, - {"(G0,';')", "1.;"}, {}}; - for (int j{0}; ones[j][0]; ++j) { - realTest(ones[j][0], 1.0, ones[j][1]); - } - - realTest("(E32.17,';')", -1.0, " -0.10000000000000000E+01;"); - realTest("(F32.17,';')", -1.0, " -1.00000000000000000;"); - realTest("(G32.17,';')", -1.0, " -1.0000000000000000 ;"); - realTest("(G0,';')", -1.0, "-1.;"); - - volatile union { - double d; - std::uint64_t n; - } u; - u.n = 0x8000000000000000; // -0 - realTest("(E9.1,';')", u.d, " -0.0E+00;"); - realTest("(F4.0,';')", u.d, " -0.;"); - realTest("(G8.0,';')", u.d, "-0.0E+00;"); - realTest("(G8.1,';')", u.d, " -0. ;"); - realTest("(G0,';')", u.d, "-0.;"); - u.n = 0x7ff0000000000000; // +Inf - realTest("(E9.1,';')", u.d, " Inf;"); - realTest("(F9.1,';')", u.d, " Inf;"); - realTest("(G9.1,';')", u.d, " Inf;"); - realTest("(SP,E9.1,';')", u.d, " +Inf;"); - realTest("(SP,F9.1,';')", u.d, " +Inf;"); - realTest("(SP,G9.1,';')", u.d, " +Inf;"); - realTest("(G0,';')", u.d, "Inf;"); - u.n = 0xfff0000000000000; // -Inf - realTest("(E9.1,';')", u.d, " -Inf;"); - realTest("(F9.1,';')", u.d, " -Inf;"); - realTest("(G9.1,';')", u.d, " -Inf;"); - realTest("(G0,';')", u.d, "-Inf;"); - u.n = 0x7ff0000000000001; // NaN - realTest("(E9.1,';')", u.d, " NaN;"); - realTest("(F9.1,';')", u.d, " NaN;"); - realTest("(G9.1,';')", u.d, " NaN;"); - realTest("(G0,';')", u.d, "NaN;"); - u.n = 0xfff0000000000001; // NaN (sign irrelevant) - realTest("(E9.1,';')", u.d, " NaN;"); - realTest("(F9.1,';')", u.d, " NaN;"); - realTest("(G9.1,';')", u.d, " NaN;"); - realTest("(SP,E9.1,';')", u.d, " NaN;"); - realTest("(SP,F9.1,';')", u.d, " NaN;"); - realTest("(SP,G9.1,';')", u.d, " NaN;"); - realTest("(G0,';')", u.d, "NaN;"); - - u.n = 0x3fb999999999999a; // 0.1 rounded - realTest("(E62.55,';')", u.d, - " 0.1000000000000000055511151231257827021181583404541015625E+00;"); - realTest("(E0.0,';')", u.d, "0.E+00;"); - realTest("(E0.55,';')", u.d, - "0.1000000000000000055511151231257827021181583404541015625E+00;"); - realTest("(E0,';')", u.d, ".1E+00;"); - realTest("(F58.55,';')", u.d, - " 0.1000000000000000055511151231257827021181583404541015625;"); - realTest("(F0.0,';')", u.d, "0.;"); - realTest("(F0.55,';')", u.d, - ".1000000000000000055511151231257827021181583404541015625;"); - realTest("(F0,';')", u.d, ".1;"); - realTest("(G62.55,';')", u.d, - " 0.1000000000000000055511151231257827021181583404541015625 ;"); - realTest("(G0.0,';')", u.d, "0.;"); - realTest("(G0.55,';')", u.d, - ".1000000000000000055511151231257827021181583404541015625;"); - realTest("(G0,';')", u.d, ".1;"); - - u.n = 0x3ff8000000000000; // 1.5 - realTest("(E9.2,';')", u.d, " 0.15E+01;"); - realTest("(F4.1,';')", u.d, " 1.5;"); - realTest("(G7.1,';')", u.d, " 2. ;"); - realTest("(RN,E8.1,';')", u.d, " 0.2E+01;"); - realTest("(RN,F3.0,';')", u.d, " 2.;"); - realTest("(RN,G7.0,';')", u.d, " 0.E+01;"); - realTest("(RN,G7.1,';')", u.d, " 2. ;"); - realTest("(RD,E8.1,';')", u.d, " 0.1E+01;"); - realTest("(RD,F3.0,';')", u.d, " 1.;"); - realTest("(RD,G7.0,';')", u.d, " 0.E+01;"); - realTest("(RD,G7.1,';')", u.d, " 1. ;"); - realTest("(RU,E8.1,';')", u.d, " 0.2E+01;"); - realTest("(RU,G7.0,';')", u.d, " 0.E+01;"); - realTest("(RU,G7.1,';')", u.d, " 2. ;"); - realTest("(RZ,E8.1,';')", u.d, " 0.1E+01;"); - realTest("(RZ,F3.0,';')", u.d, " 1.;"); - realTest("(RZ,G7.0,';')", u.d, " 0.E+01;"); - realTest("(RZ,G7.1,';')", u.d, " 1. ;"); - realTest("(RC,E8.1,';')", u.d, " 0.2E+01;"); - realTest("(RC,F3.0,';')", u.d, " 2.;"); - realTest("(RC,G7.0,';')", u.d, " 0.E+01;"); - realTest("(RC,G7.1,';')", u.d, " 2. ;"); - - // TODO continue F and G editing tests on these data - - u.n = 0xbff8000000000000; // -1.5 - realTest("(E9.2,';')", u.d, "-0.15E+01;"); - realTest("(RN,E8.1,';')", u.d, "-0.2E+01;"); - realTest("(RD,E8.1,';')", u.d, "-0.2E+01;"); - realTest("(RU,E8.1,';')", u.d, "-0.1E+01;"); - realTest("(RZ,E8.1,';')", u.d, "-0.1E+01;"); - realTest("(RC,E8.1,';')", u.d, "-0.2E+01;"); - - u.n = 0x4004000000000000; // 2.5 - realTest("(E9.2,';')", u.d, " 0.25E+01;"); - realTest("(RN,E8.1,';')", u.d, " 0.2E+01;"); - realTest("(RD,E8.1,';')", u.d, " 0.2E+01;"); - realTest("(RU,E8.1,';')", u.d, " 0.3E+01;"); - realTest("(RZ,E8.1,';')", u.d, " 0.2E+01;"); - realTest("(RC,E8.1,';')", u.d, " 0.3E+01;"); - - u.n = 0xc004000000000000; // -2.5 - realTest("(E9.2,';')", u.d, "-0.25E+01;"); - realTest("(RN,E8.1,';')", u.d, "-0.2E+01;"); - realTest("(RD,E8.1,';')", u.d, "-0.3E+01;"); - realTest("(RU,E8.1,';')", u.d, "-0.2E+01;"); - realTest("(RZ,E8.1,';')", u.d, "-0.2E+01;"); - realTest("(RC,E8.1,';')", u.d, "-0.3E+01;"); - - u.n = 1; // least positive nonzero subnormal - realTest("(E32.17,';')", u.d, " 0.49406564584124654-323;"); - realTest("(ES32.17,';')", u.d, " 4.94065645841246544-324;"); - realTest("(EN32.17,';')", u.d, " 4.94065645841246544-324;"); - realTest("(E759.752,';')", u.d, - " 0." - "494065645841246544176568792868221372365059802614324764425585682500675507" - "270208751865299836361635992379796564695445717730926656710355939796398774" - "796010781878126300713190311404527845817167848982103688718636056998730723" - "050006387409153564984387312473397273169615140031715385398074126238565591" - "171026658556686768187039560310624931945271591492455329305456544401127480" - "129709999541931989409080416563324524757147869014726780159355238611550134" - "803526493472019379026810710749170333222684475333572083243193609238289345" - "836806010601150616980975307834227731832924790498252473077637592724787465" - "608477820373446969953364701797267771758512566055119913150489110145103786" - "273816725095583738973359899366480994116420570263709027924276754456522908" - "75386825064197182655334472656250-323;"); - realTest("(G0,';')", u.d, ".5-323;"); - realTest("(E757.750,';')", u.d, - " 0." - "494065645841246544176568792868221372365059802614324764425585682500675507" - "270208751865299836361635992379796564695445717730926656710355939796398774" - "796010781878126300713190311404527845817167848982103688718636056998730723" - "050006387409153564984387312473397273169615140031715385398074126238565591" - "171026658556686768187039560310624931945271591492455329305456544401127480" - "129709999541931989409080416563324524757147869014726780159355238611550134" - "803526493472019379026810710749170333222684475333572083243193609238289345" - "836806010601150616980975307834227731832924790498252473077637592724787465" - "608477820373446969953364701797267771758512566055119913150489110145103786" - "273816725095583738973359899366480994116420570263709027924276754456522908" - "753868250641971826553344726562-323;"); - realTest("(RN,E757.750,';')", u.d, - " 0." - "494065645841246544176568792868221372365059802614324764425585682500675507" - "270208751865299836361635992379796564695445717730926656710355939796398774" - "796010781878126300713190311404527845817167848982103688718636056998730723" - "050006387409153564984387312473397273169615140031715385398074126238565591" - "171026658556686768187039560310624931945271591492455329305456544401127480" - "129709999541931989409080416563324524757147869014726780159355238611550134" - "803526493472019379026810710749170333222684475333572083243193609238289345" - "836806010601150616980975307834227731832924790498252473077637592724787465" - "608477820373446969953364701797267771758512566055119913150489110145103786" - "273816725095583738973359899366480994116420570263709027924276754456522908" - "753868250641971826553344726562-323;"); - realTest("(RD,E757.750,';')", u.d, - " 0." - "494065645841246544176568792868221372365059802614324764425585682500675507" - "270208751865299836361635992379796564695445717730926656710355939796398774" - "796010781878126300713190311404527845817167848982103688718636056998730723" - "050006387409153564984387312473397273169615140031715385398074126238565591" - "171026658556686768187039560310624931945271591492455329305456544401127480" - "129709999541931989409080416563324524757147869014726780159355238611550134" - "803526493472019379026810710749170333222684475333572083243193609238289345" - "836806010601150616980975307834227731832924790498252473077637592724787465" - "608477820373446969953364701797267771758512566055119913150489110145103786" - "273816725095583738973359899366480994116420570263709027924276754456522908" - "753868250641971826553344726562-323;"); - realTest("(RU,E757.750,';')", u.d, - " 0." - "494065645841246544176568792868221372365059802614324764425585682500675507" - "270208751865299836361635992379796564695445717730926656710355939796398774" - "796010781878126300713190311404527845817167848982103688718636056998730723" - "050006387409153564984387312473397273169615140031715385398074126238565591" - "171026658556686768187039560310624931945271591492455329305456544401127480" - "129709999541931989409080416563324524757147869014726780159355238611550134" - "803526493472019379026810710749170333222684475333572083243193609238289345" - "836806010601150616980975307834227731832924790498252473077637592724787465" - "608477820373446969953364701797267771758512566055119913150489110145103786" - "273816725095583738973359899366480994116420570263709027924276754456522908" - "753868250641971826553344726563-323;"); - realTest("(RC,E757.750,';')", u.d, - " 0." - "494065645841246544176568792868221372365059802614324764425585682500675507" - "270208751865299836361635992379796564695445717730926656710355939796398774" - "796010781878126300713190311404527845817167848982103688718636056998730723" - "050006387409153564984387312473397273169615140031715385398074126238565591" - "171026658556686768187039560310624931945271591492455329305456544401127480" - "129709999541931989409080416563324524757147869014726780159355238611550134" - "803526493472019379026810710749170333222684475333572083243193609238289345" - "836806010601150616980975307834227731832924790498252473077637592724787465" - "608477820373446969953364701797267771758512566055119913150489110145103786" - "273816725095583738973359899366480994116420570263709027924276754456522908" - "753868250641971826553344726563-323;"); - - u.n = 0x10000000000000; // least positive nonzero normal - realTest("(E723.716,';')", u.d, - " 0." - "222507385850720138309023271733240406421921598046233183055332741688720443" - "481391819585428315901251102056406733973103581100515243416155346010885601" - "238537771882113077799353200233047961014744258363607192156504694250373420" - "837525080665061665815894872049117996859163964850063590877011830487479978" - "088775374994945158045160505091539985658247081864511353793580499211598108" - "576605199243335211435239014879569960959128889160299264151106346631339366" - "347758651302937176204732563178148566435087212282863764204484681140761391" - "147706280168985324411002416144742161856716615054015428508471675290190316" - "132277889672970737312333408698898317506783884692609277397797285865965494" - "10913690954061364675687023986783152906809846172109246253967285156250-" - "307;"); - realTest("(G0,';')", u.d, ".22250738585072014-307;"); - - u.n = 0x7fefffffffffffffuLL; // greatest finite - realTest("(E32.17,';')", u.d, " 0.17976931348623157+309;"); - realTest("(E317.310,';')", u.d, - " 0." - "179769313486231570814527423731704356798070567525844996598917476803157260" - "780028538760589558632766878171540458953514382464234321326889464182768467" - "546703537516986049910576551282076245490090389328944075868508455133942304" - "583236903222948165808559332123348274797826204144723168738177180919299881" - "2504040261841248583680+309;"); - realTest("(ES317.310,';')", u.d, - " 1." - "797693134862315708145274237317043567980705675258449965989174768031572607" - "800285387605895586327668781715404589535143824642343213268894641827684675" - "467035375169860499105765512820762454900903893289440758685084551339423045" - "832369032229481658085593321233482747978262041447231687381771809192998812" - "5040402618412485836800+308;"); - realTest("(EN319.310,';')", u.d, - " 179." - "769313486231570814527423731704356798070567525844996598917476803157260780" - "028538760589558632766878171540458953514382464234321326889464182768467546" - "703537516986049910576551282076245490090389328944075868508455133942304583" - "236903222948165808559332123348274797826204144723168738177180919299881250" - "4040261841248583680000+306;"); - realTest("(G0,';')", u.d, ".17976931348623157+309;"); - - realTest("(F5.3,';')", 25., "*****;"); - realTest("(F5.3,';')", 2.5, "2.500;"); - realTest("(F5.3,';')", 0.25, "0.250;"); - realTest("(F5.3,';')", 0.025, "0.025;"); - realTest("(F5.3,';')", 0.0025, "0.003;"); - realTest("(F5.3,';')", 0.00025, "0.000;"); - realTest("(F5.3,';')", 0.000025, "0.000;"); - realTest("(F5.3,';')", -25., "*****;"); - realTest("(F5.3,';')", -2.5, "*****;"); - realTest("(F5.3,';')", -0.25, "-.250;"); - realTest("(F5.3,';')", -0.025, "-.025;"); - realTest("(F5.3,';')", -0.0025, "-.003;"); - realTest("(F5.3,';')", -0.00025, "-.000;"); - realTest("(F5.3,';')", -0.000025, "-.000;"); - - realInTest("(F18.0)", " 0", 0x0); - realInTest("(F18.0)", " ", 0x0); - realInTest("(F18.0)", " -0", 0x8000000000000000); - realInTest("(F18.0)", " 01", 0x3ff0000000000000); - realInTest("(F18.0)", " 1", 0x3ff0000000000000); - realInTest("(F18.0)", " 125.", 0x405f400000000000); - realInTest("(F18.0)", " 12.5", 0x4029000000000000); - realInTest("(F18.0)", " 1.25", 0x3ff4000000000000); - realInTest("(F18.0)", " 01.25", 0x3ff4000000000000); - realInTest("(F18.0)", " .125", 0x3fc0000000000000); - realInTest("(F18.0)", " 0.125", 0x3fc0000000000000); - realInTest("(F18.0)", " .0625", 0x3fb0000000000000); - realInTest("(F18.0)", " 0.0625", 0x3fb0000000000000); - realInTest("(F18.0)", " 125", 0x405f400000000000); - realInTest("(F18.1)", " 125", 0x4029000000000000); - realInTest("(F18.2)", " 125", 0x3ff4000000000000); - realInTest("(F18.3)", " 125", 0x3fc0000000000000); - realInTest("(-1P,F18.0)", " 125", 0x4093880000000000); // 1250 - realInTest("(1P,F18.0)", " 125", 0x4029000000000000); // 12.5 - realInTest("(BZ,F18.0)", " 125 ", 0x4093880000000000); // 1250 - realInTest("(BZ,F18.0)", " 125 . e +1 ", 0x42a6bcc41e900000); // 1.25e13 - realInTest("(DC,F18.0)", " 12,5", 0x4029000000000000); - - listInputTest(); - descrOutputTest(); - - return EndTests(); -} diff --git a/flang/unittests/RuntimeGTest/CMakeLists.txt b/flang/unittests/RuntimeGTest/CMakeLists.txt index 77aff3069f14..d4ad6b2e1520 100644 --- a/flang/unittests/RuntimeGTest/CMakeLists.txt +++ b/flang/unittests/RuntimeGTest/CMakeLists.txt @@ -1,5 +1,10 @@ add_flang_unittest(FlangRuntimeTests CharacterTest.cpp + RuntimeCrashTest.cpp + CrashHandlerFixture.cpp + NumericalFormatTest.cpp + RuntimeCrashTest.cpp + CrashHandlerFixture.cpp ) target_link_libraries(FlangRuntimeTests diff --git a/flang/unittests/RuntimeGTest/CharacterTest.cpp b/flang/unittests/RuntimeGTest/CharacterTest.cpp index a025429035f8..6afba32e33e3 100644 --- a/flang/unittests/RuntimeGTest/CharacterTest.cpp +++ b/flang/unittests/RuntimeGTest/CharacterTest.cpp @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +// Basic sanity tests of CHARACTER API; exhaustive testing will be done +// in Fortran. + #include "../../runtime/character.h" #include "gtest/gtest.h" #include @@ -136,147 +139,86 @@ TYPED_TEST(CharacterComparisonTests, CompareCharacters) { } } -//------------------------------------------------------------------------------ -/// Tests and infrastructure for Scan functions -//------------------------------------------------------------------------------ +// Test search functions INDEX(), SCAN(), and VERIFY() template -using ScanFuncTy = std::function; - -using ScanFuncsTy = - std::tuple, ScanFuncTy, ScanFuncTy>; - -// These functions are the systems under test in CharacterScanTests test cases. -static ScanFuncsTy scanFuncs{ - RTNAME(Scan1), - RTNAME(Scan2), - RTNAME(Scan4), +template