diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml index 1a26a699db8e0..b5e60781e0006 100644 --- a/.github/workflows/libcxx-build-and-test.yaml +++ b/.github/workflows/libcxx-build-and-test.yaml @@ -242,6 +242,7 @@ jobs: - { config: mingw-dll, mingw: true } - { config: mingw-static, mingw: true } - { config: mingw-dll-i686, mingw: true } + - { config: mingw-incomplete-sysroot, mingw: true } steps: - uses: actions/checkout@v4 - name: Install dependencies @@ -260,6 +261,12 @@ jobs: del llvm-mingw*.zip mv llvm-mingw* c:\llvm-mingw echo "c:\llvm-mingw\bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append + - name: Simulate a from-scratch build of llvm-mingw + if: ${{ matrix.config == 'mingw-incomplete-sysroot' }} + run: | + rm -r c:\llvm-mingw\include\c++ + rm -r c:\llvm-mingw\*-w64-mingw32\lib\libc++* + rm -r c:\llvm-mingw\*-w64-mingw32\lib\libunwind* - name: Add Git Bash to the path run: | echo "c:\Program Files\Git\usr\bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append diff --git a/clang-tools-extra/clang-tidy/add_new_check.py b/clang-tools-extra/clang-tidy/add_new_check.py index bd69bddcc6825..d384dbae28abb 100755 --- a/clang-tools-extra/clang-tidy/add_new_check.py +++ b/clang-tools-extra/clang-tidy/add_new_check.py @@ -8,9 +8,6 @@ # # ===-----------------------------------------------------------------------===# -from __future__ import print_function -from __future__ import unicode_literals - import argparse import io import itertools @@ -19,10 +16,13 @@ import sys import textwrap +# FIXME Python 3.9: Replace typing.Tuple with builtins.tuple. +from typing import Optional, Tuple + # Adapts the module's CMakelist file. Returns 'True' if it could add a new # entry and 'False' if the entry already existed. -def adapt_cmake(module_path, check_name_camel): +def adapt_cmake(module_path: str, check_name_camel: str) -> bool: filename = os.path.join(module_path, "CMakeLists.txt") # The documentation files are encoded using UTF-8, however on Windows the @@ -57,14 +57,14 @@ def adapt_cmake(module_path, check_name_camel): # Adds a header for the new check. def write_header( - module_path, - module, - namespace, - check_name, - check_name_camel, - description, - lang_restrict, -): + module_path: str, + module: str, + namespace: str, + check_name: str, + check_name_camel: str, + description: str, + lang_restrict: str, +) -> None: wrapped_desc = "\n".join( textwrap.wrap( description, width=80, initial_indent="/// ", subsequent_indent="/// " @@ -139,7 +139,9 @@ class %(check_name_camel)s : public ClangTidyCheck { # Adds the implementation of the new check. -def write_implementation(module_path, module, namespace, check_name_camel): +def write_implementation( + module_path: str, module: str, namespace: str, check_name_camel: str +) -> None: filename = os.path.join(module_path, check_name_camel) + ".cpp" print("Creating %s..." % filename) with io.open(filename, "w", encoding="utf8", newline="\n") as f: @@ -187,7 +189,7 @@ def write_implementation(module_path, module, namespace, check_name_camel): # Returns the source filename that implements the module. -def get_module_filename(module_path, module): +def get_module_filename(module_path: str, module: str) -> str: modulecpp = list( filter( lambda p: p.lower() == module.lower() + "tidymodule.cpp", @@ -198,7 +200,9 @@ def get_module_filename(module_path, module): # Modifies the module to include the new check. -def adapt_module(module_path, module, check_name, check_name_camel): +def adapt_module( + module_path: str, module: str, check_name: str, check_name_camel: str +) -> None: filename = get_module_filename(module_path, module) with io.open(filename, "r", encoding="utf8") as f: lines = f.readlines() @@ -217,10 +221,10 @@ def adapt_module(module_path, module, check_name, check_name_camel): + '");\n' ) - lines = iter(lines) + lines_iter = iter(lines) try: while True: - line = next(lines) + line = next(lines_iter) if not header_added: match = re.search('#include "(.*)"', line) if match: @@ -247,10 +251,11 @@ def adapt_module(module_path, module, check_name, check_name_camel): # If we didn't find the check name on this line, look on the # next one. prev_line = line - line = next(lines) + line = next(lines_iter) match = re.search(' *"([^"]*)"', line) if match: current_check_name = match.group(1) + assert current_check_name if current_check_name > check_fq_name: check_added = True f.write(check_decl) @@ -262,7 +267,9 @@ def adapt_module(module_path, module, check_name, check_name_camel): # Adds a release notes entry. -def add_release_notes(module_path, module, check_name, description): +def add_release_notes( + module_path: str, module: str, check_name: str, description: str +) -> None: wrapped_desc = "\n".join( textwrap.wrap( description, width=80, initial_indent=" ", subsequent_indent=" " @@ -324,9 +331,14 @@ def add_release_notes(module_path, module, check_name, description): # Adds a test for the check. -def write_test(module_path, module, check_name, test_extension, test_standard): - if test_standard: - test_standard = f"-std={test_standard}-or-later " +def write_test( + module_path: str, + module: str, + check_name: str, + test_extension: str, + test_standard: Optional[str], +) -> None: + test_standard = f"-std={test_standard}-or-later " if test_standard else "" check_name_dashes = module + "-" + check_name filename = os.path.normpath( os.path.join( @@ -362,7 +374,7 @@ def write_test(module_path, module, check_name, test_extension, test_standard): ) -def get_actual_filename(dirname, filename): +def get_actual_filename(dirname: str, filename: str) -> str: if not os.path.isdir(dirname): return "" name = os.path.join(dirname, filename) @@ -376,7 +388,7 @@ def get_actual_filename(dirname, filename): # Recreates the list of checks in the docs/clang-tidy/checks directory. -def update_checks_list(clang_tidy_path): +def update_checks_list(clang_tidy_path: str) -> None: docs_dir = os.path.join(clang_tidy_path, "../docs/clang-tidy/checks") filename = os.path.normpath(os.path.join(docs_dir, "list.rst")) # Read the content of the current list.rst file @@ -390,12 +402,12 @@ def update_checks_list(clang_tidy_path): for file in filter( lambda s: s.endswith(".rst"), os.listdir(os.path.join(docs_dir, subdir)) ): - doc_files.append([subdir, file]) + doc_files.append((subdir, file)) doc_files.sort() # We couldn't find the source file from the check name, so try to find the # class name that corresponds to the check in the module file. - def filename_from_module(module_name, check_name): + def filename_from_module(module_name: str, check_name: str) -> str: module_path = os.path.join(clang_tidy_path, module_name) if not os.path.isdir(module_path): return "" @@ -433,7 +445,7 @@ def filename_from_module(module_name, check_name): return "" # Examine code looking for a c'tor definition to get the base class name. - def get_base_class(code, check_file): + def get_base_class(code: str, check_file: str) -> str: check_class_name = os.path.splitext(os.path.basename(check_file))[0] ctor_pattern = check_class_name + r"\([^:]*\)\s*:\s*([A-Z][A-Za-z0-9]*Check)\(" matches = re.search(r"\s+" + check_class_name + "::" + ctor_pattern, code) @@ -452,7 +464,7 @@ def get_base_class(code, check_file): return "" # Some simple heuristics to figure out if a check has an autofix or not. - def has_fixits(code): + def has_fixits(code: str) -> bool: for needle in [ "FixItHint", "ReplacementText", @@ -464,7 +476,7 @@ def has_fixits(code): return False # Try to figure out of the check supports fixits. - def has_auto_fix(check_name): + def has_auto_fix(check_name: str) -> str: dirname, _, check_name = check_name.partition("-") check_file = get_actual_filename( @@ -499,7 +511,7 @@ def has_auto_fix(check_name): return "" - def process_doc(doc_file): + def process_doc(doc_file: Tuple[str, str]) -> Tuple[str, Optional[re.Match[str]]]: check_name = doc_file[0] + "-" + doc_file[1].replace(".rst", "") with io.open(os.path.join(docs_dir, *doc_file), "r", encoding="utf8") as doc: @@ -508,13 +520,13 @@ def process_doc(doc_file): if match: # Orphan page, don't list it. - return "", "" + return "", None match = re.search(r".*:http-equiv=refresh: \d+;URL=(.*).html(.*)", content) # Is it a redirect? return check_name, match - def format_link(doc_file): + def format_link(doc_file: Tuple[str, str]) -> str: check_name, match = process_doc(doc_file) if not match and check_name and not check_name.startswith("clang-analyzer-"): return " :doc:`%(check_name)s <%(module)s/%(check)s>`,%(autofix)s\n" % { @@ -526,7 +538,7 @@ def format_link(doc_file): else: return "" - def format_link_alias(doc_file): + def format_link_alias(doc_file: Tuple[str, str]) -> str: check_name, match = process_doc(doc_file) if (match or (check_name.startswith("clang-analyzer-"))) and check_name: module = doc_file[0] @@ -543,6 +555,7 @@ def format_link_alias(doc_file): ref_end = "_" else: redirect_parts = re.search(r"^\.\./([^/]*)/([^/]*)$", match.group(1)) + assert redirect_parts title = redirect_parts[1] + "-" + redirect_parts[2] target = redirect_parts[1] + "/" + redirect_parts[2] autofix = has_auto_fix(title) @@ -599,7 +612,7 @@ def format_link_alias(doc_file): # Adds a documentation for the check. -def write_docs(module_path, module, check_name): +def write_docs(module_path: str, module: str, check_name: str) -> None: check_name_dashes = module + "-" + check_name filename = os.path.normpath( os.path.join( @@ -623,15 +636,15 @@ def write_docs(module_path, module, check_name): ) -def get_camel_name(check_name): +def get_camel_name(check_name: str) -> str: return "".join(map(lambda elem: elem.capitalize(), check_name.split("-"))) -def get_camel_check_name(check_name): +def get_camel_check_name(check_name: str) -> str: return get_camel_name(check_name) + "Check" -def main(): +def main() -> None: language_to_extension = { "c": "c", "c++": "cpp", @@ -756,6 +769,8 @@ def main(): ) elif language in ["objc", "objc++"]: language_restrict = "%(lang)s.ObjC" + else: + raise ValueError(f"Unsupported language '{language}' was specified") write_header( module_path, @@ -769,7 +784,7 @@ def main(): write_implementation(module_path, module, namespace, check_name_camel) adapt_module(module_path, module, check_name, check_name_camel) add_release_notes(module_path, module, check_name, description) - test_extension = language_to_extension.get(language) + test_extension = language_to_extension[language] write_test(module_path, module, check_name, test_extension, args.standard) write_docs(module_path, module, check_name) update_checks_list(clang_tidy_path) diff --git a/clang-tools-extra/clang-tidy/bugprone/CastingThroughVoidCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CastingThroughVoidCheck.cpp index 9e714b4be4dfe..f0a9ace229740 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CastingThroughVoidCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CastingThroughVoidCheck.cpp @@ -38,7 +38,9 @@ void CastingThroughVoidCheck::check(const MatchFinder::MatchResult &Result) { const auto ST = *Result.Nodes.getNodeAs("source_type"); const auto VT = *Result.Nodes.getNodeAs("void_type"); const auto *CE = Result.Nodes.getNodeAs("cast"); - diag(CE->getExprLoc(), "do not cast %0 to %1 through %2") << ST << TT << VT; + diag(CE->getExprLoc(), + "do not cast %0 to %1 through %2; use reinterpret_cast instead") + << ST << TT << VT; } } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp index 5f046c502eb38..e516b71088425 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp @@ -67,9 +67,7 @@ static bool canAdvanceAssignment(AssignedLevel Level) { static void updateAssignmentLevel( const FieldDecl *Field, const Expr *Init, const CXXConstructorDecl *Ctor, llvm::DenseMap &AssignedFields) { - auto It = AssignedFields.find(Field); - if (It == AssignedFields.end()) - It = AssignedFields.insert({Field, AssignedLevel::None}).first; + auto It = AssignedFields.try_emplace(Field, AssignedLevel::None).first; if (!canAdvanceAssignment(It->second)) // fast path for already decided field. diff --git a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp index 42c4b6edb6d20..afc4897eeb2ae 100644 --- a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp @@ -14,6 +14,16 @@ using namespace clang::ast_matchers; namespace clang::tidy::misc { +namespace { + +AST_MATCHER_P(CXXMethodDecl, firstParameter, + ast_matchers::internal::Matcher, InnerMatcher) { + unsigned N = Node.isExplicitObjectMemberFunction() ? 1 : 0; + return (N < Node.parameters().size() && + InnerMatcher.matches(*Node.parameters()[N], Finder, Builder)); +} +} // namespace + void UnconventionalAssignOperatorCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { const auto HasGoodReturnType = @@ -29,7 +39,7 @@ void UnconventionalAssignOperatorCheck::registerMatchers( hasName("operator="), ofClass(recordDecl().bind("class"))) .bind("method"); const auto IsSelfAssign = - cxxMethodDecl(IsAssign, hasParameter(0, parmVarDecl(hasType(IsSelf)))) + cxxMethodDecl(IsAssign, firstParameter(parmVarDecl(hasType(IsSelf)))) .bind("method"); Finder->addMatcher( @@ -41,8 +51,7 @@ void UnconventionalAssignOperatorCheck::registerMatchers( rValueReferenceType(pointee(isConstQualified())))))); Finder->addMatcher( - cxxMethodDecl(IsSelfAssign, - hasParameter(0, parmVarDecl(hasType(BadSelf)))) + cxxMethodDecl(IsSelfAssign, firstParameter(parmVarDecl(hasType(BadSelf)))) .bind("ArgumentType"), this); diff --git a/clang-tools-extra/clangd/Feature.cpp b/clang-tools-extra/clangd/Feature.cpp index 859618a7470ac..ec707a33f656b 100644 --- a/clang-tools-extra/clangd/Feature.cpp +++ b/clang-tools-extra/clangd/Feature.cpp @@ -8,6 +8,7 @@ #include "Feature.h" #include "clang/Basic/Version.h" +#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX #include "llvm/Support/Compiler.h" #include "llvm/TargetParser/Host.h" diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp index c324643498d94..643b8e9f12d75 100644 --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX #include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" #include "llvm/Support/Path.h" diff --git a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp index b64dd4acad4c2..2ce2975bd962b 100644 --- a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp +++ b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" diff --git a/clang-tools-extra/clangd/unittests/SerializationTests.cpp b/clang-tools-extra/clangd/unittests/SerializationTests.cpp index 35a2e2ba77a65..2a7a6c36d3d17 100644 --- a/clang-tools-extra/clangd/unittests/SerializationTests.cpp +++ b/clang-tools-extra/clangd/unittests/SerializationTests.cpp @@ -12,6 +12,7 @@ #include "support/Logger.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX #include "llvm/Support/Compression.h" #include "llvm/Support/Error.h" #include "llvm/Support/ScopedPrinter.h" diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index b001a6ad44669..8d028f8863cb7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -104,10 +104,18 @@ New check aliases Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Improved :doc:`bugprone-casting-through-void + ` check to suggest replacing + the offending code with ``reinterpret_cast``, to more clearly express intent. + - Improved :doc:`modernize-use-std-format ` check to support replacing member function calls too. +- Improved :doc:`misc-unconventional-assign-operator + ` check to avoid + false positive for C++23 deducing this. + - Improved :doc:`modernize-use-std-print ` check to support replacing member function calls too. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/casting-through-void.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/casting-through-void.rst index a9ab478b9a82e..d9f94b6a3f20b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/casting-through-void.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/casting-through-void.rst @@ -3,7 +3,9 @@ bugprone-casting-through-void ============================= -Detects unsafe or redundant two-step casting operations involving ``void*``. +Detects unsafe or redundant two-step casting operations involving ``void*``, +which is equivalent to ``reinterpret_cast`` as per the +`C++ Standard `_. Two-step type conversions via ``void*`` are discouraged for several reasons. @@ -16,7 +18,17 @@ Two-step type conversions via ``void*`` are discouraged for several reasons. In summary, avoiding two-step type conversions through ``void*`` ensures clearer code, maintains essential compiler warnings, and prevents ambiguity and potential runtime -errors, particularly in complex inheritance scenarios. +errors, particularly in complex inheritance scenarios. If such a cast is wanted, +it shall be done via ``reinterpret_cast``, to express the intent more clearly. + +Note: it is expected that, after applying the suggested fix and using +``reinterpret_cast``, the check :doc:`cppcoreguidelines-pro-type-reinterpret-cast +<../cppcoreguidelines/pro-type-reinterpret-cast>` will emit a warning. +This is intentional: ``reinterpret_cast`` is a dangerous operation that can +easily break the strict aliasing rules when dereferencing the casted pointer, +invoking Undefined Behavior. The warning is there to prompt users to carefuly +analyze whether the usage of ``reinterpret_cast`` is safe, in which case the +warning may be suppressed. Examples: @@ -29,3 +41,8 @@ Examples: reinterpret_cast(reinterpret_cast(ptr)); // WRONG (IntegerPointer)(void *)ptr; // WRONG IntegerPointer(static_cast(ptr)); // WRONG + + reinterpret_cast(ptr); // OK, clearly expresses intent. + // NOTE: dereferencing this pointer violates + // the strict aliasing rules, invoking + // Undefined Behavior. diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst index 86fba6c7e4f7c..8ac1ad56bc8cf 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst @@ -7,8 +7,7 @@ This check implements detection of local variables which could be declared as ``const`` but are not. Declaring variables as ``const`` is required or recommended by many coding guidelines, such as: `ES.25 `_ -from the C++ Core Guidelines and `AUTOSAR C++14 Rule A7-1-1 (6.7.1 Specifiers) -`_. +from the C++ Core Guidelines. Please note that this check's analysis is type-based only. Variables that are not modified but used to create a non-const handle that might escape the scope are not diagnosed diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/unconventional-assign-operator.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/unconventional-assign-operator.rst index 3b4b65a5cb683..49e3fd5b6ee42 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/unconventional-assign-operator.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/unconventional-assign-operator.rst @@ -13,6 +13,3 @@ types and definitions with good return type but wrong ``return`` statements. type (e.g. ``int``). * Private and deleted operators are ignored. * The operator must always return ``*this``. - -This check implements `AUTOSAR C++14 Rule A13-2-1 -`_. diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/avoid-nested-conditional-operator.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/avoid-nested-conditional-operator.rst index 44b74283292ce..cd3906855d497 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/avoid-nested-conditional-operator.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/avoid-nested-conditional-operator.rst @@ -16,6 +16,3 @@ Examples: int NestInConditional = (condition1 ? true1 : false1) ? true2 : false2; int NestInTrue = condition1 ? (condition2 ? true1 : false1) : false2; int NestInFalse = condition1 ? true1 : condition2 ? true2 : false1; - -This check implements part of `AUTOSAR C++14 Rule A5-16-1 -`_. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/casting-through-void.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/casting-through-void.cpp index a784e49885873..68172212904f8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/casting-through-void.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/casting-through-void.cpp @@ -10,42 +10,42 @@ const double cd = 100; void normal_test() { static_cast(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'V' (aka 'void *') [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'V' (aka 'void *'); use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&i)); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'int *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'int *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&i)); } void const_pointer_test() { static_cast(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *const' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *const' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *const' through 'V' (aka 'void *') [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *const' through 'V' (aka 'void *'); use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&i)); - // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'int *' to 'int *const' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'int *' to 'int *const' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&i)); } void const_test() { static_cast(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'double *' to 'const int *' through 'const void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'double *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'double *' to 'const int *' through 'const V' (aka 'void *const') [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'double *' to 'const int *' through 'const V' (aka 'void *const'); use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&i)); - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'int *' to 'const int *' through 'const void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'int *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&i)); static_cast(static_cast(&cd)); - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const double *' to 'const int *' through 'const void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const double *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&cd)); - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const double *' to 'const int *' through 'const CV' (aka 'const void *const') [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const double *' to 'const int *' through 'const CV' (aka 'const void *const'); use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&ci)); - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const int *' to 'const int *' through 'const void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const int *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(static_cast(&ci)); } @@ -53,11 +53,11 @@ void const_test() { void reinterpret_cast_test() { static_cast(reinterpret_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] reinterpret_cast(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] reinterpret_cast(reinterpret_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast(reinterpret_cast(&i)); reinterpret_cast(reinterpret_cast(&i)); @@ -66,11 +66,11 @@ void reinterpret_cast_test() { void c_style_cast_test() { static_cast((void *)&d); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] (int *)(void *)&d; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast((void *)&d); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] static_cast((void *)&i); } @@ -82,12 +82,12 @@ using I = int *; void cxx_functional_cast() { A(static_cast(&d)); I(static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not cast 'double *' to 'I' (aka 'int *') through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not cast 'double *' to 'I' (aka 'int *') through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] } void bit_cast() { __builtin_bit_cast(int *, static_cast(&d)); - // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not cast 'double *' to 'int *' through 'void *' [bugprone-casting-through-void] + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void] } namespace PR87069 { diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/unconventional-assign-operator-cxx23.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/unconventional-assign-operator-cxx23.cpp new file mode 100644 index 0000000000000..d947df164be86 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/unconventional-assign-operator-cxx23.cpp @@ -0,0 +1,10 @@ +// RUN: %check_clang_tidy -std=c++23 %s misc-unconventional-assign-operator %t + +struct BadArgument { + BadArgument &operator=(this BadArgument& self, BadArgument &); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument' +}; + +struct GoodArgument { + GoodArgument &operator=(this GoodArgument& self, GoodArgument const &); +}; diff --git a/clang/cmake/caches/Release.cmake b/clang/cmake/caches/Release.cmake index 6d5f75ca0074e..c93ff40ff3ee4 100644 --- a/clang/cmake/caches/Release.cmake +++ b/clang/cmake/caches/Release.cmake @@ -55,14 +55,22 @@ set(STAGE1_RUNTIMES "compiler-rt") if (LLVM_RELEASE_ENABLE_PGO) list(APPEND STAGE1_PROJECTS "lld") - set(CLANG_BOOTSTRAP_TARGETS + set(tmp_targets generate-profdata stage2-package stage2-clang + stage2 stage2-install stage2-check-all stage2-check-llvm - stage2-check-clang CACHE STRING "") + stage2-check-clang) + + foreach(X IN LISTS LLVM_RELEASE_FINAL_STAGE_TARGETS) + list(APPEND tmp_targets "stage2-${X}") + endforeach() + list(REMOVE_DUPLICATES tmp_targets) + + set(CLANG_BOOTSTRAP_TARGETS "${tmp_targets}" CACHE STRING "") # Configuration for stage2-instrumented set(BOOTSTRAP_CLANG_ENABLE_BOOTSTRAP ON CACHE STRING "") diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 62903fc3744ca..c08697282cbfe 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1483,6 +1483,7 @@ Generic lambda expressions __cpp_generic_lambdas C+ variable templates __cpp_variable_templates C++14 C++03 Binary literals __cpp_binary_literals C++14 C++03 Relaxed constexpr __cpp_constexpr C++14 C++11 +Static assert with no message __cpp_static_assert >= 201411L C++17 C++11 Pack expansion in generalized lambda-capture __cpp_init_captures C++17 C++03 ``if constexpr`` __cpp_if_constexpr C++17 C++11 fold expressions __cpp_fold_expressions C++17 C++03 @@ -1503,6 +1504,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+ ``static operator()`` __cpp_static_call_operator C++23 C++03 Attributes on Lambda-Expressions C++23 C++11 Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03 +Static assert with user-generated message __cpp_static_assert >= 202306L C++26 C++11 Pack Indexing __cpp_pack_indexing C++26 C++03 ``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03 Variadic Friends __cpp_variadic_friend C++26 C++03 diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0eee71d00a2c5..684484ccd298f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -109,6 +109,9 @@ C++ Language Changes constant expression. Supports the `V.xyzw` syntax and other tidbits as seen in OpenCL. Selecting multiple elements is left as a future work. +- Accept C++26 user-defined ``static_assert`` messages in C++11 as an extension. + + C++2c Feature Support ^^^^^^^^^^^^^^^^^^^^^ @@ -122,6 +125,9 @@ C++2c Feature Support - Implemented `P2747R2 constexpr placement new `_. +- Added the ``__builtin_is_within_lifetime`` builtin, which supports + `P2641R4 Checking if a union alternative is active `_ + C++23 Feature Support ^^^^^^^^^^^^^^^^^^^^^ - Removed the restriction to literal types in constexpr functions in C++23 mode. @@ -154,6 +160,10 @@ Resolutions to C++ Defect Reports - Allow ``void{}`` as a prvalue of type ``void``. (`CWG2351: void{} `_). +- Clang now allows comparing unequal object pointers that have been cast to ``void *`` + in constant expressions. These comparisons always worked in non-constant expressions. + (`CWG2749: Treatment of "pointer to void" for relational comparisons `_). + C Language Changes ------------------ @@ -225,6 +235,11 @@ Attribute Changes in Clang more cases where the returned reference outlives the object. (#GH100567) +- Clang now correctly diagnoses the use of ``btf_type_tag`` in C++ and ignores + it; this attribute is a C-only attribute, and caused crashes with template + instantiation by accidentally allowing it in C++ in some circumstances. + (#GH106864) + Improvements to Clang's diagnostics ----------------------------------- @@ -268,6 +283,15 @@ Improvements to Clang's diagnostics - Improved diagnostic when trying to overload a function in an ``extern "C"`` context. (#GH80235) +- Clang now respects lifetimebound attribute for the assignment operator parameter. (#GH106372). + +- The lifetimebound and GSL analysis in clang are coherent, allowing clang to + detect more use-after-free bugs. (#GH100549). + +- Clang now diagnoses dangling cases where a gsl-pointer is constructed from a gsl-owner object inside a container (#GH100384). + +- Clang now warns for u8 character literals used in C23 with ``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``. + Improvements to Clang's time-trace ---------------------------------- @@ -342,6 +366,12 @@ Bug Fixes to C++ Support specialization right before its declaration context. (#GH64082) - Fixed a constraint comparison bug for friend declarations. (#GH78101) - Fix handling of ``_`` as the name of a lambda's init capture variable. (#GH107024) +- Fix an issue with dependent source location expressions (#GH106428), (#GH81155), (#GH80210), (#GH85373) +- Fixed a bug in the substitution of empty pack indexing types. (#GH105903) +- Clang no longer tries to capture non-odr used default arguments of template parameters of generic lambdas (#GH107048) +- Fixed a bug where defaulted comparison operators would remove ``const`` from base classes. (#GH102588) + +- Fix a crash when using ``source_location`` in the trailing return type of a lambda expression. (#GH67134) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def index cdf0804680ad0..6620840df0ced 100644 --- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def @@ -249,4 +249,8 @@ FIELD(HasDeclaredCopyAssignmentWithConstParam, 1, MERGE_OR) /// base classes or fields have a no-return destructor FIELD(IsAnyDestructorNoReturn, 1, NO_MERGE) +/// Whether the record type is intangible (if any base classes or fields have +/// type that is intangible). HLSL only. +FIELD(IsHLSLIntangible, 1, NO_MERGE) + #undef FIELD diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 0d72cc6a08dcb..252e6e9256414 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1547,6 +1547,10 @@ class CXXRecordDecl : public RecordDecl { /// destructors are marked noreturn. bool isAnyDestructorNoReturn() const { return data().IsAnyDestructorNoReturn; } + /// Returns true if the class contains HLSL intangible type, either as + /// a field or in base class. + bool isHLSLIntangible() const { return data().IsHLSLIntangible; } + /// If the class is a local class [class.local], returns /// the enclosing function declaration. const FunctionDecl *isLocalClass() const { diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 08f7638d7d8f9..ef36a73716454 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2658,6 +2658,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) bool is##Id##Type() const; #include "clang/Basic/HLSLIntangibleTypes.def" bool isHLSLSpecificType() const; // Any HLSL specific type + bool isHLSLIntangibleType() const; // Any HLSL intangible type /// Determines if this type, which must satisfy /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather @@ -5828,12 +5829,15 @@ class PackIndexingType final QualType Pattern; Expr *IndexExpr; - unsigned Size; + unsigned Size : 31; + + LLVM_PREFERRED_TYPE(bool) + unsigned ExpandsToEmptyPack : 1; protected: friend class ASTContext; // ASTContext creates these. PackIndexingType(const ASTContext &Context, QualType Canonical, - QualType Pattern, Expr *IndexExpr, + QualType Pattern, Expr *IndexExpr, bool ExpandsToEmptyPack, ArrayRef Expansions = {}); public: @@ -5857,6 +5861,8 @@ class PackIndexingType final bool hasSelectedType() const { return getSelectedIndex() != std::nullopt; } + bool expandsToEmptyPack() const { return ExpandsToEmptyPack; } + ArrayRef getExpansions() const { return {getExpansionsPtr(), Size}; } @@ -5869,10 +5875,10 @@ class PackIndexingType final if (hasSelectedType()) getSelectedType().Profile(ID); else - Profile(ID, Context, getPattern(), getIndexExpr()); + Profile(ID, Context, getPattern(), getIndexExpr(), expandsToEmptyPack()); } static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, - QualType Pattern, Expr *E); + QualType Pattern, Expr *E, bool ExpandsToEmptyPack); private: const QualType *getExpansionsPtr() const { @@ -8336,6 +8342,12 @@ inline bool Type::isHLSLSpecificType() const { false; // end boolean or operation } +inline bool Type::isHLSLIntangibleType() const { + // All HLSL specific types are currently intangible type as well, but that + // might change in the future. + return isHLSLSpecificType(); +} + inline bool Type::isTemplateTypeParmType() const { return isa(CanonicalType); } diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 5db39eb3aefa7..03fbdcf60140d 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -951,12 +951,20 @@ class HLSLAttributedResourceTypeLoc HLSLAttributedResourceLocInfo> { public: TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); } + + TypeLoc getContainedLoc() const { + return TypeLoc(getTypePtr()->getContainedType(), getNonLocalData()); + } + void setSourceRange(const SourceRange &R) { getLocalData()->Range = R; } SourceRange getLocalSourceRange() const { return getLocalData()->Range; } void initializeLocal(ASTContext &Context, SourceLocation loc) { setSourceRange(SourceRange()); } QualType getInnerType() const { return getTypePtr()->getWrappedType(); } + unsigned getLocalDataSize() const { + return sizeof(HLSLAttributedResourceLocInfo); + } }; struct ObjCObjectTypeLocInfo { diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index 3df19315fd573..539a344cb0b69 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -473,9 +473,12 @@ let Class = PackIndexingType in { def : Property<"indexExpression", ExprRef> { let Read = [{ node->getIndexExpr() }]; } + def : Property<"expandsToEmptyPack", Bool> { + let Read = [{ node->expandsToEmptyPack() }]; + } def : Creator<[{ - return ctx.getPackIndexingType(pattern, indexExpression); + return ctx.getPackIndexingType(pattern, indexExpression, expandsToEmptyPack); }]>; } diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h index 228b4ae1e3e11..267cde64f8f23 100644 --- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h +++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H #include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" #include "clang/AST/Stmt.h" #include "clang/Basic/SourceLocation.h" #include "llvm/Support/Debug.h" @@ -106,6 +107,20 @@ class UnsafeBufferUsageHandler { virtual void handleUnsafeOperation(const Stmt *Operation, bool IsRelatedToDecl, ASTContext &Ctx) = 0; + /// Invoked when a call to an unsafe libc function is found. + /// \param PrintfInfo + /// is 0 if the callee function is not a member of the printf family; + /// is 1 if the callee is `sprintf`; + /// is 2 if arguments of the call have `__size_by` relation but are not in a + /// safe pattern; + /// is 3 if string arguments do not guarantee null-termination + /// is 4 if the callee takes va_list + /// \param UnsafeArg one of the actual arguments that is unsafe, non-null + /// only when `2 <= PrintfInfo <= 3` + virtual void handleUnsafeLibcCall(const CallExpr *Call, unsigned PrintfInfo, + ASTContext &Ctx, + const Expr *UnsafeArg = nullptr) = 0; + /// Invoked when an unsafe operation with a std container is found. virtual void handleUnsafeOperationInContainer(const Stmt *Operation, bool IsRelatedToDecl, @@ -151,6 +166,10 @@ class UnsafeBufferUsageHandler { virtual bool ignoreUnsafeBufferInContainer(const SourceLocation &Loc) const = 0; + /// \return true iff unsafe libc call should NOT be reported at `Loc` + virtual bool + ignoreUnsafeBufferInLibcCall(const SourceLocation &Loc) const = 0; + virtual std::string getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc, StringRef WSSuffix = "") const = 0; diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def index 242ad763ba62b..09fa510bc0472 100644 --- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def +++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def @@ -18,10 +18,10 @@ #define WARNING_GADGET(name) GADGET(name) #endif -/// A `WARNING_GADGET` subset, where the code pattern of each gadget -/// corresponds uses of a (possibly hardened) contatiner (e.g., `std::span`). -#ifndef WARNING_CONTAINER_GADGET -#define WARNING_CONTAINER_GADGET(name) WARNING_GADGET(name) +/// A `WARNING_GADGET` subset, each of which may be enable/disable separately +/// with different flags +#ifndef WARNING_OPTIONAL_GADGET +#define WARNING_OPTIONAL_GADGET(name) WARNING_GADGET(name) #endif /// Safe gadgets correspond to code patterns that aren't unsafe but need to be @@ -38,7 +38,8 @@ WARNING_GADGET(PointerArithmetic) WARNING_GADGET(UnsafeBufferUsageAttr) WARNING_GADGET(UnsafeBufferUsageCtorAttr) WARNING_GADGET(DataInvocation) -WARNING_CONTAINER_GADGET(SpanTwoParamConstructor) // Uses of `std::span(arg0, arg1)` +WARNING_OPTIONAL_GADGET(UnsafeLibcFunctionCall) +WARNING_OPTIONAL_GADGET(SpanTwoParamConstructor) // Uses of `std::span(arg0, arg1)` FIXABLE_GADGET(ULCArraySubscript) // `DRE[any]` in an Unspecified Lvalue Context FIXABLE_GADGET(DerefSimplePtrArithFixable) FIXABLE_GADGET(PointerDereference) @@ -52,5 +53,5 @@ FIXABLE_GADGET(PointerInit) #undef FIXABLE_GADGET #undef WARNING_GADGET -#undef WARNING_CONTAINER_GADGET +#undef WARNING_OPTIONAL_GADGET #undef GADGET diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 8d2a362abc3c3..0c98f8e25a6fb 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4643,16 +4643,14 @@ def HLSLResource : InheritableAttr { let Documentation = [InternalOnly]; } -def HLSLROV : InheritableAttr { +def HLSLROV : TypeAttr { let Spellings = [CXX11<"hlsl", "is_rov">]; - let Subjects = SubjectList<[Struct]>; let LangOpts = [HLSL]; let Documentation = [InternalOnly]; } -def HLSLResourceClass : InheritableAttr { +def HLSLResourceClass : TypeAttr { let Spellings = [CXX11<"hlsl", "resource_class">]; - let Subjects = SubjectList<[Field]>; let LangOpts = [HLSL]; let Args = [ EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass", diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 8668b25661dec..92118418d9d45 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -934,6 +934,12 @@ def IsConstantEvaluated : LangBuiltin<"CXX_LANG"> { let Prototype = "bool()"; } +def IsWithinLifetime : LangBuiltin<"CXX_LANG"> { + let Spellings = ["__builtin_is_within_lifetime"]; + let Attributes = [NoThrow, CustomTypeChecking, Consteval]; + let Prototype = "bool(void*)"; +} + // GCC exception builtins def EHReturn : Builtin { let Spellings = ["__builtin_eh_return"]; @@ -4679,6 +4685,12 @@ def HLSLWaveGetLaneIndex : LangBuiltin<"HLSL_LANG"> { let Prototype = "unsigned int()"; } +def HLSLWaveIsFirstLane : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_is_first_lane"]; + let Attributes = [NoThrow, Const]; + let Prototype = "bool()"; +} + def HLSLClamp : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_elementwise_clamp"]; let Attributes = [NoThrow, Const]; diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index ab29ef38f7792..5060647d35764 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -448,6 +448,7 @@ TARGET_BUILTIN(__builtin_amdgcn_s_barrier_join, "vi", "n", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_s_wakeup_barrier, "vi", "n", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_s_barrier_leave, "b", "n", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_prefetch_data, "vvC*Ui", "nc", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32") diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index e4aa8661b9a80..48376ee052798 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -2261,6 +2261,68 @@ TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8_512_mask, "V32cV32xV32cUi", "nV:512:" TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8s_128_mask, "V16cV8xV16cUc", "nV:128:", "avx10.2-256") TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8s_256_mask, "V16cV16xV16cUs", "nV:256:", "avx10.2-256") TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8s_512_mask, "V32cV32xV32cUi", "nV:512:", "avx10.2-512") + +// AVX10.2 BF16 +TARGET_BUILTIN(__builtin_ia32_loadsbf16128_mask, "V8yV8yC*V8yUc", "nV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_storesbf16128_mask, "vV8y*V8yUc", "nV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vaddnepbf16128, "V8yV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vaddnepbf16256, "V16yV16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vaddnepbf16512, "V32yV32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vdivnepbf16128, "V8yV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vdivnepbf16256, "V16yV16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vdivnepbf16512, "V32yV32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vmaxpbf16128, "V8yV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vmaxpbf16256, "V16yV16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vmaxpbf16512, "V32yV32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vminpbf16128, "V8yV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vminpbf16256, "V16yV16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vminpbf16512, "V32yV32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vmulnepbf16128, "V8yV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vmulnepbf16256, "V16yV16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vmulnepbf16512, "V32yV32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vsubnepbf16128, "V8yV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vsubnepbf16256, "V16yV16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vsubnepbf16512, "V32yV32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vcomsbf16eq, "iV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vcomsbf16lt, "iV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vcomsbf16neq, "iV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vcomsbf16ge, "iV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vcomsbf16gt, "iV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vcomsbf16le, "iV8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vcmppbf16512_mask,"UiV32yV32yIiUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vcmppbf16256_mask,"UsV16yV16yIiUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vcmppbf16128_mask,"UcV8yV8yIiUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vfpclasspbf16128_mask, "UcV8yIiUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vfpclasspbf16256_mask, "UsV16yIiUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vfpclasspbf16512_mask, "UiV32yIiUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vscalefpbf16128_mask, "V8yV8yV8yV8yUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vscalefpbf16256_mask, "V16yV16yV16yV16yUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vscalefpbf16512_mask, "V32yV32yV32yV32yUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vrcppbf16128_mask, "V8yV8yV8yUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vrcppbf16256_mask, "V16yV16yV16yUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vrcppbf16512_mask, "V32yV32yV32yUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vgetexppbf16128_mask, "V8yV8yV8yUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vgetexppbf16256_mask, "V16yV16yV16yUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vgetexppbf16512_mask, "V32yV32yV32yUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vrsqrtpbf16128_mask, "V8yV8yV8yUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vrsqrtpbf16256_mask, "V16yV16yV16yUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vrsqrtpbf16512_mask, "V32yV32yV32yUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vreducenepbf16128_mask, "V8yV8yIiV8yUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vreducenepbf16256_mask, "V16yV16yIiV16yUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vreducenepbf16512_mask, "V32yV32yIiV32yUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vrndscalenepbf16_128_mask, "V8yV8yIiV8yUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vrndscalenepbf16_256_mask, "V16yV16yIiV16yUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vrndscalenepbf16_mask, "V32yV32yIiV32yUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vgetmantpbf16128_mask, "V8yV8yIiV8yUc", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vgetmantpbf16256_mask, "V16yV16yIiV16yUs", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vgetmantpbf16512_mask, "V32yV32yIiV32yUi", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vsqrtnepbf16, "V8yV8y", "ncV:128:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vsqrtnepbf16256, "V16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vsqrtnepbf16512, "V32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vfmaddnepbh512, "V32yV32yV32yV32y", "ncV:512:", "avx10.2-512") +TARGET_BUILTIN(__builtin_ia32_vfmaddnepbh256, "V16yV16yV16yV16y", "ncV:256:", "avx10.2-256") +TARGET_BUILTIN(__builtin_ia32_vfmaddnepbh128, "V8yV8yV8yV8y", "ncV:128:", "avx10.2-256") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 2ef6ddc68f4bf..f069f4fc118f2 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -67,6 +67,9 @@ clang_tablegen(arm_neon.inc -gen-arm-neon-sema clang_tablegen(arm_fp16.inc -gen-arm-neon-sema SOURCE arm_fp16.td TARGET ClangARMFP16) +clang_tablegen(arm_immcheck_types.inc -gen-arm-immcheck-types + SOURCE arm_sve.td + TARGET ClangARMImmChecks) clang_tablegen(arm_mve_builtins.inc -gen-arm-mve-builtin-def SOURCE arm_mve.td TARGET ClangARMMveBuiltinsDef) diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index 45ad84831589b..21a307d1e8987 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -148,8 +148,6 @@ def note_constexpr_var_init_weak : Note< def note_constexpr_typeid_polymorphic : Note< "typeid applied to expression of polymorphic type %0 is " "not allowed in a constant expression in C++ standards before C++20">; -def note_constexpr_void_comparison : Note< - "comparison between unequal pointers to void has unspecified result">; def note_constexpr_temporary_here : Note<"temporary created here">; def note_constexpr_dynamic_alloc_here : Note<"heap allocation performed here">; def note_constexpr_conditional_never_const : Note< @@ -169,14 +167,14 @@ def note_constexpr_this : Note< def access_kind : TextSubstitution< "%select{read of|read of|assignment to|increment of|decrement of|" "member call on|dynamic_cast of|typeid applied to|construction of|" - "destruction of}0">; + "destruction of|read of}0">; def access_kind_subobject : TextSubstitution< "%select{read of|read of|assignment to|increment of|decrement of|" "member call on|dynamic_cast of|typeid applied to|" - "construction of subobject of|destruction of}0">; + "construction of subobject of|destruction of|read of}0">; def access_kind_volatile : TextSubstitution< "%select{read of|read of|assignment to|increment of|decrement of|" - "||||}0">; + "|||||}0">; def note_constexpr_lifetime_ended : Note< "%sub{access_kind}0 %select{temporary|variable}1 whose " "%plural{8:storage duration|:lifetime}0 has ended">; @@ -409,6 +407,12 @@ def warn_is_constant_evaluated_always_true_constexpr : Warning< "'%0' will always evaluate to 'true' in a manifestly constant-evaluated expression">, InGroup>; +def err_invalid_is_within_lifetime : Note< + "'%0' cannot be called with " + "%select{a null pointer|a one-past-the-end pointer|" + "a pointer to an object whose lifetime has not yet begun}1" +>; + // inline asm related. let CategoryName = "Inline Assembly Issue" in { def err_asm_invalid_escape : Error< diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index c4c29942ee1cb..116ce7a04f66f 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1558,7 +1558,8 @@ def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">; // Warnings and fixes to support the "safe buffers" programming model. def UnsafeBufferUsageInContainer : DiagGroup<"unsafe-buffer-usage-in-container">; -def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer]>; +def UnsafeBufferUsageInLibcCall : DiagGroup<"unsafe-buffer-usage-in-libc-call">; +def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer, UnsafeBufferUsageInLibcCall]>; // Warnings and notes related to the function effects system underlying // the nonblocking and nonallocating attributes. diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 12d7b8c0205ee..fc14bb6aa2165 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -283,6 +283,9 @@ def warn_cxx98_compat_unicode_literal : Warning< def warn_cxx14_compat_u8_character_literal : Warning< "unicode literals are incompatible with C++ standards before C++17">, InGroup, DefaultIgnore; +def warn_c17_compat_u8_character_literal : Warning< + "unicode literals are incompatible with C standards before C23">, + InGroup, DefaultIgnore; def warn_cxx11_compat_user_defined_literal : Warning< "identifier after literal will be treated as a user-defined literal suffix " "in C++11">, InGroup, DefaultIgnore; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 0b8ab4bf09250..0aa2c4a70849a 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -470,6 +470,12 @@ def warn_c17_compat_static_assert_no_message : Warning< "'_Static_assert' with no message is incompatible with C standards before " "C23">, DefaultIgnore, InGroup; +def ext_cxx_static_assert_user_generated_message : ExtWarn< + "'static_assert' with a user-generated message is a C++26 extension">, + InGroup; +def warn_cxx20_compat_static_assert_user_generated_message : Warning< + "'static_assert' with a user-generated message is incompatible with " + "C++ standards before C++26">, DefaultIgnore, InGroup; def err_function_definition_not_allowed : Error< "function definition is not allowed here">; def err_expected_end_of_enumerator : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dcb49d8a67604..58819a64813fc 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12186,6 +12186,10 @@ def err_builtin_launder_invalid_arg : Error< "%select{non-pointer|function pointer|void pointer}0 argument to " "'__builtin_launder' is not allowed">; +def err_builtin_is_within_lifetime_invalid_arg : Error< + "%select{non-|function }0pointer argument to '__builtin_is_within_lifetime' " + "is not allowed">; + def err_builtin_invalid_arg_type: Error < "%ordinal0 argument must be " "%select{a vector, integer or floating point type|a matrix|" @@ -12364,6 +12368,7 @@ def err_hlsl_packoffset_cross_reg_boundary : Error<"packoffset cannot cross regi def err_hlsl_packoffset_alignment_mismatch : Error<"packoffset at 'y' not match alignment %0 required by %1">; def err_hlsl_pointers_unsupported : Error< "%select{pointers|references}0 are unsupported in HLSL">; +def err_hlsl_missing_resource_class : Error<"HLSL resource needs to have [[hlsl::resource_class()]] attribute">; def err_hlsl_operator_unsupported : Error< "the '%select{&|*|->}0' operator is unsupported in HLSL">; @@ -12412,6 +12417,13 @@ def warn_unsafe_buffer_operation : Warning< "unsafe buffer access|function introduces unsafe buffer manipulation|unsafe invocation of span::data|" "field %1 prone to unsafe buffer manipulation}0">, InGroup, DefaultIgnore; +def warn_unsafe_buffer_libc_call : Warning< + "function %0 is unsafe">, + InGroup, DefaultIgnore; +def note_unsafe_buffer_printf_call : Note< + "%select{|change to 'snprintf' for explicit bounds checking | buffer pointer and size may not match" + "|string argument is not guaranteed to be null-terminated" + "|'va_list' is unsafe}0">; def note_unsafe_buffer_operation : Note< "used%select{| in pointer arithmetic| in buffer access}0 here">; def note_unsafe_buffer_variable_fixit_group : Note< diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 10538f555b418..7f5d26118bdc7 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -54,6 +54,8 @@ FEATURE(memtag_globals, FEATURE(xray_instrument, LangOpts.XRayInstrument) FEATURE(undefined_behavior_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined)) +FEATURE(realtime_sanitizer, + LangOpts.Sanitize.has(SanitizerKind::Realtime)) FEATURE(coverage_sanitizer, LangOpts.SanitizeCoverage) FEATURE(assume_nonnull, true) FEATURE(attribute_analyzer_noreturn, true) diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index d3ccc7ef81c07..e0f1ea435d54e 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -724,7 +724,7 @@ class SourceManager : public RefCountedBase { /// /// Negative FileIDs are indexes into this table. To get from ID to an index, /// use (-ID - 2). - llvm::PagedVector LoadedSLocEntryTable; + llvm::PagedVector LoadedSLocEntryTable; /// For each allocation in LoadedSLocEntryTable, we keep the first FileID. /// We assume exactly one allocation per AST file, and use that to determine diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 4333830bf34f2..d0f41b17c154f 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -216,6 +216,35 @@ namespace clang { } bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; } bool isQuad() const { return (Flags & QuadFlag) != 0; } + unsigned getEltSizeInBits() const { + switch (getEltType()) { + case Int8: + case Poly8: + return 8; + case Int16: + case Float16: + case Poly16: + case BFloat16: + return 16; + case Int32: + case Float32: + return 32; + case Int64: + case Float64: + case Poly64: + return 64; + case Poly128: + return 128; + } + llvm_unreachable("Invalid NeonTypeFlag!"); + } + }; + + // Shared between SVE/SME and NEON + enum ImmCheckType { +#define LLVM_GET_ARM_INTRIN_IMMCHECKTYPES +#include "clang/Basic/arm_immcheck_types.inc" +#undef LLVM_GET_ARM_INTRIN_IMMCHECKTYPES }; /// Flags to identify the types for overloaded SVE builtins. @@ -249,12 +278,6 @@ namespace clang { #undef LLVM_GET_SVE_MERGETYPES }; - enum ImmCheckType { -#define LLVM_GET_SVE_IMMCHECKTYPES -#include "clang/Basic/arm_sve_typeflags.inc" -#undef LLVM_GET_SVE_IMMCHECKTYPES - }; - SVETypeFlags(uint64_t F) : Flags(F) { EltTypeShift = llvm::countr_zero(EltTypeMask); MemEltTypeShift = llvm::countr_zero(MemEltTypeMask); diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 212c1f6ff3a12..a82ff684b2ac7 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -660,8 +660,9 @@ KEYWORD(out , KEYHLSL) #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL) #include "clang/Basic/HLSLIntangibleTypes.def" -// HLSL Type traits. +// HLSL Type traits TYPE_TRAIT_2(__builtin_hlsl_is_scalarized_layout_compatible, IsScalarizedLayoutCompatible, KEYHLSL) +TYPE_TRAIT_1(__builtin_hlsl_is_intangible, IsIntangibleType, KEYHLSL) // OpenMP Type Traits UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL) diff --git a/clang/include/clang/Basic/arm_fp16.td b/clang/include/clang/Basic/arm_fp16.td index d36b4617bef5d..ed26e84af075e 100644 --- a/clang/include/clang/Basic/arm_fp16.td +++ b/clang/include/clang/Basic/arm_fp16.td @@ -76,17 +76,23 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "f def SCALAR_FCVTPUH : SInst<"vcvtp_u16", "(1U)1", "Sh">; def SCALAR_FCVTPUH1 : SInst<"vcvtp_u32", "(1U>)1", "Sh">; def SCALAR_FCVTPUH2 : SInst<"vcvtp_u64", "(1U>>)1", "Sh">; - let isVCVT_N = 1 in { + let ImmChecks = [ImmCheck<1, ImmCheck1_16>] in { def SCALAR_SCVTFSHO : SInst<"vcvth_n_f16", "(1F)(1!)I", "sUs">; def SCALAR_SCVTFSH1O: SInst<"vcvth_n_f16", "(1F<)(1!)I", "iUi">; def SCALAR_SCVTFSH2O: SInst<"vcvth_n_f16", "(1F<<)(1!)I", "lUl">; - def SCALAR_FCVTZSHO : SInst<"vcvt_n_s16", "(1S)1I", "Sh">; - def SCALAR_FCVTZSH1O: SInst<"vcvt_n_s32", "(1S>)1I", "Sh">; - def SCALAR_FCVTZSH2O: SInst<"vcvt_n_s64", "(1S>>)1I", "Sh">; - def SCALAR_FCVTZUHO : SInst<"vcvt_n_u16", "(1U)1I", "Sh">; - def SCALAR_FCVTZUH1O: SInst<"vcvt_n_u32", "(1U>)1I", "Sh">; - def SCALAR_FCVTZUH2O: SInst<"vcvt_n_u64", "(1U>>)1I", "Sh">; } + def SCALAR_FCVTZSHO : SInst<"vcvt_n_s16", "(1S)1I", "Sh", + [ImmCheck<1, ImmCheckCvt, 0>]>; + def SCALAR_FCVTZSH1O: SInst<"vcvt_n_s32", "(1S>)1I", "Sh", + [ImmCheck<1, ImmCheckCvt, 0>]>; + def SCALAR_FCVTZSH2O: SInst<"vcvt_n_s64", "(1S>>)1I", "Sh", + [ImmCheck<1, ImmCheckCvt, 0>]>; + def SCALAR_FCVTZUHO : SInst<"vcvt_n_u16", "(1U)1I", "Sh", + [ImmCheck<1, ImmCheckCvt, 0>]>; + def SCALAR_FCVTZUH1O: SInst<"vcvt_n_u32", "(1U>)1I", "Sh", + [ImmCheck<1, ImmCheckCvt, 0>]>; + def SCALAR_FCVTZUH2O: SInst<"vcvt_n_u64", "(1U>>)1I", "Sh", + [ImmCheck<1, ImmCheckCvt, 0>]>; // Comparison def SCALAR_CMEQRH : SInst<"vceq", "(1U)11", "Sh">; def SCALAR_CMEQZH : SInst<"vceqz", "(1U)1", "Sh">; diff --git a/clang/include/clang/Basic/arm_immcheck_incl.td b/clang/include/clang/Basic/arm_immcheck_incl.td new file mode 100644 index 0000000000000..9d7f74a35aaa8 --- /dev/null +++ b/clang/include/clang/Basic/arm_immcheck_incl.td @@ -0,0 +1,43 @@ +class ImmCheckType { + int Value = val; +} + +// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h +def ImmCheck0_31 : ImmCheckType<0>; // 0..31 (used for e.g. predicate patterns) +def ImmCheck1_16 : ImmCheckType<1>; // 1..16 +def ImmCheckExtract : ImmCheckType<2>; // 0..(2048/sizeinbits(elt) - 1) +def ImmCheckShiftRight : ImmCheckType<3>; // 1..sizeinbits(elt) +def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2 +def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1) +def ImmCheck0_7 : ImmCheckType<6>; // 0..7 +def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(sizeinbits(vec)/(sizeinbits(elt)) - 1) +def ImmCheckCvt : ImmCheckType<8>; // 1..sizeinbits(elt) (same as ShiftRight) +def ImmCheckLaneIndexCompRotate : ImmCheckType<9>; // 0..(sizeinbits(vec)/(2*sizeinbits(elt)) - 1) +def ImmCheckLaneIndexDot : ImmCheckType<10>; // 0..(sizeinbits(vec)/(4*sizeinbits(elt)) - 1) +def ImmCheckComplexRot90_270 : ImmCheckType<11>; // [90,270] +def ImmCheckComplexRotAll90 : ImmCheckType<12>; // [0, 90, 180,270] +def ImmCheck0_13 : ImmCheckType<13>; // 0..13 +def ImmCheck0_1 : ImmCheckType<14>; // 0..1 +def ImmCheck0_2 : ImmCheckType<15>; // 0..2 +def ImmCheck0_3 : ImmCheckType<16>; // 0..3 +def ImmCheck0_0 : ImmCheckType<17>; // 0..0 +def ImmCheck0_15 : ImmCheckType<18>; // 0..15 +def ImmCheck0_255 : ImmCheckType<19>; // 0..255 +def ImmCheck2_4_Mul2 : ImmCheckType<20>; // 2, 4 +def ImmCheck1_1 : ImmCheckType<21>; // 1..1 +def ImmCheck1_3 : ImmCheckType<22>; // 1..3 +def ImmCheck1_7 : ImmCheckType<23>; // 1..7 +def ImmCheck1_32 : ImmCheckType<24>; // 1..32 +def ImmCheck1_64 : ImmCheckType<25>; // 1..64 +def ImmCheck0_63 : ImmCheckType<26>; // 0..63 + +class ImmCheck { + // Parameter index of immediate argument to be verified + int ImmArgIdx = immArgIdx; + + // Parameter index of argument whose type determines the context of this immediate check - + // element type for SVE/SME, element type and vector size for NEON (ignoring element type for + // ClassB NEON intrinsics). + int TypeContextArgIdx = typeArgIdx; + ImmCheckType Kind = kind; +} diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td index 3098fa67e6a51..875ec6e90b685 100644 --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -284,16 +284,17 @@ def OP_CVT_F32_BF16 // Splat operation - performs a range-checked splat over a vector def SPLAT : WInst<"splat_lane", ".(!q)I", - "UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl">; + "UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; def SPLATQ : WInst<"splat_laneq", ".(!Q)I", - "UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl"> { - let isLaneQ = 1; -} + "UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; + let TargetGuard = "bf16,neon" in { - def SPLAT_BF : WInst<"splat_lane", ".(!q)I", "bQb">; - def SPLATQ_BF : WInst<"splat_laneq", ".(!Q)I", "bQb"> { - let isLaneQ = 1; - } + def SPLAT_BF : WInst<"splat_lane", ".(!q)I", "bQb", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; + def SPLATQ_BF : WInst<"splat_laneq", ".(!Q)I", "bQb", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; } //===----------------------------------------------------------------------===// @@ -401,27 +402,57 @@ def VQRSHL : SInst<"vqrshl", "..S", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.12 Shifts by constant let isShift = 1 in { -def VSHR_N : SInst<"vshr_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; -def VSHL_N : IInst<"vshl_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; -def VRSHR_N : SInst<"vrshr_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; -def VSRA_N : SInst<"vsra_n", "...I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; -def VRSRA_N : SInst<"vrsra_n", "...I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; -def VQSHL_N : SInst<"vqshl_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; -def VQSHLU_N : SInst<"vqshlu_n", "U.I", "csilQcQsQiQl">; -def VSHRN_N : IInst<"vshrn_n", "; -def VQSHRUN_N : SInst<"vqshrun_n", "(; -def VQRSHRUN_N : SInst<"vqrshrun_n", "(; -def VQSHRN_N : SInst<"vqshrn_n", "; -def VRSHRN_N : IInst<"vrshrn_n", "; -def VQRSHRN_N : SInst<"vqrshrn_n", "; -def VSHLL_N : SInst<"vshll_n", "(>Q).I", "csiUcUsUi">; + + +def VSHR_N : SInst<"vshr_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", + [ImmCheck<1, ImmCheckShiftRight>]>; +def VSHL_N : IInst<"vshl_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", + [ImmCheck<1, ImmCheckShiftLeft>]>; +def VRSHR_N : SInst<"vrshr_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", + [ImmCheck<1, ImmCheckShiftRight>]>; +def VSRA_N : SInst<"vsra_n", "...I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", + [ImmCheck<2, ImmCheckShiftRight>]>; +def VRSRA_N : SInst<"vrsra_n", "...I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", + [ImmCheck<2, ImmCheckShiftRight>]>; +def VQSHL_N : SInst<"vqshl_n", "..I", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", + [ImmCheck<1, ImmCheckShiftLeft>]>; +def VQSHLU_N : SInst<"vqshlu_n", "U.I", "csilQcQsQiQl", + [ImmCheck<1, ImmCheckShiftLeft>]>; + +// Narrowing right shifts should have an immediate range of 1..(sizeinbits(arg)/2). +// However, as the overloaded type code that is supplied to a polymorphic builtin +// is that of the return type (half as wide as the argument in this case), using +// ImmCheckShiftRightNarrow would return in an upper bound of (sizeinbits(arg)/2)/2. +// ImmCheckShiftRight produces the correct behavior here. +def VSHRN_N : IInst<"vshrn_n", "]>; +def VQSHRUN_N : SInst<"vqshrun_n", "(]>; +def VQRSHRUN_N : SInst<"vqrshrun_n", "(]>; +def VQSHRN_N : SInst<"vqshrn_n", "]>; +def VRSHRN_N : IInst<"vrshrn_n", "]>; +def VQRSHRN_N : SInst<"vqrshrn_n", "]>; + +// Widening left-shifts should have a range of 0..(sizeinbits(arg)-1). +// This polymorphic builtin is supplied the wider return type as it's overloaded +// base type, so the range here is actually 0..(sizeinbits(arg)*2). +// This cannot be rectified currently due to a use of vshll_n_s16 with an +// out-of-bounds immediate in the defintiion of vcvt_f32_bf16. +def VSHLL_N : SInst<"vshll_n", "(>Q).I", "csiUcUsUi", + [ImmCheck<1, ImmCheckShiftLeft>]>; //////////////////////////////////////////////////////////////////////////////// // E.3.13 Shifts with insert def VSRI_N : WInst<"vsri_n", "...I", - "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">; + "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs", + [ImmCheck<2, ImmCheckShiftRight, 0>]>; def VSLI_N : WInst<"vsli_n", "...I", - "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">; + "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs", + [ImmCheck<2, ImmCheckShiftLeft, 0>]>; } //////////////////////////////////////////////////////////////////////////////// @@ -435,7 +466,8 @@ def VLD1_X3 : WInst<"vld1_x3", "3(c*!)", def VLD1_X4 : WInst<"vld1_x4", "4(c*!)", "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VLD1_LANE : WInst<"vld1_lane", ".(c*!).I", - "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; def VLD1_DUP : WInst<"vld1_dup", ".(c*!)", "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VST1 : WInst<"vst1", "v*(.!)", @@ -447,19 +479,23 @@ def VST1_X3 : WInst<"vst1_x3", "v*(3!)", def VST1_X4 : WInst<"vst1_x4", "v*(4!)", "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VST1_LANE : WInst<"vst1_lane", "v*(.!)I", - "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; + let ArchGuard = "(__ARM_FP & 2)" in { def VLD1_F16 : WInst<"vld1", ".(c*!)", "hQh">; def VLD1_X2_F16 : WInst<"vld1_x2", "2(c*!)", "hQh">; def VLD1_X3_F16 : WInst<"vld1_x3", "3(c*!)", "hQh">; def VLD1_X4_F16 : WInst<"vld1_x4", "4(c*!)", "hQh">; -def VLD1_LANE_F16 : WInst<"vld1_lane", ".(c*!).I", "hQh">; +def VLD1_LANE_F16 : WInst<"vld1_lane", ".(c*!).I", "hQh", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; def VLD1_DUP_F16 : WInst<"vld1_dup", ".(c*!)", "hQh">; def VST1_F16 : WInst<"vst1", "v*(.!)", "hQh">; def VST1_X2_F16 : WInst<"vst1_x2", "v*(2!)", "hQh">; def VST1_X3_F16 : WInst<"vst1_x3", "v*(3!)", "hQh">; def VST1_X4_F16 : WInst<"vst1_x4", "v*(4!)", "hQh">; -def VST1_LANE_F16 : WInst<"vst1_lane", "v*(.!)I", "hQh">; +def VST1_LANE_F16 : WInst<"vst1_lane", "v*(.!)I", "hQh", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; } //////////////////////////////////////////////////////////////////////////////// @@ -473,15 +509,21 @@ def VLD3_DUP : WInst<"vld3_dup", "3(c*!)", "UcUsUiUlcsilfPcPsQcQfQiQlQsQPcQPsQUcQUiQUlQUs">; def VLD4_DUP : WInst<"vld4_dup", "4(c*!)", "UcUsUiUlcsilfPcPsQcQfQiQlQsQPcQPsQUcQUiQUlQUs">; -def VLD2_LANE : WInst<"vld2_lane", "2(c*!)2I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">; -def VLD3_LANE : WInst<"vld3_lane", "3(c*!)3I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">; -def VLD4_LANE : WInst<"vld4_lane", "4(c*!)4I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">; +def VLD2_LANE : WInst<"vld2_lane", "2(c*!)2I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; +def VLD3_LANE : WInst<"vld3_lane", "3(c*!)3I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; +def VLD4_LANE : WInst<"vld4_lane", "4(c*!)4I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs", + [ImmCheck<6, ImmCheckLaneIndex, 1>]>; def VST2 : WInst<"vst2", "v*(2!)", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">; def VST3 : WInst<"vst3", "v*(3!)", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">; def VST4 : WInst<"vst4", "v*(4!)", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">; -def VST2_LANE : WInst<"vst2_lane", "v*(2!)I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">; -def VST3_LANE : WInst<"vst3_lane", "v*(3!)I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">; -def VST4_LANE : WInst<"vst4_lane", "v*(4!)I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">; +def VST2_LANE : WInst<"vst2_lane", "v*(2!)I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs", + [ImmCheck<3, ImmCheckLaneIndex, 1>]>; +def VST3_LANE : WInst<"vst3_lane", "v*(3!)I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; +def VST4_LANE : WInst<"vst4_lane", "v*(4!)I", "QUsQUiQsQiQfQPsUcUsUicsifPcPs", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; let ArchGuard = "(__ARM_FP & 2)" in { def VLD2_F16 : WInst<"vld2", "2(c*!)", "hQh">; def VLD3_F16 : WInst<"vld3", "3(c*!)", "hQh">; @@ -489,28 +531,36 @@ def VLD4_F16 : WInst<"vld4", "4(c*!)", "hQh">; def VLD2_DUP_F16 : WInst<"vld2_dup", "2(c*!)", "hQh">; def VLD3_DUP_F16 : WInst<"vld3_dup", "3(c*!)", "hQh">; def VLD4_DUP_F16 : WInst<"vld4_dup", "4(c*!)", "hQh">; -def VLD2_LANE_F16 : WInst<"vld2_lane", "2(c*!)2I", "hQh">; -def VLD3_LANE_F16 : WInst<"vld3_lane", "3(c*!)3I", "hQh">; -def VLD4_LANE_F16 : WInst<"vld4_lane", "4(c*!)4I", "hQh">; +def VLD2_LANE_F16 : WInst<"vld2_lane", "2(c*!)2I", "hQh", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; +def VLD3_LANE_F16 : WInst<"vld3_lane", "3(c*!)3I", "hQh", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; +def VLD4_LANE_F16 : WInst<"vld4_lane", "4(c*!)4I", "hQh", + [ImmCheck<6, ImmCheckLaneIndex, 1>]>; def VST2_F16 : WInst<"vst2", "v*(2!)", "hQh">; def VST3_F16 : WInst<"vst3", "v*(3!)", "hQh">; def VST4_F16 : WInst<"vst4", "v*(4!)", "hQh">; -def VST2_LANE_F16 : WInst<"vst2_lane", "v*(2!)I", "hQh">; -def VST3_LANE_F16 : WInst<"vst3_lane", "v*(3!)I", "hQh">; -def VST4_LANE_F16 : WInst<"vst4_lane", "v*(4!)I", "hQh">; +def VST2_LANE_F16 : WInst<"vst2_lane", "v*(2!)I", "hQh", + [ImmCheck<3, ImmCheckLaneIndex, 1>]>; +def VST3_LANE_F16 : WInst<"vst3_lane", "v*(3!)I", "hQh", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; +def VST4_LANE_F16 : WInst<"vst4_lane", "v*(4!)I", "hQh", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; } //////////////////////////////////////////////////////////////////////////////// // E.3.16 Extract lanes from a vector let InstName = "vmov" in def VGET_LANE : IInst<"vget_lane", "1.I", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">; + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; //////////////////////////////////////////////////////////////////////////////// // E.3.17 Set lanes within a vector let InstName = "vmov" in def VSET_LANE : IInst<"vset_lane", ".1.I", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">; + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; //////////////////////////////////////////////////////////////////////////////// // E.3.18 Initialize a vector from bit pattern @@ -559,11 +609,12 @@ let ArchGuard = "(__ARM_FP & 2)" in { def VCVT_S32 : SInst<"vcvt_s32", "S.", "fQf">; def VCVT_U32 : SInst<"vcvt_u32", "U.", "fQf">; def VCVT_F32 : SInst<"vcvt_f32", "F(.!)", "iUiQiQUi">; -let isVCVT_N = 1 in { -def VCVT_N_S32 : SInst<"vcvt_n_s32", "S.I", "fQf">; -def VCVT_N_U32 : SInst<"vcvt_n_u32", "U.I", "fQf">; -def VCVT_N_F32 : SInst<"vcvt_n_f32", "F(.!)I", "iUiQiQUi">; -} +def VCVT_N_S32 : SInst<"vcvt_n_s32", "S.I", "fQf", + [ImmCheck<1, ImmCheck1_32>]>; +def VCVT_N_U32 : SInst<"vcvt_n_u32", "U.I", "fQf", + [ImmCheck<1, ImmCheck1_32>]>; +def VCVT_N_F32 : SInst<"vcvt_n_f32", "F(.!)I", "iUiQiQUi", + [ImmCheck<1, ImmCheck1_32>]>; def VMOVN : IInst<"vmovn", "; def VMOVL : SInst<"vmovl", "(>Q).", "csiUcUsUi">; @@ -610,8 +661,10 @@ def VQDMULH_LANE : SOpInst<"vqdmulh_lane", "..qI", "siQsQi", OP_QDMULH_LN>; def VQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "..qI", "siQsQi", OP_QRDMULH_LN>; } let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)" in { -def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..(!q)I", "siQsQi">; -def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..(!q)I", "siQsQi">; +def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..(!q)I", "siQsQi", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..(!q)I", "siQsQi", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; } let TargetGuard = "v8.1a,neon" in { @@ -629,7 +682,8 @@ def VQDMLSL_N : SOpInst<"vqdmlsl_n", "(>Q)(>Q).1", "si", OP_QDMLSL_N>; //////////////////////////////////////////////////////////////////////////////// // E.3.26 Vector Extract def VEXT : WInst<"vext", "...I", - "cUcPcsUsPsiUilUlfQcQUcQPcQsQUsQPsQiQUiQlQUlQf">; + "cUcPcsUsPsiUilUlfQcQUcQPcQsQUsQPsQiQUiQlQUlQf", + [ImmCheck<2, ImmCheckLaneIndex, 0>]>; //////////////////////////////////////////////////////////////////////////////// // E.3.27 Reverse vector elements @@ -738,14 +792,22 @@ def ST1_X2 : WInst<"vst1_x2", "v*(2!)", "dQdPlQPl">; def ST1_X3 : WInst<"vst1_x3", "v*(3!)", "dQdPlQPl">; def ST1_X4 : WInst<"vst1_x4", "v*(4!)", "dQdPlQPl">; -def LD1_LANE : WInst<"vld1_lane", ".(c*!).I", "dQdPlQPl">; -def LD2_LANE : WInst<"vld2_lane", "2(c*!)2I", "lUlQcQUcQPcQlQUldQdPlQPl">; -def LD3_LANE : WInst<"vld3_lane", "3(c*!)3I", "lUlQcQUcQPcQlQUldQdPlQPl">; -def LD4_LANE : WInst<"vld4_lane", "4(c*!)4I", "lUlQcQUcQPcQlQUldQdPlQPl">; -def ST1_LANE : WInst<"vst1_lane", "v*(.!)I", "dQdPlQPl">; -def ST2_LANE : WInst<"vst2_lane", "v*(2!)I", "lUlQcQUcQPcQlQUldQdPlQPl">; -def ST3_LANE : WInst<"vst3_lane", "v*(3!)I", "lUlQcQUcQPcQlQUldQdPlQPl">; -def ST4_LANE : WInst<"vst4_lane", "v*(4!)I", "lUlQcQUcQPcQlQUldQdPlQPl">; +def LD1_LANE : WInst<"vld1_lane", ".(c*!).I", "dQdPlQPl", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def LD2_LANE : WInst<"vld2_lane", "2(c*!)2I", "lUlQcQUcQPcQlQUldQdPlQPl", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; +def LD3_LANE : WInst<"vld3_lane", "3(c*!)3I", "lUlQcQUcQPcQlQUldQdPlQPl", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; +def LD4_LANE : WInst<"vld4_lane", "4(c*!)4I", "lUlQcQUcQPcQlQUldQdPlQPl", + [ImmCheck<6, ImmCheckLaneIndex, 1>]>; +def ST1_LANE : WInst<"vst1_lane", "v*(.!)I", "dQdPlQPl", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def ST2_LANE : WInst<"vst2_lane", "v*(2!)I", "lUlQcQUcQPcQlQUldQdPlQPl", + [ImmCheck<3, ImmCheckLaneIndex, 1>]>; +def ST3_LANE : WInst<"vst3_lane", "v*(3!)I", "lUlQcQUcQPcQlQUldQdPlQPl", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; +def ST4_LANE : WInst<"vst4_lane", "v*(4!)I", "lUlQcQUcQPcQlQUldQdPlQPl", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; def LD1_DUP : WInst<"vld1_dup", ".(c*!)", "dQdPlQPl">; def LD2_DUP : WInst<"vld2_dup", "2(c*!)", "dQdPlQPl">; @@ -901,8 +963,8 @@ def SHLL_HIGH_N : SOpInst<"vshll_high_n", ">.I", "HcHsHiHUcHUsHUi", OP_LONG_HI>; //////////////////////////////////////////////////////////////////////////////// -def SRI_N : WInst<"vsri_n", "...I", "PlQPl">; -def SLI_N : WInst<"vsli_n", "...I", "PlQPl">; +def SRI_N : WInst<"vsri_n", "...I", "PlQPl", [ImmCheck<2, ImmCheckShiftRight, 0>]>; +def SLI_N : WInst<"vsli_n", "...I", "PlQPl", [ImmCheck<2, ImmCheckShiftLeft, 0>]>; // Right shift narrow high def SHRN_HIGH_N : IOpInst<"vshrn_high_n", "<(.", "HcHsHiHUcHUsHUi", OP_MOVL_HI>; -let isVCVT_N = 1 in { -def CVTF_N_F64 : SInst<"vcvt_n_f64", "F(.!)I", "lUlQlQUl">; -def FCVTZS_N_S64 : SInst<"vcvt_n_s64", "S.I", "dQd">; -def FCVTZS_N_U64 : SInst<"vcvt_n_u64", "U.I", "dQd">; -} +def CVTF_N_F64 : SInst<"vcvt_n_f64", "F(.!)I", "lUlQlQUl", + [ImmCheck<1, ImmCheck1_64>]>; +def FCVTZS_N_S64 : SInst<"vcvt_n_s64", "S.I", "dQd", + [ImmCheck<1, ImmCheck1_64>]>; +def FCVTZS_N_U64 : SInst<"vcvt_n_u64", "U.I", "dQd", + [ImmCheck<1, ImmCheck1_64>]>; //////////////////////////////////////////////////////////////////////////////// // 3VDiff class using high 64-bit in operands @@ -965,29 +1028,25 @@ let TargetGuard = "aes,neon" in { //////////////////////////////////////////////////////////////////////////////// // Extract or insert element from vector -def GET_LANE : IInst<"vget_lane", "1.I", "dQdPlQPl">; -def SET_LANE : IInst<"vset_lane", ".1.I", "dQdPlQPl">; +def GET_LANE : IInst<"vget_lane", "1.I", "dQdPlQPl", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; +def SET_LANE : IInst<"vset_lane", ".1.I", "dQdPlQPl", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; def COPY_LANE : IOpInst<"vcopy_lane", "..I.I", "csilUcUsUiUlPcPsPlfd", OP_COPY_LN>; def COPYQ_LANE : IOpInst<"vcopy_lane", "..IqI", "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>; def COPY_LANEQ : IOpInst<"vcopy_laneq", "..IQI", - "csilPcPsPlUcUsUiUlfd", OP_COPY_LN> { - let isLaneQ = 1; -} + "csilPcPsPlUcUsUiUlfd", OP_COPY_LN>; def COPYQ_LANEQ : IOpInst<"vcopy_laneq", "..I.I", - "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN> { - let isLaneQ = 1; -} + "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>; //////////////////////////////////////////////////////////////////////////////// // Set all lanes to same value def VDUP_LANE1: WOpInst<"vdup_lane", ".qI", "dQdPlQPl", OP_DUP_LN>; def VDUP_LANE2: WOpInst<"vdup_laneq", ".QI", "csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl", - OP_DUP_LN> { - let isLaneQ = 1; -} + OP_DUP_LN>; def DUP_N : WOpInst<"vdup_n", ".1", "dQdPlQPl", OP_DUP>; def MOV_N : WOpInst<"vmov_n", ".1", "dQdPlQPl", OP_DUP>; @@ -1003,60 +1062,36 @@ def CREATE : NoTestOpInst<"vcreate", ".(IU>)", "dPl", OP_CAST> { //////////////////////////////////////////////////////////////////////////////// def VMLA_LANEQ : IOpInst<"vmla_laneq", "...QI", - "siUsUifQsQiQUsQUiQf", OP_MLA_LN> { - let isLaneQ = 1; -} + "siUsUifQsQiQUsQUiQf", OP_MLA_LN>; def VMLS_LANEQ : IOpInst<"vmls_laneq", "...QI", - "siUsUifQsQiQUsQUiQf", OP_MLS_LN> { - let isLaneQ = 1; -} - -def VFMA_LANE : IInst<"vfma_lane", "...qI", "fdQfQd">; -def VFMA_LANEQ : IInst<"vfma_laneq", "...QI", "fdQfQd"> { - let isLaneQ = 1; -} + "siUsUifQsQiQUsQUiQf", OP_MLS_LN>; +def VFMA_LANE : IInst<"vfma_lane", "...qI", "fdQfQd", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def VFMA_LANEQ : IInst<"vfma_laneq", "...QI", "fdQfQd", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; def VFMS_LANE : IOpInst<"vfms_lane", "...qI", "fdQfQd", OP_FMS_LN>; -def VFMS_LANEQ : IOpInst<"vfms_laneq", "...QI", "fdQfQd", OP_FMS_LNQ> { - let isLaneQ = 1; -} +def VFMS_LANEQ : IOpInst<"vfms_laneq", "...QI", "fdQfQd", OP_FMS_LNQ>; -def VMLAL_LANEQ : SOpInst<"vmlal_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLAL_LN> { - let isLaneQ = 1; -} +def VMLAL_LANEQ : SOpInst<"vmlal_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLAL_LN>; def VMLAL_HIGH_LANE : SOpInst<"vmlal_high_lane", "(>Q)(>Q)Q.I", "siUsUi", OP_MLALHi_LN>; def VMLAL_HIGH_LANEQ : SOpInst<"vmlal_high_laneq", "(>Q)(>Q)QQI", "siUsUi", - OP_MLALHi_LN> { - let isLaneQ = 1; -} -def VMLSL_LANEQ : SOpInst<"vmlsl_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLSL_LN> { - let isLaneQ = 1; -} + OP_MLALHi_LN>; +def VMLSL_LANEQ : SOpInst<"vmlsl_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLSL_LN>; def VMLSL_HIGH_LANE : SOpInst<"vmlsl_high_lane", "(>Q)(>Q)Q.I", "siUsUi", OP_MLSLHi_LN>; def VMLSL_HIGH_LANEQ : SOpInst<"vmlsl_high_laneq", "(>Q)(>Q)QQI", "siUsUi", - OP_MLSLHi_LN> { - let isLaneQ = 1; -} - -def VQDMLAL_LANEQ : SOpInst<"vqdmlal_laneq", "(>Q)(>Q).QI", "si", OP_QDMLAL_LN> { - let isLaneQ = 1; -} + OP_MLSLHi_LN>; +def VQDMLAL_LANEQ : SOpInst<"vqdmlal_laneq", "(>Q)(>Q).QI", "si", OP_QDMLAL_LN>; def VQDMLAL_HIGH_LANE : SOpInst<"vqdmlal_high_lane", "(>Q)(>Q)Q.I", "si", OP_QDMLALHi_LN>; def VQDMLAL_HIGH_LANEQ : SOpInst<"vqdmlal_high_laneq", "(>Q)(>Q)QQI", "si", - OP_QDMLALHi_LN> { - let isLaneQ = 1; -} -def VQDMLSL_LANEQ : SOpInst<"vqdmlsl_laneq", "(>Q)(>Q).QI", "si", OP_QDMLSL_LN> { - let isLaneQ = 1; -} + OP_QDMLALHi_LN>; +def VQDMLSL_LANEQ : SOpInst<"vqdmlsl_laneq", "(>Q)(>Q).QI", "si", OP_QDMLSL_LN>; def VQDMLSL_HIGH_LANE : SOpInst<"vqdmlsl_high_lane", "(>Q)(>Q)Q.I", "si", OP_QDMLSLHi_LN>; def VQDMLSL_HIGH_LANEQ : SOpInst<"vqdmlsl_high_laneq", "(>Q)(>Q)QQI", "si", - OP_QDMLSLHi_LN> { - let isLaneQ = 1; -} + OP_QDMLSLHi_LN>; // Newly add double parameter for vmul_lane in aarch64 // Note: d type is handled by SCALAR_VMUL_LANE @@ -1064,48 +1099,31 @@ def VMUL_LANE_A64 : IOpInst<"vmul_lane", "..qI", "Qd", OP_MUL_LN>; // Note: d type is handled by SCALAR_VMUL_LANEQ def VMUL_LANEQ : IOpInst<"vmul_laneq", "..QI", - "sifUsUiQsQiQUsQUiQfQd", OP_MUL_LN> { - let isLaneQ = 1; -} -def VMULL_LANEQ : SOpInst<"vmull_laneq", "(>Q).QI", "siUsUi", OP_MULL_LN> { - let isLaneQ = 1; -} + "sifUsUiQsQiQUsQUiQfQd", OP_MUL_LN>; +def VMULL_LANEQ : SOpInst<"vmull_laneq", "(>Q).QI", "siUsUi", OP_MULL_LN>; def VMULL_HIGH_LANE : SOpInst<"vmull_high_lane", "(>Q)Q.I", "siUsUi", OP_MULLHi_LN>; def VMULL_HIGH_LANEQ : SOpInst<"vmull_high_laneq", "(>Q)QQI", "siUsUi", - OP_MULLHi_LN> { - let isLaneQ = 1; -} - -def VQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(>Q).QI", "si", OP_QDMULL_LN> { - let isLaneQ = 1; -} + OP_MULLHi_LN>; +def VQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(>Q).QI", "si", OP_QDMULL_LN>; def VQDMULL_HIGH_LANE : SOpInst<"vqdmull_high_lane", "(>Q)Q.I", "si", OP_QDMULLHi_LN>; def VQDMULL_HIGH_LANEQ : SOpInst<"vqdmull_high_laneq", "(>Q)QQI", "si", - OP_QDMULLHi_LN> { - let isLaneQ = 1; -} + OP_QDMULLHi_LN>; +def VQDMULH_LANEQ : SInst<"vqdmulh_laneq", "..QI", "siQsQi", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def VQRDMULH_LANEQ : SInst<"vqrdmulh_laneq", "..QI", "siQsQi", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -let isLaneQ = 1 in { -def VQDMULH_LANEQ : SInst<"vqdmulh_laneq", "..QI", "siQsQi">; -def VQRDMULH_LANEQ : SInst<"vqrdmulh_laneq", "..QI", "siQsQi">; -} let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a,neon" in { -def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "...QI", "siQsQi", OP_QRDMLAH_LN> { - let isLaneQ = 1; -} -def VQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "...QI", "siQsQi", OP_QRDMLSH_LN> { - let isLaneQ = 1; -} +def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "...QI", "siQsQi", OP_QRDMLAH_LN>; +def VQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "...QI", "siQsQi", OP_QRDMLSH_LN>; } // ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a" // Note: d type implemented by SCALAR_VMULX_LANE def VMULX_LANE : IOpInst<"vmulx_lane", "..qI", "fQfQd", OP_MULX_LN>; // Note: d type is implemented by SCALAR_VMULX_LANEQ -def VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "fQfQd", OP_MULX_LN> { - let isLaneQ = 1; -} +def VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "fQfQd", OP_MULX_LN>; //////////////////////////////////////////////////////////////////////////////// // Across vectors class @@ -1118,7 +1136,8 @@ def FMINNMV : SInst<"vminnmv", "1.", "fQfQd">; //////////////////////////////////////////////////////////////////////////////// // Newly added Vector Extract for f64 -def VEXT_A64 : WInst<"vext", "...I", "dQdPlQPl">; +def VEXT_A64 : WInst<"vext", "...I", "dQdPlQPl", + [ImmCheck<2, ImmCheckLaneIndex, 0>]>; //////////////////////////////////////////////////////////////////////////////// // Crypto @@ -1147,10 +1166,7 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "s def BCAX : SInst<"vbcax", "....", "QUcQUsQUiQUlQcQsQiQl">; def EOR3 : SInst<"veor3", "....", "QUcQUsQUiQUlQcQsQiQl">; def RAX1 : SInst<"vrax1", "...", "QUl">; - -let isVXAR = 1 in { -def XAR : SInst<"vxar", "...I", "QUl">; -} +def XAR : SInst<"vxar", "...I", "QUl", [ImmCheck<2, ImmCheck0_63>]>; } let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3,neon" in { @@ -1162,10 +1178,10 @@ def SHA512H2 : SInst<"vsha512h2", "....", "QUl">; let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4,neon" in { def SM3SS1 : SInst<"vsm3ss1", "....", "QUi">; -def SM3TT1A : SInst<"vsm3tt1a", "....I", "QUi">; -def SM3TT1B : SInst<"vsm3tt1b", "....I", "QUi">; -def SM3TT2A : SInst<"vsm3tt2a", "....I", "QUi">; -def SM3TT2B : SInst<"vsm3tt2b", "....I", "QUi">; +def SM3TT1A : SInst<"vsm3tt1a", "....I", "QUi", [ImmCheck<3, ImmCheck0_3>]>; +def SM3TT1B : SInst<"vsm3tt1b", "....I", "QUi", [ImmCheck<3, ImmCheck0_3>]>; +def SM3TT2A : SInst<"vsm3tt2a", "....I", "QUi", [ImmCheck<3, ImmCheck0_3>]>; +def SM3TT2B : SInst<"vsm3tt2b", "....I", "QUi", [ImmCheck<3, ImmCheck0_3>]>; def SM3PARTW1 : SInst<"vsm3partw1", "....", "QUi">; def SM3PARTW2 : SInst<"vsm3partw2", "....", "QUi">; } @@ -1327,49 +1343,68 @@ def SCALAR_RSHL: SInst<"vrshl", "11(S1)", "SlSUl">; // Scalar Shift (Immediate) let isScalarShift = 1 in { // Signed/Unsigned Shift Right (Immediate) -def SCALAR_SSHR_N: SInst<"vshr_n", "11I", "SlSUl">; +def SCALAR_SSHR_N: SInst<"vshr_n", "11I", "SlSUl", + [ImmCheck<1, ImmCheckShiftRight, 0>]>; // Signed/Unsigned Rounding Shift Right (Immediate) -def SCALAR_SRSHR_N: SInst<"vrshr_n", "11I", "SlSUl">; +def SCALAR_SRSHR_N: SInst<"vrshr_n", "11I", "SlSUl", + [ImmCheck<1, ImmCheckShiftRight, 0>]>; // Signed/Unsigned Shift Right and Accumulate (Immediate) -def SCALAR_SSRA_N: SInst<"vsra_n", "111I", "SlSUl">; +def SCALAR_SSRA_N: SInst<"vsra_n", "111I", "SlSUl", + [ImmCheck<2, ImmCheckShiftRight, 0>]>; // Signed/Unsigned Rounding Shift Right and Accumulate (Immediate) -def SCALAR_SRSRA_N: SInst<"vrsra_n", "111I", "SlSUl">; +def SCALAR_SRSRA_N: SInst<"vrsra_n", "111I", "SlSUl", + [ImmCheck<2, ImmCheckShiftRight, 0>]>; // Shift Left (Immediate) -def SCALAR_SHL_N: SInst<"vshl_n", "11I", "SlSUl">; +def SCALAR_SHL_N: SInst<"vshl_n", "11I", "SlSUl", + [ImmCheck<1, ImmCheckShiftLeft, 0>]>; // Signed/Unsigned Saturating Shift Left (Immediate) -def SCALAR_SQSHL_N: SInst<"vqshl_n", "11I", "ScSsSiSlSUcSUsSUiSUl">; +def SCALAR_SQSHL_N: SInst<"vqshl_n", "11I", "ScSsSiSlSUcSUsSUiSUl", + [ImmCheck<1, ImmCheckShiftLeft, 0>]>; // Signed Saturating Shift Left Unsigned (Immediate) -def SCALAR_SQSHLU_N: SInst<"vqshlu_n", "11I", "ScSsSiSl">; +def SCALAR_SQSHLU_N: SInst<"vqshlu_n", "11I", "ScSsSiSl", + [ImmCheck<1, ImmCheckShiftLeft, 0>]>; // Shift Right And Insert (Immediate) -def SCALAR_SRI_N: SInst<"vsri_n", "111I", "SlSUl">; +def SCALAR_SRI_N: SInst<"vsri_n", "111I", "SlSUl", + [ImmCheck<2, ImmCheckShiftRight, 0>]>; // Shift Left And Insert (Immediate) -def SCALAR_SLI_N: SInst<"vsli_n", "111I", "SlSUl">; +def SCALAR_SLI_N: SInst<"vsli_n", "111I", "SlSUl", + [ImmCheck<2, ImmCheckShiftLeft, 0>]>; let isScalarNarrowShift = 1 in { // Signed/Unsigned Saturating Shift Right Narrow (Immediate) - def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "(1<)1I", "SsSiSlSUsSUiSUl">; + def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "(1<)1I", "SsSiSlSUsSUiSUl", + [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; // Signed/Unsigned Saturating Rounded Shift Right Narrow (Immediate) - def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "(1<)1I", "SsSiSlSUsSUiSUl">; + def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "(1<)1I", "SsSiSlSUsSUiSUl", + [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; // Signed Saturating Shift Right Unsigned Narrow (Immediate) - def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "(1; + def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "(1]>; // Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate) - def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "(1; + def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "(1]>; } //////////////////////////////////////////////////////////////////////////////// // Scalar Signed/Unsigned Fixed-point Convert To Floating-Point (Immediate) -def SCALAR_SCVTF_N_F32: SInst<"vcvt_n_f32", "(1F)(1!)I", "SiSUi">; -def SCALAR_SCVTF_N_F64: SInst<"vcvt_n_f64", "(1F)(1!)I", "SlSUl">; +def SCALAR_SCVTF_N_F32: SInst<"vcvt_n_f32", "(1F)(1!)I", "SiSUi", + [ImmCheck<1, ImmCheck1_32>]>; +def SCALAR_SCVTF_N_F64: SInst<"vcvt_n_f64", "(1F)(1!)I", "SlSUl", + [ImmCheck<1, ImmCheck1_64>]>; //////////////////////////////////////////////////////////////////////////////// // Scalar Floating-point Convert To Signed/Unsigned Fixed-point (Immediate) -def SCALAR_FCVTZS_N_S32 : SInst<"vcvt_n_s32", "(1S)1I", "Sf">; -def SCALAR_FCVTZU_N_U32 : SInst<"vcvt_n_u32", "(1U)1I", "Sf">; -def SCALAR_FCVTZS_N_S64 : SInst<"vcvt_n_s64", "(1S)1I", "Sd">; -def SCALAR_FCVTZU_N_U64 : SInst<"vcvt_n_u64", "(1U)1I", "Sd">; +def SCALAR_FCVTZS_N_S32 : SInst<"vcvt_n_s32", "(1S)1I", "Sf", + [ImmCheck<1, ImmCheck1_32>]>; +def SCALAR_FCVTZU_N_U32 : SInst<"vcvt_n_u32", "(1U)1I", "Sf", + [ImmCheck<1, ImmCheck1_32>]>; +def SCALAR_FCVTZS_N_S64 : SInst<"vcvt_n_s64", "(1S)1I", "Sd", + [ImmCheck<1, ImmCheck1_64>]>; +def SCALAR_FCVTZU_N_U64 : SInst<"vcvt_n_u64", "(1U)1I", "Sd", + [ImmCheck<1, ImmCheck1_64>]>; } //////////////////////////////////////////////////////////////////////////////// @@ -1562,94 +1597,72 @@ def SCALAR_UQXTN : SInst<"vqmovn", "(1<)1", "SUsSUiSUl">; // Scalar Floating Point multiply (scalar, by element) def SCALAR_FMUL_LANE : IOpInst<"vmul_lane", "11.I", "SfSd", OP_SCALAR_MUL_LN>; -def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "11QI", "SfSd", OP_SCALAR_MUL_LN> { - let isLaneQ = 1; -} +def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "11QI", "SfSd", OP_SCALAR_MUL_LN>; // Scalar Floating Point multiply extended (scalar, by element) def SCALAR_FMULX_LANE : IOpInst<"vmulx_lane", "11.I", "SfSd", OP_SCALAR_MULX_LN>; -def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "11QI", "SfSd", OP_SCALAR_MULX_LN> { - let isLaneQ = 1; -} +def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "11QI", "SfSd", OP_SCALAR_MULX_LN>; def SCALAR_VMUL_N : IInst<"vmul_n", "..1", "d">; // VMUL_LANE_A64 d type implemented using scalar mul lane -def SCALAR_VMUL_LANE : IInst<"vmul_lane", "..qI", "d">; +def SCALAR_VMUL_LANE : IInst<"vmul_lane", "..qI", "d", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; // VMUL_LANEQ d type implemented using scalar mul lane -def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "..QI", "d"> { - let isLaneQ = 1; -} - +def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "..QI", "d", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; // VMULX_LANE d type implemented using scalar vmulx_lane def SCALAR_VMULX_LANE : IOpInst<"vmulx_lane", "..qI", "d", OP_SCALAR_VMULX_LN>; // VMULX_LANEQ d type implemented using scalar vmulx_laneq -def SCALAR_VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "d", OP_SCALAR_VMULX_LNQ> { - let isLaneQ = 1; -} - +def SCALAR_VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "d", OP_SCALAR_VMULX_LNQ>; // Scalar Floating Point fused multiply-add (scalar, by element) -def SCALAR_FMLA_LANE : IInst<"vfma_lane", "111.I", "SfSd">; -def SCALAR_FMLA_LANEQ : IInst<"vfma_laneq", "111QI", "SfSd"> { - let isLaneQ = 1; -} +def SCALAR_FMLA_LANE : IInst<"vfma_lane", "111.I", "SfSd", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SCALAR_FMLA_LANEQ : IInst<"vfma_laneq", "111QI", "SfSd", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; // Scalar Floating Point fused multiply-subtract (scalar, by element) def SCALAR_FMLS_LANE : IOpInst<"vfms_lane", "111.I", "SfSd", OP_FMS_LN>; -def SCALAR_FMLS_LANEQ : IOpInst<"vfms_laneq", "111QI", "SfSd", OP_FMS_LNQ> { - let isLaneQ = 1; -} +def SCALAR_FMLS_LANEQ : IOpInst<"vfms_laneq", "111QI", "SfSd", OP_FMS_LNQ>; // Signed Saturating Doubling Multiply Long (scalar by element) def SCALAR_SQDMULL_LANE : SOpInst<"vqdmull_lane", "(1>)1.I", "SsSi", OP_SCALAR_QDMULL_LN>; -def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(1>)1QI", "SsSi", OP_SCALAR_QDMULL_LN> { - let isLaneQ = 1; -} +def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(1>)1QI", "SsSi", OP_SCALAR_QDMULL_LN>; // Signed Saturating Doubling Multiply-Add Long (scalar by element) -def SCALAR_SQDMLAL_LANE : SInst<"vqdmlal_lane", "(1>)(1>)1.I", "SsSi">; -def SCALAR_SQDMLAL_LANEQ : SInst<"vqdmlal_laneq", "(1>)(1>)1QI", "SsSi"> { - let isLaneQ = 1; -} +def SCALAR_SQDMLAL_LANE : SInst<"vqdmlal_lane", "(1>)(1>)1.I", "SsSi", + [ImmCheck<3, ImmCheckLaneIndex, 1>]>; +def SCALAR_SQDMLAL_LANEQ : SInst<"vqdmlal_laneq", "(1>)(1>)1QI", "SsSi", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; // Signed Saturating Doubling Multiply-Subtract Long (scalar by element) -def SCALAR_SQDMLS_LANE : SInst<"vqdmlsl_lane", "(1>)(1>)1.I", "SsSi">; -def SCALAR_SQDMLS_LANEQ : SInst<"vqdmlsl_laneq", "(1>)(1>)1QI", "SsSi"> { - let isLaneQ = 1; -} - +def SCALAR_SQDMLS_LANE : SInst<"vqdmlsl_lane", "(1>)(1>)1.I", "SsSi", + [ImmCheck<3, ImmCheckLaneIndex, 1>]>; +def SCALAR_SQDMLS_LANEQ : SInst<"vqdmlsl_laneq", "(1>)(1>)1QI", "SsSi", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; // Scalar Integer Saturating Doubling Multiply Half High (scalar by element) def SCALAR_SQDMULH_LANE : SOpInst<"vqdmulh_lane", "11.I", "SsSi", OP_SCALAR_QDMULH_LN>; -def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QDMULH_LN> { - let isLaneQ = 1; -} +def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QDMULH_LN>; // Scalar Integer Saturating Rounding Doubling Multiply Half High def SCALAR_SQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "11.I", "SsSi", OP_SCALAR_QRDMULH_LN>; -def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QRDMULH_LN> { - let isLaneQ = 1; -} +def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QRDMULH_LN>; let TargetGuard = "v8.1a,neon" in { // Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half def SCALAR_SQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "111.I", "SsSi", OP_SCALAR_QRDMLAH_LN>; -def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLAH_LN> { - let isLaneQ = 1; -} - +def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLAH_LN>; // Signed Saturating Rounding Doubling Multiply Subtract Returning High Half def SCALAR_SQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "111.I", "SsSi", OP_SCALAR_QRDMLSH_LN>; -def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLSH_LN> { - let isLaneQ = 1; -} +def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLSH_LN>; } // TargetGuard = "v8.1a" -def SCALAR_VDUP_LANE : IInst<"vdup_lane", "1.I", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; -def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "1QI", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs"> { - let isLaneQ = 1; -} +def SCALAR_VDUP_LANE : IInst<"vdup_lane", "1.I", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; +def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "1QI", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; } // ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)" @@ -1719,11 +1732,12 @@ let TargetGuard = "fullfp16,neon" in { def VCLTH : SOpInst<"vclt", "U..", "hQh", OP_LT>; // Vector conversion - let isVCVT_N = 1 in { - def VCVT_N_F16 : SInst<"vcvt_n_f16", "F(.!)I", "sUsQsQUs">; - def VCVT_N_S16 : SInst<"vcvt_n_s16", "S.I", "hQh">; - def VCVT_N_U16 : SInst<"vcvt_n_u16", "U.I", "hQh">; - } + def VCVT_N_F16 : SInst<"vcvt_n_f16", "F(.!)I", "sUsQsQUs", + [ImmCheck<1, ImmCheck1_16>]>; + def VCVT_N_S16 : SInst<"vcvt_n_s16", "S.I", "hQh", + [ImmCheck<1, ImmCheck1_16>]>; + def VCVT_N_U16 : SInst<"vcvt_n_u16", "U.I", "hQh", + [ImmCheck<1, ImmCheck1_16>]>; // Max/Min def VMAXH : SInst<"vmax", "...", "hQh">; @@ -1770,7 +1784,7 @@ def VZIPH : WInst<"vzip", "2..", "hQh">; def VUZPH : WInst<"vuzp", "2..", "hQh">; def VTRNH : WInst<"vtrn", "2..", "hQh">; // Vector Extract -def VEXTH : WInst<"vext", "...I", "hQh">; +def VEXTH : WInst<"vext", "...I", "hQh", [ImmCheck<2, ImmCheckLaneIndex, 0>]>; // Reverse vector elements def VREV64H : WOpInst<"vrev64", "..", "hQh", OP_REV64>; @@ -1801,54 +1815,42 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "f // ARMv8.2-A FP16 lane vector intrinsics. // FMA lane - def VFMA_LANEH : IInst<"vfma_lane", "...qI", "hQh">; - def VFMA_LANEQH : IInst<"vfma_laneq", "...QI", "hQh"> { - let isLaneQ = 1; - } + def VFMA_LANEH : IInst<"vfma_lane", "...qI", "hQh", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; + def VFMA_LANEQH : IInst<"vfma_laneq", "...QI", "hQh", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; // FMA lane with scalar argument def FMLA_NH : SOpInst<"vfma_n", "...1", "hQh", OP_FMLA_N>; // Scalar floating point fused multiply-add (scalar, by element) - def SCALAR_FMLA_LANEH : IInst<"vfma_lane", "111.I", "Sh">; - def SCALAR_FMLA_LANEQH : IInst<"vfma_laneq", "111QI", "Sh"> { - let isLaneQ = 1; - } + def SCALAR_FMLA_LANEH : IInst<"vfma_lane", "111.I", "Sh", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; + def SCALAR_FMLA_LANEQH : IInst<"vfma_laneq", "111QI", "Sh", + [ImmCheck<3, ImmCheckLaneIndex, 2>]>; // FMS lane def VFMS_LANEH : IOpInst<"vfms_lane", "...qI", "hQh", OP_FMS_LN>; - def VFMS_LANEQH : IOpInst<"vfms_laneq", "...QI", "hQh", OP_FMS_LNQ> { - let isLaneQ = 1; - } + def VFMS_LANEQH : IOpInst<"vfms_laneq", "...QI", "hQh", OP_FMS_LNQ>; // FMS lane with scalar argument def FMLS_NH : SOpInst<"vfms_n", "...1", "hQh", OP_FMLS_N>; // Scalar floating foint fused multiply-subtract (scalar, by element) def SCALAR_FMLS_LANEH : IOpInst<"vfms_lane", "111.I", "Sh", OP_FMS_LN>; - def SCALAR_FMLS_LANEQH : IOpInst<"vfms_laneq", "111QI", "Sh", OP_FMS_LNQ> { - let isLaneQ = 1; - } - + def SCALAR_FMLS_LANEQH : IOpInst<"vfms_laneq", "111QI", "Sh", OP_FMS_LNQ>; // Mul lane - def VMUL_LANEQH : IOpInst<"vmul_laneq", "..QI", "hQh", OP_MUL_LN> { - let isLaneQ = 1; - } + def VMUL_LANEQH : IOpInst<"vmul_laneq", "..QI", "hQh", OP_MUL_LN>; // Scalar floating point multiply (scalar, by element) def SCALAR_FMUL_LANEH : IOpInst<"vmul_lane", "11.I", "Sh", OP_SCALAR_MUL_LN>; - def SCALAR_FMUL_LANEQH : IOpInst<"vmul_laneq", "11QI", "Sh", OP_SCALAR_MUL_LN> { - let isLaneQ = 1; - } + def SCALAR_FMUL_LANEQH : IOpInst<"vmul_laneq", "11QI", "Sh", OP_SCALAR_MUL_LN>; // Mulx lane def VMULX_LANEH : IOpInst<"vmulx_lane", "..qI", "hQh", OP_MULX_LN>; - def VMULX_LANEQH : IOpInst<"vmulx_laneq", "..QI", "hQh", OP_MULX_LN> { - let isLaneQ = 1; - } + def VMULX_LANEQH : IOpInst<"vmulx_laneq", "..QI", "hQh", OP_MULX_LN>; def VMULX_NH : IOpInst<"vmulx_n", "..1", "hQh", OP_MULX_N>; // Scalar floating point mulx (scalar, by element) - def SCALAR_FMULX_LANEH : IInst<"vmulx_lane", "11.I", "Sh">; - def SCALAR_FMULX_LANEQH : IInst<"vmulx_laneq", "11QI", "Sh"> { - let isLaneQ = 1; - } - + def SCALAR_FMULX_LANEH : IInst<"vmulx_lane", "11.I", "Sh", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; + def SCALAR_FMULX_LANEQH : IInst<"vmulx_laneq", "11QI", "Sh", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; // ARMv8.2-A FP16 reduction vector intrinsics. def VMAXVH : SInst<"vmaxv", "1.", "hQh">; def VMINVH : SInst<"vminv", "1.", "hQh">; @@ -1865,10 +1867,10 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)" in { def VZIP2H : SOpInst<"vzip2", "...", "hQh", OP_ZIP2>; def VUZP2H : SOpInst<"vuzp2", "...", "hQh", OP_UZP2>; - def SCALAR_VDUP_LANEH : IInst<"vdup_lane", "1.I", "Sh">; - def SCALAR_VDUP_LANEQH : IInst<"vdup_laneq", "1QI", "Sh"> { - let isLaneQ = 1; - } + def SCALAR_VDUP_LANEH : IInst<"vdup_lane", "1.I", "Sh", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; + def SCALAR_VDUP_LANEQH : IInst<"vdup_laneq", "1QI", "Sh", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; } // v8.2-A dot product instructions. @@ -1878,9 +1880,7 @@ let TargetGuard = "dotprod,neon" in { } let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "dotprod,neon" in { // Variants indexing into a 128-bit vector are A64 only. - def UDOT_LANEQ : SOpInst<"vdot_laneq", "..(<<)(< { - let isLaneQ = 1; - } + def UDOT_LANEQ : SOpInst<"vdot_laneq", "..(<<)(<; } // v8.2-A FP16 fused multiply-add long instructions. @@ -1895,18 +1895,10 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "f def VFMLAL_LANE_HIGH : SOpInst<"vfmlal_lane_high", "(F>)(F>)F(Fq)I", "hQh", OP_FMLAL_LN_Hi>; def VFMLSL_LANE_HIGH : SOpInst<"vfmlsl_lane_high", "(F>)(F>)F(Fq)I", "hQh", OP_FMLSL_LN_Hi>; - def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN> { - let isLaneQ = 1; - } - def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN> { - let isLaneQ = 1; - } - def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN_Hi> { - let isLaneQ = 1; - } - def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN_Hi> { - let isLaneQ = 1; - } + def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN>; + def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN>; + def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN_Hi>; + def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN_Hi>; } let TargetGuard = "i8mm,neon" in { @@ -1919,19 +1911,15 @@ let TargetGuard = "i8mm,neon" in { def VSUDOT_LANE : SOpInst<"vsudot_lane", "..(<<)(<; let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)" in { - let isLaneQ = 1 in { - def VUSDOT_LANEQ : SOpInst<"vusdot_laneq", "..(<; - def VSUDOT_LANEQ : SOpInst<"vsudot_laneq", "..(<<)(<; - } + def VUSDOT_LANEQ : SOpInst<"vusdot_laneq", "..(<; + def VSUDOT_LANEQ : SOpInst<"vsudot_laneq", "..(<<)(<; } } let TargetGuard = "bf16,neon" in { def VDOT_BF : SInst<"vbfdot", "..BB", "fQf">; def VDOT_LANE_BF : SOpInst<"vbfdot_lane", "..B(Bq)I", "fQf", OP_BFDOT_LN>; - def VDOT_LANEQ_BF : SOpInst<"vbfdot_laneq", "..B(BQ)I", "fQf", OP_BFDOT_LNQ> { - let isLaneQ = 1; - } + def VDOT_LANEQ_BF : SOpInst<"vbfdot_laneq", "..B(BQ)I", "fQf", OP_BFDOT_LNQ>; def VFMMLA_BF : SInst<"vbfmmla", "..BB", "Qf">; @@ -1952,20 +1940,16 @@ multiclass VCMLA_ROTS { // vcmla{ROT}_lane def : SOpInst<"vcmla" # ROT # "_lane", "...qI", type, Op<(call "vcmla" # ROT, $p0, $p1, (bitcast $p0, (dup_typed lanety , (call "vget_lane", (bitcast lanety, $p2), $p3))))>>; - // vcmlaq{ROT}_lane def : SOpInst<"vcmla" # ROT # "_lane", "...qI", "Q" # type, Op<(call "vcmla" # ROT, $p0, $p1, (bitcast $p0, (dup_typed laneqty , (call "vget_lane", (bitcast lanety, $p2), $p3))))>>; - let isLaneQ = 1 in { - // vcmla{ROT}_laneq - def : SOpInst<"vcmla" # ROT # "_laneq", "...QI", type, Op<(call "vcmla" # ROT, $p0, $p1, - (bitcast $p0, (dup_typed lanety, (call "vget_lane", (bitcast laneqty, $p2), $p3))))>>; - - // vcmlaq{ROT}_laneq - def : SOpInst<"vcmla" # ROT # "_laneq", "...QI", "Q" # type, Op<(call "vcmla" # ROT, $p0, $p1, - (bitcast $p0, (dup_typed laneqty , (call "vget_lane", (bitcast laneqty, $p2), $p3))))>>; - } + // vcmla{ROT}_laneq + def : SOpInst<"vcmla" # ROT # "_laneq", "...QI", type, Op<(call "vcmla" # ROT, $p0, $p1, + (bitcast $p0, (dup_typed lanety, (call "vget_lane", (bitcast laneqty, $p2), $p3))))>>; + // vcmlaq{ROT}_laneq + def : SOpInst<"vcmla" # ROT # "_laneq", "...QI", "Q" # type, Op<(call "vcmla" # ROT, $p0, $p1, + (bitcast $p0, (dup_typed laneqty , (call "vget_lane", (bitcast laneqty, $p2), $p3))))>>; } } @@ -2002,21 +1986,21 @@ let TargetGuard = "bf16,neon" in { def VDUP_N_BF : WOpInst<"vdup_n", ".1", "bQb", OP_DUP>; def VDUP_LANE_BF : WOpInst<"vdup_lane", ".qI", "bQb", OP_DUP_LN>; - def VDUP_LANEQ_BF: WOpInst<"vdup_laneq", ".QI", "bQb", OP_DUP_LN> { - let isLaneQ = 1; - } + def VDUP_LANEQ_BF: WOpInst<"vdup_laneq", ".QI", "bQb", OP_DUP_LN>; def VCOMBINE_BF : NoTestOpInst<"vcombine", "Q..", "b", OP_CONC>; def VGET_HIGH_BF : NoTestOpInst<"vget_high", ".Q", "b", OP_HI>; def VGET_LOW_BF : NoTestOpInst<"vget_low", ".Q", "b", OP_LO>; - def VGET_LANE_BF : IInst<"vget_lane", "1.I", "bQb">; - def VSET_LANE_BF : IInst<"vset_lane", ".1.I", "bQb">; - def SCALAR_VDUP_LANE_BF : IInst<"vdup_lane", "1.I", "Sb">; - def SCALAR_VDUP_LANEQ_BF : IInst<"vdup_laneq", "1QI", "Sb"> { - let isLaneQ = 1; - } + def VGET_LANE_BF : IInst<"vget_lane", "1.I", "bQb", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; + def VSET_LANE_BF : IInst<"vset_lane", ".1.I", "bQb", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; + def SCALAR_VDUP_LANE_BF : IInst<"vdup_lane", "1.I", "Sb", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; + def SCALAR_VDUP_LANEQ_BF : IInst<"vdup_laneq", "1QI", "Sb", + [ImmCheck<1, ImmCheckLaneIndex, 0>]>; def VLD1_BF : WInst<"vld1", ".(c*!)", "bQb">; def VLD2_BF : WInst<"vld2", "2(c*!)", "bQb">; @@ -2036,14 +2020,22 @@ let TargetGuard = "bf16,neon" in { def VST1_X3_BF : WInst<"vst1_x3", "v*(3!)", "bQb">; def VST1_X4_BF : WInst<"vst1_x4", "v*(4!)", "bQb">; - def VLD1_LANE_BF : WInst<"vld1_lane", ".(c*!).I", "bQb">; - def VLD2_LANE_BF : WInst<"vld2_lane", "2(c*!)2I", "bQb">; - def VLD3_LANE_BF : WInst<"vld3_lane", "3(c*!)3I", "bQb">; - def VLD4_LANE_BF : WInst<"vld4_lane", "4(c*!)4I", "bQb">; - def VST1_LANE_BF : WInst<"vst1_lane", "v*(.!)I", "bQb">; - def VST2_LANE_BF : WInst<"vst2_lane", "v*(2!)I", "bQb">; - def VST3_LANE_BF : WInst<"vst3_lane", "v*(3!)I", "bQb">; - def VST4_LANE_BF : WInst<"vst4_lane", "v*(4!)I", "bQb">; + def VLD1_LANE_BF : WInst<"vld1_lane", ".(c*!).I", "bQb", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; + def VLD2_LANE_BF : WInst<"vld2_lane", "2(c*!)2I", "bQb", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; + def VLD3_LANE_BF : WInst<"vld3_lane", "3(c*!)3I", "bQb", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; + def VLD4_LANE_BF : WInst<"vld4_lane", "4(c*!)4I", "bQb", + [ImmCheck<6, ImmCheckLaneIndex, 1>]>; + def VST1_LANE_BF : WInst<"vst1_lane", "v*(.!)I", "bQb", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; + def VST2_LANE_BF : WInst<"vst2_lane", "v*(2!)I", "bQb", + [ImmCheck<3, ImmCheckLaneIndex, 1>]>; + def VST3_LANE_BF : WInst<"vst3_lane", "v*(3!)I", "bQb", + [ImmCheck<4, ImmCheckLaneIndex, 1>]>; + def VST4_LANE_BF : WInst<"vst4_lane", "v*(4!)I", "bQb", + [ImmCheck<5, ImmCheckLaneIndex, 1>]>; def VLD1_DUP_BF : WInst<"vld1_dup", ".(c*!)", "bQb">; def VLD2_DUP_BF : WInst<"vld2_dup", "2(c*!)", "bQb">; @@ -2093,6 +2085,39 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "b // v8.9a/v9.4a LRCPC3 intrinsics let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "rcpc3,neon" in { - def VLDAP1_LANE : WInst<"vldap1_lane", ".(c*!).I", "QUlQlUlldQdPlQPl">; - def VSTL1_LANE : WInst<"vstl1_lane", "v*(.!)I", "QUlQlUlldQdPlQPl">; -} + def VLDAP1_LANE : WInst<"vldap1_lane", ".(c*!).I", "QUlQlUlldQdPlQPl", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; + def VSTL1_LANE : WInst<"vstl1_lane", "v*(.!)I", "QUlQlUlldQdPlQPl", + [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +} + +// Lookup table read with 2-bit/4-bit indices +let ArchGuard = "defined(__aarch64__)", TargetGuard = "lut" in { + def VLUTI2_B : SInst<"vluti2_lane", "Q.(qU)I", "cUcPcQcQUcQPc", + [ImmCheck<2, ImmCheck0_1>]>; + def VLUTI2_B_Q : SInst<"vluti2_laneq", "Q.(QU)I", "cUcPcQcQUcQPc", + [ImmCheck<2, ImmCheck0_3>]>; + def VLUTI2_H : SInst<"vluti2_lane", "Q.(]>; + def VLUTI2_H_Q : SInst<"vluti2_laneq", "Q.(]>; + def VLUTI4_B : SInst<"vluti4_lane", "..(qU)I", "QcQUcQPc", + [ImmCheck<2, ImmCheck0_0>]>; + def VLUTI4_B_Q : SInst<"vluti4_laneq", "..UI", "QcQUcQPc", + [ImmCheck<2, ImmCheck0_1>]>; + def VLUTI4_H_X2 : SInst<"vluti4_lane_x2", ".2(]>; + def VLUTI4_H_X2_Q : SInst<"vluti4_laneq_x2", ".2(]>; + + let TargetGuard = "lut,bf16" in { + def VLUTI2_BF : SInst<"vluti2_lane", "Q.(]>; + def VLUTI2_BF_Q : SInst<"vluti2_laneq", "Q.(]>; + def VLUTI4_BF_X2 : SInst<"vluti4_lane_x2", ".2(]>; + def VLUTI4_BF_X2_Q : SInst<"vluti4_laneq_x2", ".2(]>; + } +} \ No newline at end of file diff --git a/clang/include/clang/Basic/arm_neon_incl.td b/clang/include/clang/Basic/arm_neon_incl.td index 3b8015daee6d9..b088e0794cdea 100644 --- a/clang/include/clang/Basic/arm_neon_incl.td +++ b/clang/include/clang/Basic/arm_neon_incl.td @@ -21,6 +21,8 @@ // //===----------------------------------------------------------------------===// +include "arm_immcheck_incl.td" + // The base Operation class. All operations must subclass this. class Operation ops=[]> { list Ops = ops; @@ -260,7 +262,7 @@ def OP_UNAVAILABLE : Operation { // Every intrinsic subclasses Inst. -class Inst { +class Inst ch = []>{ string Name = n; string Prototype = p; string Types = t; @@ -272,12 +274,7 @@ class Inst { bit isShift = 0; bit isScalarShift = 0; bit isScalarNarrowShift = 0; - bit isVCVT_N = 0; - bit isVXAR = 0; - // For immediate checks: the immediate will be assumed to specify the lane of - // a Q register. Only used for intrinsics which end up calling polymorphic - // builtins. - bit isLaneQ = 0; + list ImmChecks = ch; // Certain intrinsics have different names than their representative // instructions. This field allows us to handle this correctly when we @@ -300,9 +297,9 @@ class Inst { // SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8", "p8") // IInst: Instruction with generic integer suffix (e.g., "i8") // WInst: Instruction with only bit size suffix (e.g., "8") -class SInst : Inst {} -class IInst : Inst {} -class WInst : Inst {} +class SInst ch = []> : Inst {} +class IInst ch = []> : Inst {} +class WInst ch = []> : Inst {} // The following instruction classes are implemented via operators // instead of builtins. As such these declarations are only used for diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index 078373823a3b6..edf73d9022b06 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -1939,6 +1939,24 @@ def SVTBL2_BF16 : SInst<"svtbl2[_{d}]", "d2u", "b", MergeNone, "", [VerifyRunti def SVTBX_BF16 : SInst<"svtbx[_{d}]", "dddu", "b", MergeNone, "aarch64_sve_tbx", [VerifyRuntimeMode]>; } +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Lookup table +let SVETargetGuard = "sve2,lut", SMETargetGuard = "sme2,lut" in { + def SVLUTI2_B : SInst<"svluti2_lane[_{d}]", "dd[i", "cUc", MergeNone, "aarch64_sve_luti2_lane", [VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_3>]>; + def SVLUTI2_H : SInst<"svluti2_lane[_{d}]", "dd[i", "sUsh", MergeNone, "aarch64_sve_luti2_lane", [VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_7>]>; + + def SVLUTI4_B : SInst<"svluti4_lane[_{d}]", "dd[i", "cUc", MergeNone, "aarch64_sve_luti4_lane", [VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_1>]>; + def SVLUTI4_H : SInst<"svluti4_lane[_{d}]", "dd[i", "sUsh", MergeNone, "aarch64_sve_luti4_lane", [VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_3>]>; + + def SVLUTI4_x2 : SInst<"svluti4_lane[_{d}]_x2", "d2.d[i", "sUsh", MergeNone, "aarch64_sve_luti4_lane_x2", [VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_3>]>; +} + +let SVETargetGuard = "sve2,lut,bf16", SMETargetGuard = "sme2,lut,bf16" in { + def SVLUTI2_BF16 : SInst<"svluti2_lane[_{d}]", "dd[i", "b", MergeNone, "aarch64_sve_luti2_lane", [ VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_7>]>; + def SVLUTI4_BF16 : SInst<"svluti4_lane[_{d}]", "dd[i", "b", MergeNone, "aarch64_sve_luti4_lane", [ VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_3>]>; + def SVLUTI4_BF16_x2 : SInst<"svluti4_lane[_{d}]_x2", "d2.d[i", "b", MergeNone, "aarch64_sve_luti4_lane_x2", [ VerifyRuntimeMode], [ImmCheck<2, ImmCheck0_3>]>; +} + //////////////////////////////////////////////////////////////////////////////// // SVE2 - Optional @@ -2235,6 +2253,13 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in { def SVSQDMULH_X4 : SInst<"svqdmulh[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_sqdmulh_vgx4", [IsStreaming], []>; } +let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,faminmax" in { + def FAMIN_X2 : Inst<"svamin[_{d}_x2]", "222", "hfd", MergeNone, "aarch64_sme_famin_x2", [IsStreaming], []>; + def FAMAX_X2 : Inst<"svamax[_{d}_x2]", "222", "hfd", MergeNone, "aarch64_sme_famax_x2", [IsStreaming], []>; + def FAMIN_X4 : Inst<"svamin[_{d}_x4]", "444", "hfd", MergeNone, "aarch64_sme_famin_x4", [IsStreaming], []>; + def FAMAX_X4 : Inst<"svamax[_{d}_x4]", "444", "hfd", MergeNone, "aarch64_sme_famax_x4", [IsStreaming], []>; +} + let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in { def REINTERPRET_SVBOOL_TO_SVCOUNT : Inst<"svreinterpret[_c]", "}P", "Pc", MergeNone, "", [VerifyRuntimeMode], []>; def REINTERPRET_SVCOUNT_TO_SVBOOL : Inst<"svreinterpret[_b]", "P}", "Pc", MergeNone, "", [VerifyRuntimeMode], []>; @@ -2401,3 +2426,8 @@ let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in { def SVBFMLSLB_LANE : SInst<"svbfmlslb_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslb_lane", [IsOverloadNone, VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; def SVBFMLSLT_LANE : SInst<"svbfmlslt_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslt_lane", [IsOverloadNone, VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; } + +let SVETargetGuard = "sve2,faminmax", SMETargetGuard = "sme2,faminmax" in { + defm SVAMIN : SInstZPZZ<"svamin", "hfd", "aarch64_sve_famin", "aarch64_sve_famin_u">; + defm SVAMAX : SInstZPZZ<"svamax", "hfd", "aarch64_sve_famax", "aarch64_sve_famax_u">; +} diff --git a/clang/include/clang/Basic/arm_sve_sme_incl.td b/clang/include/clang/Basic/arm_sve_sme_incl.td index 6ec357825a132..fdf4ba55fe938 100644 --- a/clang/include/clang/Basic/arm_sve_sme_incl.td +++ b/clang/include/clang/Basic/arm_sve_sme_incl.td @@ -13,6 +13,8 @@ // //===----------------------------------------------------------------------===// +include "arm_immcheck_incl.td" + //===----------------------------------------------------------------------===// // Instruction definitions //===----------------------------------------------------------------------===// @@ -233,40 +235,6 @@ def IsInZT0 : FlagType<0x400000000000>; def IsOutZT0 : FlagType<0x800000000000>; def IsInOutZT0 : FlagType<0x1000000000000>; -// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h -class ImmCheckType { - int Value = val; -} -def ImmCheck0_31 : ImmCheckType<0>; // 0..31 (used for e.g. predicate patterns) -def ImmCheck1_16 : ImmCheckType<1>; // 1..16 -def ImmCheckExtract : ImmCheckType<2>; // 0..(2048/sizeinbits(elt) - 1) -def ImmCheckShiftRight : ImmCheckType<3>; // 1..sizeinbits(elt) -def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2 -def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1) -def ImmCheck0_7 : ImmCheckType<6>; // 0..7 -def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(128/(1*sizeinbits(elt)) - 1) -def ImmCheckLaneIndexCompRotate : ImmCheckType<8>; // 0..(128/(2*sizeinbits(elt)) - 1) -def ImmCheckLaneIndexDot : ImmCheckType<9>; // 0..(128/(4*sizeinbits(elt)) - 1) -def ImmCheckComplexRot90_270 : ImmCheckType<10>; // [90,270] -def ImmCheckComplexRotAll90 : ImmCheckType<11>; // [0, 90, 180,270] -def ImmCheck0_13 : ImmCheckType<12>; // 0..13 -def ImmCheck0_1 : ImmCheckType<13>; // 0..1 -def ImmCheck0_2 : ImmCheckType<14>; // 0..2 -def ImmCheck0_3 : ImmCheckType<15>; // 0..3 -def ImmCheck0_0 : ImmCheckType<16>; // 0..0 -def ImmCheck0_15 : ImmCheckType<17>; // 0..15 -def ImmCheck0_255 : ImmCheckType<18>; // 0..255 -def ImmCheck2_4_Mul2 : ImmCheckType<19>; // 2, 4 -def ImmCheck1_1 : ImmCheckType<20>; // 1..1 -def ImmCheck1_3 : ImmCheckType<21>; // 1..3 -def ImmCheck1_7 : ImmCheckType<22>; // 1..7 - -class ImmCheck { - int Arg = arg; - int EltSizeArg = eltSizeArg; - ImmCheckType Kind = kind; -} - defvar InvalidMode = ""; class Inst, Group, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Parse OpenMP pragmas and generate parallel code.">; def fno_openmp : Flag<["-"], "fno-openmp">, Group, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Flags<[NoArgumentUnused]>; class OpenMPVersionHelp { string str = !strconcat( @@ -6761,6 +6762,14 @@ def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, HelpText<"Set the default integer and logical kind to an 8 byte wide type">; def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, HelpText<"Set the default real kind to an 8 byte wide type">; +def fdisable_real_3 : Flag<["-"],"fdisable-real-3">, Group, + HelpText<"Disable real(KIND=3) from TargetCharacteristics">, Flags<[HelpHidden]>; +def fdisable_real_10 : Flag<["-"],"fdisable-real-10">, Group, + HelpText<"Disable real(KIND=10) from TargetCharacteristics">, Flags<[HelpHidden]>; +def fdisable_integer_2 : Flag<["-"],"fdisable-integer-2">, Group, + HelpText<"Disable integer(KIND=2) from TargetCharacteristics">, Flags<[HelpHidden]>; +def fdisable_integer_16 : Flag<["-"],"fdisable-integer-16">, Group, + HelpText<"Disable integer(KIND=16) from TargetCharacteristics">, Flags<[HelpHidden]>; def flarge_sizes : Flag<["-"],"flarge-sizes">, Group, HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">; diff --git a/clang/include/clang/Interpreter/Value.h b/clang/include/clang/Interpreter/Value.h index d70e8f8719026..a93c0841915fc 100644 --- a/clang/include/clang/Interpreter/Value.h +++ b/clang/include/clang/Interpreter/Value.h @@ -33,6 +33,7 @@ #ifndef LLVM_CLANG_INTERPRETER_VALUE_H #define LLVM_CLANG_INTERPRETER_VALUE_H +#include "llvm/Config/llvm-config.h" // for LLVM_BUILD_LLVM_DYLIB, LLVM_BUILD_SHARED_LIBS #include "llvm/Support/Compiler.h" #include diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h index b8196a3170d63..8c4c56e222130 100644 --- a/clang/include/clang/Sema/SemaARM.h +++ b/clang/include/clang/Sema/SemaARM.h @@ -13,7 +13,9 @@ #ifndef LLVM_CLANG_SEMA_SEMAARM_H #define LLVM_CLANG_SEMA_SEMAARM_H -#include "clang/AST/ASTFwd.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/Expr.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Sema/SemaBase.h" #include "llvm/ADT/StringRef.h" #include @@ -40,15 +42,21 @@ class SemaARM : public SemaBase { /// flags. Do Sema checks for the runtime mode. }; + bool CheckImmediateArg(CallExpr *TheCall, unsigned CheckTy, unsigned ArgIdx, + unsigned EltBitWidth, unsigned VecBitWidth); bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, unsigned MaxWidth); bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); + bool PerformNeonImmChecks( + CallExpr *TheCall, + SmallVectorImpl> &ImmChecks, + int OverloadType = -1); + bool + PerformSVEImmChecks(CallExpr *TheCall, + SmallVectorImpl> &ImmChecks); bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool - ParseSVEImmChecks(CallExpr *TheCall, - llvm::SmallVector, 3> &ImmChecks); bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index d79ca9a4fa18d..64b39ca7712ee 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -15,8 +15,10 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/Attr.h" +#include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/SemaBase.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/TargetParser/Triple.h" #include @@ -26,6 +28,12 @@ class IdentifierInfo; class ParsedAttr; class Scope; +// FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no +// longer need to create builtin buffer types in HLSLExternalSemaSource. +bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, + ArrayRef AttrList, + QualType &ResType); + class SemaHLSL : public SemaBase { public: SemaHLSL(Sema &S); @@ -59,8 +67,6 @@ class SemaHLSL : public SemaBase { void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL); void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL); void handleShaderAttr(Decl *D, const ParsedAttr &AL); - void handleROVAttr(Decl *D, const ParsedAttr &AL); - void handleResourceClassAttr(Decl *D, const ParsedAttr &AL); void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL); void handleParamModifierAttr(Decl *D, const ParsedAttr &AL); bool handleResourceTypeAttr(const ParsedAttr &AL); @@ -71,12 +77,23 @@ class SemaHLSL : public SemaBase { // HLSL Type trait implementations bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const; + bool IsIntangibleType(QualType T1); bool CheckCompatibleParameterABI(FunctionDecl *New, FunctionDecl *Old); ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg); QualType getInoutParameterType(QualType Ty); + +private: + // HLSL resource type attributes need to be processed all at once. + // This is a list to collect them. + llvm::SmallVector HLSLResourcesTypeAttrs; + + /// SourceLocation corresponding to HLSLAttributedResourceTypeLocs that we + /// have not yet populated. + llvm::DenseMap + LocsForHLSLAttributedResources; }; } // namespace clang diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c61234aa4d1af..341ea98a1b149 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -6188,11 +6188,13 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr, ArrayRef Expansions, int Index) const { QualType Canonical; + bool ExpandsToEmptyPack = FullySubstituted && Expansions.empty(); if (FullySubstituted && Index != -1) { Canonical = getCanonicalType(Expansions[Index]); } else { llvm::FoldingSetNodeID ID; - PackIndexingType::Profile(ID, *this, Pattern, IndexExpr); + PackIndexingType::Profile(ID, *this, Pattern, IndexExpr, + ExpandsToEmptyPack); void *InsertPos = nullptr; PackIndexingType *Canon = DependentPackIndexingTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -6200,8 +6202,8 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr, void *Mem = Allocate( PackIndexingType::totalSizeToAlloc(Expansions.size()), TypeAlignment); - Canon = new (Mem) - PackIndexingType(*this, QualType(), Pattern, IndexExpr, Expansions); + Canon = new (Mem) PackIndexingType(*this, QualType(), Pattern, IndexExpr, + ExpandsToEmptyPack, Expansions); DependentPackIndexingTypes.InsertNode(Canon, InsertPos); } Canonical = QualType(Canon, 0); @@ -6210,8 +6212,8 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr, void *Mem = Allocate(PackIndexingType::totalSizeToAlloc(Expansions.size()), TypeAlignment); - auto *T = new (Mem) - PackIndexingType(*this, Canonical, Pattern, IndexExpr, Expansions); + auto *T = new (Mem) PackIndexingType(*this, Canonical, Pattern, IndexExpr, + ExpandsToEmptyPack, Expansions); Types.push_back(T); return QualType(T, 0); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index fa850409ba121..e854dbfb7bf2e 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -360,51 +360,42 @@ namespace clang { } template - void tryUpdateTemplateParmDeclInheritedFrom(NamedDecl *RecentParm, - NamedDecl *NewParm) { - if (auto *ParmT = dyn_cast(RecentParm)) { - if (ParmT->hasDefaultArgument()) { - auto *P = cast(NewParm); - P->removeDefaultArgument(); - P->setInheritedDefaultArgument(Importer.ToContext, ParmT); + Error importTemplateParameterDefaultArgument(const TemplateParmDeclT *D, + TemplateParmDeclT *ToD) { + Error Err = Error::success(); + if (D->hasDefaultArgument()) { + if (D->defaultArgumentWasInherited()) { + auto *ToInheritedFrom = const_cast( + importChecked(Err, D->getDefaultArgStorage().getInheritedFrom())); + if (Err) + return Err; + if (!ToInheritedFrom->hasDefaultArgument()) { + // Resolve possible circular dependency between default value of the + // template argument and the template declaration. + const auto ToInheritedDefaultArg = + importChecked(Err, D->getDefaultArgStorage() + .getInheritedFrom() + ->getDefaultArgument()); + if (Err) + return Err; + ToInheritedFrom->setDefaultArgument(Importer.getToContext(), + ToInheritedDefaultArg); + } + ToD->setInheritedDefaultArgument(ToD->getASTContext(), + ToInheritedFrom); + } else { + Expected ToDefaultArgOrErr = + import(D->getDefaultArgument()); + if (!ToDefaultArgOrErr) + return ToDefaultArgOrErr.takeError(); + // Default argument could have been set in the + // '!ToInheritedFrom->hasDefaultArgument()' branch above. + if (!ToD->hasDefaultArgument()) + ToD->setDefaultArgument(Importer.getToContext(), + *ToDefaultArgOrErr); } } - } - - // Update the parameter list `NewParams` of a template declaration - // by "inheriting" default argument values from `RecentParams`, - // which is the parameter list of an earlier declaration of the - // same template. (Note that "inheriting" default argument values - // is not related to object-oriented inheritance.) - // - // In the clang AST template parameters (NonTypeTemplateParmDec, - // TemplateTypeParmDecl, TemplateTemplateParmDecl) have a reference to the - // default value, if one is specified at the first declaration. The default - // value can be specified only once. The template parameters of the - // following declarations have a reference to the original default value - // through the "inherited" value. This value should be set for all imported - // template parameters that have a previous declaration (also a previous - // template declaration). - // - // In the `Visit*ParmDecl` functions the default value of these template - // arguments is always imported. At that location the previous declaration - // is not easily accessible, it is not possible to call - // `setInheritedDefaultArgument` at that place. - // `updateTemplateParametersInheritedFrom` is called later when the already - // imported default value is erased and changed to "inherited". - // It is important to change the mode to "inherited" otherwise false - // structural in-equivalences could be detected. - void updateTemplateParametersInheritedFrom( - const TemplateParameterList &RecentParams, - TemplateParameterList &NewParams) { - for (auto [Idx, Param] : enumerate(RecentParams)) { - tryUpdateTemplateParmDeclInheritedFrom( - Param, NewParams.getParam(Idx)); - tryUpdateTemplateParmDeclInheritedFrom( - Param, NewParams.getParam(Idx)); - tryUpdateTemplateParmDeclInheritedFrom( - Param, NewParams.getParam(Idx)); - } + return Err; } public: @@ -5955,8 +5946,8 @@ ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { ExpectedDecl ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { // For template arguments, we adopt the translation unit as our declaration - // context. This context will be fixed when the actual template declaration - // is created. + // context. This context will be fixed when (during) the actual template + // declaration is created. ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc()); if (!BeginLocOrErr) @@ -5988,13 +5979,8 @@ ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { ToD->setTypeConstraint(ToConceptRef, ToIDC); } - if (D->hasDefaultArgument()) { - Expected ToDefaultArgOrErr = - import(D->getDefaultArgument()); - if (!ToDefaultArgOrErr) - return ToDefaultArgOrErr.takeError(); - ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr); - } + if (Error Err = importTemplateParameterDefaultArgument(D, ToD)) + return Err; return ToD; } @@ -6020,13 +6006,9 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { D->isParameterPack(), ToTypeSourceInfo)) return ToD; - if (D->hasDefaultArgument()) { - Expected ToDefaultArgOrErr = - import(D->getDefaultArgument()); - if (!ToDefaultArgOrErr) - return ToDefaultArgOrErr.takeError(); - ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); - } + Err = importTemplateParameterDefaultArgument(D, ToD); + if (Err) + return Err; return ToD; } @@ -6057,13 +6039,8 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { *TemplateParamsOrErr)) return ToD; - if (D->hasDefaultArgument()) { - Expected ToDefaultArgOrErr = - import(D->getDefaultArgument()); - if (!ToDefaultArgOrErr) - return ToDefaultArgOrErr.takeError(); - ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); - } + if (Error Err = importTemplateParameterDefaultArgument(D, ToD)) + return Err; return ToD; } @@ -6201,9 +6178,6 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { } D2->setPreviousDecl(Recent); - - updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()), - **TemplateParamsOrErr); } return D2; @@ -6518,9 +6492,6 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) { ToTemplated->setPreviousDecl(PrevTemplated); } ToVarTD->setPreviousDecl(Recent); - - updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()), - **TemplateParamsOrErr); } return ToVarTD; @@ -6793,9 +6764,6 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { TemplatedFD->setPreviousDecl(PrevTemplated); } ToFunc->setPreviousDecl(Recent); - - updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()), - *Params); } return ToFunc; diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index a831f196abdcb..eea77c2f0a9bb 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -687,6 +687,8 @@ bool Compiler::VisitParenExpr(const ParenExpr *E) { template bool Compiler::VisitBinaryOperator(const BinaryOperator *BO) { // Need short-circuiting for these. + if (BO->getType()->isVectorType()) + return this->VisitVectorBinOp(BO); if (BO->isLogicalOp()) return this->VisitLogicalBinOp(BO); @@ -1222,6 +1224,105 @@ bool Compiler::VisitComplexBinOp(const BinaryOperator *E) { return true; } +template +bool Compiler::VisitVectorBinOp(const BinaryOperator *E) { + assert(E->getType()->isVectorType()); + assert(E->getLHS()->getType()->isVectorType()); + assert(E->getRHS()->getType()->isVectorType()); + + // FIXME: Current only support comparison binary operator, add support for + // other binary operator. + if (!E->isComparisonOp()) + return this->emitInvalid(E); + // Prepare storage for result. + if (!Initializing) { + unsigned LocalIndex = allocateTemporary(E); + if (!this->emitGetPtrLocal(LocalIndex, E)) + return false; + } + + const Expr *LHS = E->getLHS(); + const Expr *RHS = E->getRHS(); + const auto *VecTy = E->getType()->getAs(); + + // The LHS and RHS of a comparison operator must have the same type. So we + // just use LHS vector element type here. + PrimType ElemT = this->classifyVectorElementType(LHS->getType()); + PrimType ResultElemT = this->classifyVectorElementType(E->getType()); + + // Evaluate LHS and save value to LHSOffset. + unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false); + if (!this->visit(LHS)) + return false; + if (!this->emitSetLocal(PT_Ptr, LHSOffset, E)) + return false; + + // Evaluate RHS and save value to RHSOffset. + unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false); + if (!this->visit(RHS)) + return false; + if (!this->emitSetLocal(PT_Ptr, RHSOffset, E)) + return false; + + auto getElem = [=](unsigned Offset, unsigned Index) { + if (!this->emitGetLocal(PT_Ptr, Offset, E)) + return false; + return this->emitArrayElemPop(ElemT, Index, E); + }; + + for (unsigned I = 0; I != VecTy->getNumElements(); ++I) { + if (!getElem(LHSOffset, I)) + return false; + if (!getElem(RHSOffset, I)) + return false; + switch (E->getOpcode()) { + case BO_EQ: + if (!this->emitEQ(ElemT, E)) + return false; + break; + case BO_NE: + if (!this->emitNE(ElemT, E)) + return false; + break; + case BO_LE: + if (!this->emitLE(ElemT, E)) + return false; + break; + case BO_LT: + if (!this->emitLT(ElemT, E)) + return false; + break; + case BO_GE: + if (!this->emitGE(ElemT, E)) + return false; + break; + case BO_GT: + if (!this->emitGT(ElemT, E)) + return false; + break; + default: + llvm_unreachable("Unsupported binary operator"); + } + + // The result of the comparison is a vector of the same width and number + // of elements as the comparison operands with a signed integral element + // type. + // + // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + if (E->isComparisonOp()) { + if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E)) + return false; + if (!this->emitNeg(ResultElemT, E)) + return false; + } + + // Initialize array element with the value we just computed. + if (!this->emitInitElem(ResultElemT, I, E)) + return false; + } + return true; +} + template bool Compiler::VisitImplicitValueInitExpr( const ImplicitValueInitExpr *E) { diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index b18afacdb2e49..e6f54fe05427b 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -130,6 +130,7 @@ class Compiler : public ConstStmtVisitor, bool>, bool VisitLogicalBinOp(const BinaryOperator *E); bool VisitPointerArithBinOp(const BinaryOperator *E); bool VisitComplexBinOp(const BinaryOperator *E); + bool VisitVectorBinOp(const BinaryOperator *E); bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E); bool VisitCallExpr(const CallExpr *E); bool VisitBuiltinCallExpr(const CallExpr *E); @@ -363,7 +364,6 @@ class Compiler : public ConstStmtVisitor, bool>, bool emitComplexBoolCast(const Expr *E); bool emitComplexComparison(const Expr *LHS, const Expr *RHS, const BinaryOperator *E); - bool emitRecordDestruction(const Record *R); bool emitDestruction(const Descriptor *Desc); unsigned collectBaseOffset(const QualType BaseType, diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h index 2cffce4bc2ae4..3248e2d8be697 100644 --- a/clang/lib/AST/ByteCode/State.h +++ b/clang/lib/AST/ByteCode/State.h @@ -34,6 +34,7 @@ enum AccessKinds { AK_TypeId, AK_Construct, AK_Destroy, + AK_IsWithinLifetime, }; /// The order of this enum is important for diagnostics. diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 9a3ede426e914..01143391edab4 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -109,7 +109,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), - IsAnyDestructorNoReturn(false), IsLambda(false), + IsAnyDestructorNoReturn(false), IsHLSLIntangible(false), IsLambda(false), IsParsingBaseSpecifiers(false), ComputedVisibleConversions(false), HasODRHash(false), Definition(D) {} @@ -431,6 +431,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (BaseClassDecl->isAnyDestructorNoReturn()) data().IsAnyDestructorNoReturn = true; + if (BaseClassDecl->isHLSLIntangible()) + data().IsHLSLIntangible = true; + // C++11 [class.copy]p18: // The implicitly-declared copy assignment operator for a class X will // have the form 'X& X::operator=(const X&)' if each direct base class B @@ -1401,6 +1404,18 @@ void CXXRecordDecl::addedMember(Decl *D) { // than subobjects of zero size if (data().Empty && !IsZeroSize) data().Empty = false; + + if (getLangOpts().HLSL) { + const Type *Ty = Field->getType()->getUnqualifiedDesugaredType(); + while (isa(Ty)) + Ty = Ty->getArrayElementTypeNoTypeQual(); + + Ty = Ty->getUnqualifiedDesugaredType(); + if (Ty->isBuiltinType()) + data().IsHLSLIntangible |= Ty->isHLSLIntangibleType(); + else if (const RecordType *RT = dyn_cast(Ty)) + data().IsHLSLIntangible |= RT->getAsCXXRecordDecl()->isHLSLIntangible(); + } } // Handle using declarations of conversion functions. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 96c6276f3f34c..27930db019a17 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -13,6 +13,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/Attr.h" #include "clang/AST/ComputeDependence.h" #include "clang/AST/DeclCXX.h" @@ -2287,6 +2288,15 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx, Context = getParentContext(); } + // If we are currently parsing a lambda declarator, we might not have a fully + // formed call operator declaration yet, and we could not form a function name + // for it. Because we do not have access to Sema/function scopes here, we + // detect this case by relying on the fact such method doesn't yet have a + // type. + if (const auto *D = dyn_cast(Context); + D && D->getFunctionTypeLoc().isNull() && isLambdaCallOperator(D)) + Context = D->getParent()->getParent(); + PresumedLoc PLoc = Ctx.getSourceManager().getPresumedLoc( Ctx.getSourceManager().getExpansionRange(Loc).getEnd()); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 3dc13c14c0034..0ad3577d4e102 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1522,7 +1522,8 @@ CallStackFrame::~CallStackFrame() { } static bool isRead(AccessKinds AK) { - return AK == AK_Read || AK == AK_ReadObjectRepresentation; + return AK == AK_Read || AK == AK_ReadObjectRepresentation || + AK == AK_IsWithinLifetime; } static bool isModification(AccessKinds AK) { @@ -1532,6 +1533,7 @@ static bool isModification(AccessKinds AK) { case AK_MemberCall: case AK_DynamicCast: case AK_TypeId: + case AK_IsWithinLifetime: return false; case AK_Assign: case AK_Increment: @@ -1549,7 +1551,8 @@ static bool isAnyAccess(AccessKinds AK) { /// Is this an access per the C++ definition? static bool isFormalAccess(AccessKinds AK) { - return isAnyAccess(AK) && AK != AK_Construct && AK != AK_Destroy; + return isAnyAccess(AK) && AK != AK_Construct && AK != AK_Destroy && + AK != AK_IsWithinLifetime; } /// Is this kind of axcess valid on an indeterminate object value? @@ -1561,6 +1564,7 @@ static bool isValidIndeterminateAccess(AccessKinds AK) { // These need the object's value. return false; + case AK_IsWithinLifetime: case AK_ReadObjectRepresentation: case AK_Assign: case AK_Construct: @@ -3707,7 +3711,8 @@ struct CompleteObject { // In C++14 onwards, it is permitted to read a mutable member whose // lifetime began within the evaluation. // FIXME: Should we also allow this in C++11? - if (!Info.getLangOpts().CPlusPlus14) + if (!Info.getLangOpts().CPlusPlus14 && + AK != AccessKinds::AK_IsWithinLifetime) return false; return lifetimeStartedInEvaluation(Info, Base, /*MutableSubobject*/true); } @@ -3760,6 +3765,12 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, if ((O->isAbsent() && !(handler.AccessKind == AK_Construct && I == N)) || (O->isIndeterminate() && !isValidIndeterminateAccess(handler.AccessKind))) { + // Object has ended lifetime. + // If I is non-zero, some subobject (member or array element) of a + // complete object has ended its lifetime, so this is valid for + // IsWithinLifetime, resulting in false. + if (I != 0 && handler.AccessKind == AK_IsWithinLifetime) + return false; if (!Info.checkingPotentialConstantExpression()) Info.FFDiag(E, diag::note_constexpr_access_uninit) << handler.AccessKind << O->isIndeterminate() @@ -3927,6 +3938,9 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, // Placement new onto an inactive union member makes it active. O->setUnion(Field, APValue()); } else { + // Pointer to/into inactive union member: Not within lifetime + if (handler.AccessKind == AK_IsWithinLifetime) + return false; // FIXME: If O->getUnionValue() is absent, report that there's no // active union member rather than reporting the prior active union // member. We'll need to fix nullptr_t to not use APValue() as its @@ -11684,6 +11698,9 @@ class IntExprEvaluator bool ZeroInitialization(const Expr *E) { return Success(0, E); } + friend std::optional EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &, + const CallExpr *); + //===--------------------------------------------------------------------===// // Visitor Methods //===--------------------------------------------------------------------===// @@ -12743,6 +12760,11 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return Success(Info.InConstantContext, E); } + case Builtin::BI__builtin_is_within_lifetime: + if (auto result = EvaluateBuiltinIsWithinLifetime(*this, E)) + return Success(*result, E); + return false; + case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: case Builtin::BI__builtin_ctzll: @@ -13895,16 +13917,6 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator(); SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator(); - // C++11 [expr.rel]p3: - // Pointers to void (after pointer conversions) can be compared, with a - // result defined as follows: If both pointers represent the same - // address or are both the null pointer value, the result is true if the - // operator is <= or >= and false otherwise; otherwise the result is - // unspecified. - // We interpret this as applying to pointers to *cv* void. - if (LHSTy->isVoidPointerType() && LHSOffset != RHSOffset && IsRelational) - Info.CCEDiag(E, diag::note_constexpr_void_comparison); - // C++11 [expr.rel]p2: // - If two pointers point to non-static data members of the same object, // or to subobjects or array elements fo such members, recursively, the @@ -17332,3 +17344,84 @@ bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const { EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold); return EvaluateBuiltinStrLen(this, Result, Info); } + +namespace { +struct IsWithinLifetimeHandler { + EvalInfo &Info; + static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime; + using result_type = std::optional; + std::optional failed() { return std::nullopt; } + template + std::optional found(T &Subobj, QualType SubobjType) { + return true; + } +}; + +std::optional EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE, + const CallExpr *E) { + EvalInfo &Info = IEE.Info; + // Sometimes this is called during some sorts of constant folding / early + // evaluation. These are meant for non-constant expressions and are not + // necessary since this consteval builtin will never be evaluated at runtime. + // Just fail to evaluate when not in a constant context. + if (!Info.InConstantContext) + return std::nullopt; + assert(E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime); + const Expr *Arg = E->getArg(0); + if (Arg->isValueDependent()) + return std::nullopt; + LValue Val; + if (!EvaluatePointer(Arg, Val, Info)) + return std::nullopt; + + auto Error = [&](int Diag) { + bool CalledFromStd = false; + const auto *Callee = Info.CurrentCall->getCallee(); + if (Callee && Callee->isInStdNamespace()) { + const IdentifierInfo *Identifier = Callee->getIdentifier(); + CalledFromStd = Identifier && Identifier->isStr("is_within_lifetime"); + } + Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin() + : E->getExprLoc(), + diag::err_invalid_is_within_lifetime) + << (CalledFromStd ? "std::is_within_lifetime" + : "__builtin_is_within_lifetime") + << Diag; + return std::nullopt; + }; + // C++2c [meta.const.eval]p4: + // During the evaluation of an expression E as a core constant expression, a + // call to this function is ill-formed unless p points to an object that is + // usable in constant expressions or whose complete object's lifetime began + // within E. + + // Make sure it points to an object + // nullptr does not point to an object + if (Val.isNullPointer() || Val.getLValueBase().isNull()) + return Error(0); + QualType T = Val.getLValueBase().getType(); + assert(!T->isFunctionType() && + "Pointers to functions should have been typed as function pointers " + "which would have been rejected earlier"); + assert(T->isObjectType()); + // Hypothetical array element is not an object + if (Val.getLValueDesignator().isOnePastTheEnd()) + return Error(1); + assert(Val.getLValueDesignator().isValidSubobject() && + "Unchecked case for valid subobject"); + // All other ill-formed values should have failed EvaluatePointer, so the + // object should be a pointer to an object that is usable in a constant + // expression or whose complete lifetime began within the expression + CompleteObject CO = + findCompleteObject(Info, E, AccessKinds::AK_IsWithinLifetime, Val, T); + // The lifetime hasn't begun yet if we are still evaluating the + // initializer ([basic.life]p(1.2)) + if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue) + return Error(2); + + if (!CO) + return false; + IsWithinLifetimeHandler handler{Info}; + return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler); +} +} // namespace diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index e89ce2e4b3844..b976d1a0ee60a 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3992,12 +3992,12 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, PackIndexingType::PackIndexingType(const ASTContext &Context, QualType Canonical, QualType Pattern, - Expr *IndexExpr, + Expr *IndexExpr, bool ExpandsToEmptyPack, ArrayRef Expansions) : Type(PackIndexing, Canonical, computeDependence(Pattern, IndexExpr, Expansions)), Context(Context), Pattern(Pattern), IndexExpr(IndexExpr), - Size(Expansions.size()) { + Size(Expansions.size()), ExpandsToEmptyPack(ExpandsToEmptyPack) { std::uninitialized_copy(Expansions.begin(), Expansions.end(), getTrailingObjects()); @@ -4042,9 +4042,10 @@ PackIndexingType::computeDependence(QualType Pattern, Expr *IndexExpr, void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, QualType Pattern, - Expr *E) { + Expr *E, bool ExpandsToEmptyPack) { Pattern.Profile(ID); E->Profile(ID, Context, true); + ID.AddBoolean(ExpandsToEmptyPack); } UnaryTransformType::UnaryTransformType(QualType BaseType, diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index b1d9516c96eb7..3bef9370e621c 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1942,6 +1942,10 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::BTFTypeTag: llvm_unreachable("BTFTypeTag attribute handled separately"); + case attr::HLSLResourceClass: + case attr::HLSLROV: + llvm_unreachable("HLSL resource type attributes handled separately"); + case attr::OpenCLPrivateAddressSpace: case attr::OpenCLGlobalAddressSpace: case attr::OpenCLGlobalDeviceAddressSpace: @@ -2062,7 +2066,11 @@ void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T, void TypePrinter::printHLSLAttributedResourceBefore( const HLSLAttributedResourceType *T, raw_ostream &OS) { printBefore(T->getWrappedType(), OS); +} +void TypePrinter::printHLSLAttributedResourceAfter( + const HLSLAttributedResourceType *T, raw_ostream &OS) { + printAfter(T->getWrappedType(), OS); const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs(); OS << " [[hlsl::resource_class(" << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass) @@ -2071,11 +2079,6 @@ void TypePrinter::printHLSLAttributedResourceBefore( OS << " [[hlsl::is_rov()]]"; } -void TypePrinter::printHLSLAttributedResourceAfter( - const HLSLAttributedResourceType *T, raw_ostream &OS) { - printAfter(T->getWrappedType(), OS); -} - void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T, raw_ostream &OS) { OS << T->getDecl()->getName(); diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index e25b843c9bf83..5577f45aa5217 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -922,6 +922,9 @@ class ScopedLockableFactEntry : public FactEntry { handleRemovalFromIntersection(const FactSet &FSet, FactManager &FactMan, SourceLocation JoinLoc, LockErrorKind LEK, ThreadSafetyHandler &Handler) const override { + if (LEK == LEK_LockedAtEndOfFunction || LEK == LEK_NotLockedAtEndOfFunction) + return; + for (const auto &UnderlyingMutex : UnderlyingMutexes) { const auto *Entry = FSet.findLock(FactMan, UnderlyingMutex.Cap); if ((UnderlyingMutex.Kind == UCK_Acquired && Entry) || @@ -1177,8 +1180,7 @@ void BeforeSet::checkBeforeAfter(const ValueDecl* StartVd, } // Transitively search other before sets, and warn on cycles. if (traverse(Vdb)) { - if (!CycMap.contains(Vd)) { - CycMap.insert(std::make_pair(Vd, true)); + if (CycMap.try_emplace(Vd, true).second) { StringRef L1 = Vd->getName(); Analyzer.Handler.handleBeforeAfterCycle(L1, Vd->getLocation()); } @@ -2224,7 +2226,7 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &EntrySet, if (join(FactMan[*EntryIt], ExitFact, EntryLEK != LEK_LockedSomeLoopIterations)) *EntryIt = Fact; - } else if (!ExitFact.managed()) { + } else if (!ExitFact.managed() || EntryLEK == LEK_LockedAtEndOfFunction) { ExitFact.handleRemovalFromIntersection(ExitSet, FactMan, JoinLoc, EntryLEK, Handler); } @@ -2236,7 +2238,8 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &EntrySet, const FactEntry *ExitFact = ExitSet.findLock(FactMan, *EntryFact); if (!ExitFact) { - if (!EntryFact->managed() || ExitLEK == LEK_LockedSomeLoopIterations) + if (!EntryFact->managed() || ExitLEK == LEK_LockedSomeLoopIterations || + ExitLEK == LEK_NotLockedAtEndOfFunction) EntryFact->handleRemovalFromIntersection(EntrySetOrig, FactMan, JoinLoc, ExitLEK, Handler); if (ExitLEK == LEK_LockedSomePredecessors) diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index da7446913f7c8..ec76eae8b6077 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -10,12 +10,12 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/AST/FormatString.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtVisitor.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/Basic/CharInfo.h" #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" @@ -247,6 +247,11 @@ AST_MATCHER_P(Stmt, ignoreUnsafeBufferInContainer, return Handler->ignoreUnsafeBufferInContainer(Node.getBeginLoc()); } +AST_MATCHER_P(Stmt, ignoreUnsafeLibcCall, const UnsafeBufferUsageHandler *, + Handler) { + return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc()); +} + AST_MATCHER_P(CastExpr, castSubExpr, internal::Matcher, innerMatcher) { return innerMatcher.matches(*Node.getSubExpr(), Finder, Builder); } @@ -443,6 +448,425 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) { return false; } +AST_MATCHER_P(CallExpr, hasNumArgs, unsigned, Num) { + return Node.getNumArgs() == Num; +} + +namespace libc_func_matchers { +// Under `libc_func_matchers`, define a set of matchers that match unsafe +// functions in libc and unsafe calls to them. + +// A tiny parser to strip off common prefix and suffix of libc function names +// in real code. +// +// Given a function name, `matchName` returns `CoreName` according to the +// following grammar: +// +// LibcName := CoreName | CoreName + "_s" +// MatchingName := "__builtin_" + LibcName | +// "__builtin___" + LibcName + "_chk" | +// "__asan_" + LibcName +// +struct LibcFunNamePrefixSuffixParser { + StringRef matchName(StringRef FunName, bool isBuiltin) { + // Try to match __builtin_: + if (isBuiltin && FunName.starts_with("__builtin_")) + // Then either it is __builtin_LibcName or __builtin___LibcName_chk or + // no match: + return matchLibcNameOrBuiltinChk( + FunName.drop_front(10 /* truncate "__builtin_" */)); + // Try to match __asan_: + if (FunName.starts_with("__asan_")) + return matchLibcName(FunName.drop_front(7 /* truncate of "__asan_" */)); + return matchLibcName(FunName); + } + + // Parameter `Name` is the substring after stripping off the prefix + // "__builtin_". + StringRef matchLibcNameOrBuiltinChk(StringRef Name) { + if (Name.starts_with("__") && Name.ends_with("_chk")) + return matchLibcName( + Name.drop_front(2).drop_back(4) /* truncate "__" and "_chk" */); + return matchLibcName(Name); + } + + StringRef matchLibcName(StringRef Name) { + if (Name.ends_with("_s")) + return Name.drop_back(2 /* truncate "_s" */); + return Name; + } +}; + +// A pointer type expression is known to be null-terminated, if it has the +// form: E.c_str(), for any expression E of `std::string` type. +static bool isNullTermPointer(const Expr *Ptr) { + if (isa(Ptr->IgnoreParenImpCasts())) + return true; + if (isa(Ptr->IgnoreParenImpCasts())) + return true; + if (auto *MCE = dyn_cast(Ptr->IgnoreParenImpCasts())) { + const CXXMethodDecl *MD = MCE->getMethodDecl(); + const CXXRecordDecl *RD = MCE->getRecordDecl()->getCanonicalDecl(); + + if (MD && RD && RD->isInStdNamespace()) + if (MD->getName() == "c_str" && RD->getName() == "basic_string") + return true; + } + return false; +} + +// Return true iff at least one of following cases holds: +// 1. Format string is a literal and there is an unsafe pointer argument +// corresponding to an `s` specifier; +// 2. Format string is not a literal and there is least an unsafe pointer +// argument (including the formatter argument). +// +// `UnsafeArg` is the output argument that will be set only if this function +// returns true. +static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg, + const unsigned FmtArgIdx, ASTContext &Ctx, + bool isKprintf = false) { + class StringFormatStringHandler + : public analyze_format_string::FormatStringHandler { + const CallExpr *Call; + unsigned FmtArgIdx; + const Expr *&UnsafeArg; + + public: + StringFormatStringHandler(const CallExpr *Call, unsigned FmtArgIdx, + const Expr *&UnsafeArg) + : Call(Call), FmtArgIdx(FmtArgIdx), UnsafeArg(UnsafeArg) {} + + bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, + const char *startSpecifier, + unsigned specifierLen, + const TargetInfo &Target) override { + if (FS.getConversionSpecifier().getKind() == + analyze_printf::PrintfConversionSpecifier::sArg) { + unsigned ArgIdx = FS.getPositionalArgIndex() + FmtArgIdx; + + if (0 < ArgIdx && ArgIdx < Call->getNumArgs()) + if (!isNullTermPointer(Call->getArg(ArgIdx))) { + UnsafeArg = Call->getArg(ArgIdx); // output + // returning false stops parsing immediately + return false; + } + } + return true; // continue parsing + } + }; + + const Expr *Fmt = Call->getArg(FmtArgIdx); + + if (auto *SL = dyn_cast(Fmt->IgnoreParenImpCasts())) { + StringRef FmtStr = SL->getString(); + StringFormatStringHandler Handler(Call, FmtArgIdx, UnsafeArg); + + return analyze_format_string::ParsePrintfString( + Handler, FmtStr.begin(), FmtStr.end(), Ctx.getLangOpts(), + Ctx.getTargetInfo(), isKprintf); + } + // If format is not a string literal, we cannot analyze the format string. + // In this case, this call is considered unsafe if at least one argument + // (including the format argument) is unsafe pointer. + return llvm::any_of( + llvm::make_range(Call->arg_begin() + FmtArgIdx, Call->arg_end()), + [&UnsafeArg](const Expr *Arg) -> bool { + if (Arg->getType()->isPointerType() && !isNullTermPointer(Arg)) { + UnsafeArg = Arg; + return true; + } + return false; + }); +} + +// Matches a FunctionDecl node such that +// 1. It's name, after stripping off predefined prefix and suffix, is +// `CoreName`; and +// 2. `CoreName` or `CoreName[str/wcs]` is one of the `PredefinedNames`, which +// is a set of libc function names. +// +// Note: For predefined prefix and suffix, see `LibcFunNamePrefixSuffixParser`. +// The notation `CoreName[str/wcs]` means a new name obtained from replace +// string "wcs" with "str" in `CoreName`. +AST_MATCHER(FunctionDecl, isPredefinedUnsafeLibcFunc) { + static std::unique_ptr> PredefinedNames = nullptr; + if (!PredefinedNames) + PredefinedNames = + std::make_unique, std::set>({ + // numeric conversion: + "atof", + "atoi", + "atol", + "atoll", + "strtol", + "strtoll", + "strtoul", + "strtoull", + "strtof", + "strtod", + "strtold", + "strtoimax", + "strtoumax", + // "strfromf", "strfromd", "strfroml", // C23? + // string manipulation: + "strcpy", + "strncpy", + "strlcpy", + "strcat", + "strncat", + "strlcat", + "strxfrm", + "strdup", + "strndup", + // string examination: + "strlen", + "strnlen", + "strcmp", + "strncmp", + "stricmp", + "strcasecmp", + "strcoll", + "strchr", + "strrchr", + "strspn", + "strcspn", + "strpbrk", + "strstr", + "strtok", + // "mem-" functions + "memchr", + "wmemchr", + "memcmp", + "wmemcmp", + "memcpy", + "memccpy", + "mempcpy", + "wmemcpy", + "memmove", + "wmemmove", + "memset", + "wmemset", + // IO: + "fread", + "fwrite", + "fgets", + "fgetws", + "gets", + "fputs", + "fputws", + "puts", + // others + "strerror_s", + "strerror_r", + "bcopy", + "bzero", + "bsearch", + "qsort", + }); + + auto *II = Node.getIdentifier(); + + if (!II) + return false; + + StringRef Name = LibcFunNamePrefixSuffixParser().matchName( + II->getName(), Node.getBuiltinID()); + + // Match predefined names: + if (PredefinedNames->find(Name) != PredefinedNames->end()) + return true; + + std::string NameWCS = Name.str(); + size_t WcsPos = NameWCS.find("wcs"); + + while (WcsPos != std::string::npos) { + NameWCS[WcsPos++] = 's'; + NameWCS[WcsPos++] = 't'; + NameWCS[WcsPos++] = 'r'; + WcsPos = NameWCS.find("wcs", WcsPos); + } + if (PredefinedNames->find(NameWCS) != PredefinedNames->end()) + return true; + // All `scanf` functions are unsafe (including `sscanf`, `vsscanf`, etc.. They + // all should end with "scanf"): + return Name.ends_with("scanf"); +} + +// Match a call to one of the `v*printf` functions taking `va_list`. We cannot +// check safety for these functions so they should be changed to their +// non-va_list versions. +AST_MATCHER(FunctionDecl, isUnsafeVaListPrintfFunc) { + auto *II = Node.getIdentifier(); + + if (!II) + return false; + + StringRef Name = LibcFunNamePrefixSuffixParser().matchName( + II->getName(), Node.getBuiltinID()); + + if (!Name.ends_with("printf")) + return false; // neither printf nor scanf + return Name.starts_with("v"); +} + +// Matches a call to one of the `sprintf` functions as they are always unsafe +// and should be changed to `snprintf`. +AST_MATCHER(FunctionDecl, isUnsafeSprintfFunc) { + auto *II = Node.getIdentifier(); + + if (!II) + return false; + + StringRef Name = LibcFunNamePrefixSuffixParser().matchName( + II->getName(), Node.getBuiltinID()); + + if (!Name.ends_with("printf") || + // Let `isUnsafeVaListPrintfFunc` check for cases with va-list: + Name.starts_with("v")) + return false; + + StringRef Prefix = Name.drop_back(6); + + if (Prefix.ends_with("w")) + Prefix = Prefix.drop_back(1); + return Prefix == "s"; +} + +// Match function declarations of `printf`, `fprintf`, `snprintf` and their wide +// character versions. Calls to these functions can be safe if their arguments +// are carefully made safe. +AST_MATCHER(FunctionDecl, isNormalPrintfFunc) { + auto *II = Node.getIdentifier(); + + if (!II) + return false; + + StringRef Name = LibcFunNamePrefixSuffixParser().matchName( + II->getName(), Node.getBuiltinID()); + + if (!Name.ends_with("printf") || Name.starts_with("v")) + return false; + + StringRef Prefix = Name.drop_back(6); + + if (Prefix.ends_with("w")) + Prefix = Prefix.drop_back(1); + + return Prefix.empty() || Prefix == "k" || Prefix == "f" || Prefix == "sn"; +} + +// This matcher requires that it is known that the callee `isNormalPrintf`. +// Then if the format string is a string literal, this matcher matches when at +// least one string argument is unsafe. If the format is not a string literal, +// this matcher matches when at least one pointer type argument is unsafe. +AST_MATCHER_P(CallExpr, hasUnsafePrintfStringArg, + clang::ast_matchers::internal::Matcher, + UnsafeStringArgMatcher) { + // Determine what printf it is: + const Expr *FirstArg = Node.getArg(0); + ASTContext &Ctx = Finder->getASTContext(); + + if (isa(FirstArg->IgnoreParenImpCasts())) { + // It is a printf/kprintf. And, the format is a string literal: + bool isKprintf = false; + const Expr *UnsafeArg; + + if (auto *Callee = Node.getDirectCallee()) + if (auto *II = Callee->getIdentifier()) + isKprintf = II->getName() == "kprintf"; + if (hasUnsafeFormatOrSArg(&Node, UnsafeArg, 0, Ctx, isKprintf)) + return UnsafeStringArgMatcher.matches(*UnsafeArg, Finder, Builder); + return false; + } + + QualType PtrTy = FirstArg->getType(); + + assert(PtrTy->isPointerType()); + + QualType PteTy = (cast(PtrTy))->getPointeeType(); + + if (!Ctx.getFILEType().isNull() /* If `FILE *` is not ever in the ASTContext, + there can't be any file pointer then */ + && PteTy.getCanonicalType() == Ctx.getFILEType().getCanonicalType()) { + // It is a fprintf: + const Expr *UnsafeArg; + + if (hasUnsafeFormatOrSArg(&Node, UnsafeArg, 1, Ctx, false)) + return UnsafeStringArgMatcher.matches(*UnsafeArg, Finder, Builder); + return false; + } + + const Expr *SecondArg = Node.getArg(1); + + if (SecondArg->getType()->isIntegerType()) { + // It is a snprintf: + const Expr *UnsafeArg; + + if (hasUnsafeFormatOrSArg(&Node, UnsafeArg, 2, Ctx, false)) + return UnsafeStringArgMatcher.matches(*UnsafeArg, Finder, Builder); + return false; + } + // It is printf but the format string is passed by pointer. The only thing we + // can do is to require all pointers to be null-terminated: + for (auto Arg : Node.arguments()) + if (Arg->getType()->isPointerType() && !isNullTermPointer(Arg)) + if (UnsafeStringArgMatcher.matches(*Arg, Finder, Builder)) + return true; + return false; +} + +// This matcher requires that it is known that the callee `isNormalPrintf`. +// Then it matches if the first two arguments of the call is a pointer and an +// integer and they are not in a safe pattern. +// +// For the first two arguments: `ptr` and `size`, they are safe if in the +// following patterns: +// ptr := DRE.data(); +// size:= DRE.size()/DRE.size_bytes() +// And DRE is a hardened container or view. +AST_MATCHER(CallExpr, hasUnsafeSnprintfBuffer) { + if (Node.getNumArgs() < 3) + return false; // not an snprintf call + + const Expr *Buf = Node.getArg(0), *Size = Node.getArg(1); + + if (!Buf->getType()->isPointerType() || !Size->getType()->isIntegerType()) + return false; // not an snprintf call + + static StringRef SizedObjs[] = {"span", "array", "vector", + "basic_string_view", "basic_string"}; + Buf = Buf->IgnoreParenImpCasts(); + Size = Size->IgnoreParenImpCasts(); + if (auto *MCEPtr = dyn_cast(Buf)) + if (auto *MCESize = dyn_cast(Size)) { + auto *DREOfPtr = dyn_cast( + MCEPtr->getImplicitObjectArgument()->IgnoreParenImpCasts()); + auto *DREOfSize = dyn_cast( + MCESize->getImplicitObjectArgument()->IgnoreParenImpCasts()); + + if (!DREOfPtr || !DREOfSize) + return true; // not in safe pattern + if (DREOfPtr->getDecl() != DREOfSize->getDecl()) + return true; // not in safe pattern + if (MCEPtr->getMethodDecl()->getName() != "data") + return true; // not in safe pattern + + if (MCESize->getMethodDecl()->getName() == "size_bytes" || + // Note here the pointer must be a pointer-to-char type unless there + // is explicit casting. If there is explicit casting, this branch + // is unreachable. Thus, at this branch "size" and "size_bytes" are + // equivalent as the pointer is a char pointer: + MCESize->getMethodDecl()->getName() == "size") + for (StringRef SizedObj : SizedObjs) + if (MCEPtr->getRecordDecl()->isInStdNamespace() && + MCEPtr->getRecordDecl()->getCanonicalDecl()->getName() == + SizedObj) + return false; // It is in fact safe + } + return true; // ptr and size are not in safe pattern +} +} // namespace libc_func_matchers } // namespace clang::ast_matchers namespace { @@ -760,6 +1184,10 @@ class SpanTwoParamConstructorGadget : public WarningGadget { .bind(SpanTwoParamConstructorTag)); } + static Matcher matcher(const UnsafeBufferUsageHandler *Handler) { + return stmt(unless(ignoreUnsafeBufferInContainer(Handler)), matcher()); + } + void handleUnsafeOperation(UnsafeBufferUsageHandler &Handler, bool IsRelatedToDecl, ASTContext &Ctx) const override { @@ -1030,6 +1458,98 @@ class DataInvocationGadget : public WarningGadget { DeclUseList getClaimedVarUseSites() const override { return {}; } }; +class UnsafeLibcFunctionCallGadget : public WarningGadget { + const CallExpr *const Call; + const Expr *UnsafeArg = nullptr; + constexpr static const char *const Tag = "UnsafeLibcFunctionCall"; + // Extra tags for additional information: + constexpr static const char *const UnsafeSprintfTag = + "UnsafeLibcFunctionCall_sprintf"; + constexpr static const char *const UnsafeSizedByTag = + "UnsafeLibcFunctionCall_sized_by"; + constexpr static const char *const UnsafeStringTag = + "UnsafeLibcFunctionCall_string"; + constexpr static const char *const UnsafeVaListTag = + "UnsafeLibcFunctionCall_va_list"; + + enum UnsafeKind { + OTHERS = 0, // no specific information, the callee function is unsafe + SPRINTF = 1, // never call `-sprintf`s, call `-snprintf`s instead. + SIZED_BY = + 2, // the first two arguments of `snprintf` function have + // "__sized_by" relation but they do not conform to safe patterns + STRING = 3, // an argument is a pointer-to-char-as-string but does not + // guarantee null-termination + VA_LIST = 4, // one of the `-printf`s function that take va_list, which is + // considered unsafe as it is not compile-time check + } WarnedFunKind = OTHERS; + +public: + UnsafeLibcFunctionCallGadget(const MatchFinder::MatchResult &Result) + : WarningGadget(Kind::UnsafeLibcFunctionCall), + Call(Result.Nodes.getNodeAs(Tag)) { + if (Result.Nodes.getNodeAs(UnsafeSprintfTag)) + WarnedFunKind = SPRINTF; + else if (auto *E = Result.Nodes.getNodeAs(UnsafeStringTag)) { + WarnedFunKind = STRING; + UnsafeArg = E; + } else if (Result.Nodes.getNodeAs(UnsafeSizedByTag)) { + WarnedFunKind = SIZED_BY; + UnsafeArg = Call->getArg(0); + } else if (Result.Nodes.getNodeAs(UnsafeVaListTag)) + WarnedFunKind = VA_LIST; + } + + static Matcher matcher(const UnsafeBufferUsageHandler *Handler) { + return stmt(unless(ignoreUnsafeLibcCall(Handler)), + anyOf( + callExpr( + callee(functionDecl(anyOf( + // Match a predefined unsafe libc + // function: + functionDecl(libc_func_matchers::isPredefinedUnsafeLibcFunc()), + // Match a call to one of the `v*printf` functions + // taking va-list, which cannot be checked at + // compile-time: + functionDecl(libc_func_matchers::isUnsafeVaListPrintfFunc()) + .bind(UnsafeVaListTag), + // Match a call to a `sprintf` function, which is never + // safe: + functionDecl(libc_func_matchers::isUnsafeSprintfFunc()) + .bind(UnsafeSprintfTag)))), + // (unless the call has a sole string literal argument): + unless( + allOf(hasArgument(0, expr(stringLiteral())), hasNumArgs(1)))), + + // The following two cases require checking against actual + // arguments of the call: + + // Match a call to an `snprintf` function. And first two + // arguments of the call (that describe a buffer) are not in + // safe patterns: + callExpr(callee(functionDecl(libc_func_matchers::isNormalPrintfFunc())), + libc_func_matchers::hasUnsafeSnprintfBuffer()) + .bind(UnsafeSizedByTag), + // Match a call to a `printf` function, which can be safe if + // all arguments are null-terminated: + callExpr(callee(functionDecl(libc_func_matchers::isNormalPrintfFunc())), + libc_func_matchers::hasUnsafePrintfStringArg( + expr().bind(UnsafeStringTag))))); + } + + const Stmt *getBaseStmt() const { return Call; } + + SourceLocation getSourceLoc() const override { return Call->getBeginLoc(); } + + void handleUnsafeOperation(UnsafeBufferUsageHandler &Handler, + bool IsRelatedToDecl, + ASTContext &Ctx) const override { + Handler.handleUnsafeLibcCall(Call, WarnedFunKind, Ctx, UnsafeArg); + } + + DeclUseList getClaimedVarUseSites() const override { return {}; } +}; + // Represents expressions of the form `DRE[*]` in the Unspecified Lvalue // Context (see `isInUnspecifiedLvalueContext`). // Note here `[]` is the built-in subscript operator. @@ -1452,10 +1972,9 @@ findGadgets(const Decl *D, const UnsafeBufferUsageHandler &Handler, #define WARNING_GADGET(x) \ allOf(x ## Gadget::matcher().bind(#x), \ notInSafeBufferOptOut(&Handler)), -#define WARNING_CONTAINER_GADGET(x) \ - allOf(x ## Gadget::matcher().bind(#x), \ - notInSafeBufferOptOut(&Handler), \ - unless(ignoreUnsafeBufferInContainer(&Handler))), +#define WARNING_OPTIONAL_GADGET(x) \ + allOf(x ## Gadget::matcher(&Handler).bind(#x), \ + notInSafeBufferOptOut(&Handler)), #include "clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def" // Avoid a hanging comma. unless(stmt()) diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 04dc436eb1b9c..1448069173b5f 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -68,6 +68,10 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector &Features, HasSPE = true; LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else if (Feature == "+frsqrte") { + HasFrsqrte = true; + } else if (Feature == "+frsqrtes") { + HasFrsqrtes = true; } else if (Feature == "-hard-float") { FloatABI = SoftFloat; } else if (Feature == "+paired-vector-memops") { @@ -402,9 +406,18 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__VEC__", "10206"); Builder.defineMacro("__ALTIVEC__"); } - if (HasSPE) { + if (HasSPE) Builder.defineMacro("__SPE__"); + if (HasSPE || FloatABI == SoftFloat) Builder.defineMacro("__NO_FPRS__"); + if (FloatABI == SoftFloat) { + Builder.defineMacro("_SOFT_FLOAT"); + Builder.defineMacro("_SOFT_DOUBLE"); + } else { + if (HasFrsqrte) + Builder.defineMacro("__RSQRTE__"); + if (HasFrsqrtes) + Builder.defineMacro("__RSQRTEF__"); } if (HasVSX) Builder.defineMacro("__VSX__"); @@ -439,14 +452,10 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, // FIXME: The following are not yet generated here by Clang, but are // generated by GCC: // - // _SOFT_FLOAT_ // __RECIP_PRECISION__ // __APPLE_ALTIVEC__ // __RECIP__ // __RECIPF__ - // __RSQRTE__ - // __RSQRTEF__ - // _SOFT_DOUBLE_ // __NO_LWSYNC__ // __CMODEL_MEDIUM__ // __CMODEL_LARGE__ diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 6d5d8dd54d013..b0833d30550af 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -73,6 +73,8 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { bool HasExtDiv = false; bool HasP9Vector = false; bool HasSPE = false; + bool HasFrsqrte = false; + bool HasFrsqrtes = false; bool PairedVectorMemops = false; bool HasP10Vector = false; bool HasPCRelativeMemops = false; diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index a9cbdb7b10dff..62c382b67ad14 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -306,6 +306,7 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasAVX10_1_512 = true; } else if (Feature == "+avx10.2-256") { HasAVX10_2 = true; + HasFullBFloat16 = true; } else if (Feature == "+avx10.2-512") { HasAVX10_2_512 = true; } else if (Feature == "+avx512cd") { diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h index 08730a6a6672a..b8036cf6e6a30 100644 --- a/clang/lib/CodeGen/CGBuilder.h +++ b/clang/lib/CodeGen/CGBuilder.h @@ -14,6 +14,7 @@ #include "CodeGenTypeCache.h" #include "llvm/Analysis/Utils/Local.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/GEPNoWrapFlags.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Type.h" @@ -334,9 +335,10 @@ class CGBuilderTy : public CGBuilderBaseTy { Address CreateGEP(Address Addr, ArrayRef IdxList, llvm::Type *ElementType, CharUnits Align, - const Twine &Name = "") { + const Twine &Name = "", + llvm::GEPNoWrapFlags NW = llvm::GEPNoWrapFlags::none()) { llvm::Value *Ptr = emitRawPointerFromAddress(Addr); - return RawAddress(CreateGEP(Addr.getElementType(), Ptr, IdxList, Name), + return RawAddress(CreateGEP(Addr.getElementType(), Ptr, IdxList, Name, NW), ElementType, Align); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e4d169d2ad603..da7a1a55da531 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2538,6 +2538,9 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF, RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue) { + assert(!getContext().BuiltinInfo.isImmediate(BuiltinID) && + "Should not codegen for consteval builtins"); + const FunctionDecl *FD = GD.getDecl()->getAsFunction(); // See if we can constant fold this builtin. If so, don't emit it at all. // TODO: Extend this handling to all builtin calls that we can constant-fold. @@ -13481,6 +13484,95 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Int = Intrinsic::aarch64_neon_suqadd; return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); } + + case NEON::BI__builtin_neon_vluti2_laneq_bf16: + case NEON::BI__builtin_neon_vluti2_laneq_f16: + case NEON::BI__builtin_neon_vluti2_laneq_p16: + case NEON::BI__builtin_neon_vluti2_laneq_p8: + case NEON::BI__builtin_neon_vluti2_laneq_s16: + case NEON::BI__builtin_neon_vluti2_laneq_s8: + case NEON::BI__builtin_neon_vluti2_laneq_u16: + case NEON::BI__builtin_neon_vluti2_laneq_u8: { + Int = Intrinsic::aarch64_neon_vluti2_laneq; + llvm::Type *Tys[2]; + Tys[0] = Ty; + Tys[1] = GetNeonType(this, NeonTypeFlags(Type.getEltType(), false, + /*isQuad*/ false)); + return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vluti2_laneq"); + } + case NEON::BI__builtin_neon_vluti2q_laneq_bf16: + case NEON::BI__builtin_neon_vluti2q_laneq_f16: + case NEON::BI__builtin_neon_vluti2q_laneq_p16: + case NEON::BI__builtin_neon_vluti2q_laneq_p8: + case NEON::BI__builtin_neon_vluti2q_laneq_s16: + case NEON::BI__builtin_neon_vluti2q_laneq_s8: + case NEON::BI__builtin_neon_vluti2q_laneq_u16: + case NEON::BI__builtin_neon_vluti2q_laneq_u8: { + Int = Intrinsic::aarch64_neon_vluti2_laneq; + llvm::Type *Tys[2]; + Tys[0] = Ty; + Tys[1] = GetNeonType(this, NeonTypeFlags(Type.getEltType(), false, + /*isQuad*/ true)); + return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vluti2_laneq"); + } + case NEON::BI__builtin_neon_vluti2_lane_bf16: + case NEON::BI__builtin_neon_vluti2_lane_f16: + case NEON::BI__builtin_neon_vluti2_lane_p16: + case NEON::BI__builtin_neon_vluti2_lane_p8: + case NEON::BI__builtin_neon_vluti2_lane_s16: + case NEON::BI__builtin_neon_vluti2_lane_s8: + case NEON::BI__builtin_neon_vluti2_lane_u16: + case NEON::BI__builtin_neon_vluti2_lane_u8: { + Int = Intrinsic::aarch64_neon_vluti2_lane; + llvm::Type *Tys[2]; + Tys[0] = Ty; + Tys[1] = GetNeonType(this, NeonTypeFlags(Type.getEltType(), false, + /*isQuad*/ false)); + return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vluti2_lane"); + } + case NEON::BI__builtin_neon_vluti2q_lane_bf16: + case NEON::BI__builtin_neon_vluti2q_lane_f16: + case NEON::BI__builtin_neon_vluti2q_lane_p16: + case NEON::BI__builtin_neon_vluti2q_lane_p8: + case NEON::BI__builtin_neon_vluti2q_lane_s16: + case NEON::BI__builtin_neon_vluti2q_lane_s8: + case NEON::BI__builtin_neon_vluti2q_lane_u16: + case NEON::BI__builtin_neon_vluti2q_lane_u8: { + Int = Intrinsic::aarch64_neon_vluti2_lane; + llvm::Type *Tys[2]; + Tys[0] = Ty; + Tys[1] = GetNeonType(this, NeonTypeFlags(Type.getEltType(), false, + /*isQuad*/ true)); + return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vluti2_lane"); + } + case NEON::BI__builtin_neon_vluti4q_lane_p8: + case NEON::BI__builtin_neon_vluti4q_lane_s8: + case NEON::BI__builtin_neon_vluti4q_lane_u8: { + Int = Intrinsic::aarch64_neon_vluti4q_lane; + return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vluti4q_lane"); + } + case NEON::BI__builtin_neon_vluti4q_laneq_p8: + case NEON::BI__builtin_neon_vluti4q_laneq_s8: + case NEON::BI__builtin_neon_vluti4q_laneq_u8: { + Int = Intrinsic::aarch64_neon_vluti4q_laneq; + return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vluti4q_laneq"); + } + case NEON::BI__builtin_neon_vluti4q_lane_bf16_x2: + case NEON::BI__builtin_neon_vluti4q_lane_f16_x2: + case NEON::BI__builtin_neon_vluti4q_lane_p16_x2: + case NEON::BI__builtin_neon_vluti4q_lane_s16_x2: + case NEON::BI__builtin_neon_vluti4q_lane_u16_x2: { + Int = Intrinsic::aarch64_neon_vluti4q_lane_x2; + return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vluti4q_lane_x2"); + } + case NEON::BI__builtin_neon_vluti4q_laneq_bf16_x2: + case NEON::BI__builtin_neon_vluti4q_laneq_f16_x2: + case NEON::BI__builtin_neon_vluti4q_laneq_p16_x2: + case NEON::BI__builtin_neon_vluti4q_laneq_s16_x2: + case NEON::BI__builtin_neon_vluti4q_laneq_u16_x2: { + Int = Intrinsic::aarch64_neon_vluti4q_laneq_x2; + return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vluti4q_laneq_x2"); + } } } @@ -14728,6 +14820,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_storeups512_mask: return EmitX86MaskedStore(*this, Ops, Align(1)); + case X86::BI__builtin_ia32_storesbf16128_mask: case X86::BI__builtin_ia32_storesh128_mask: case X86::BI__builtin_ia32_storess128_mask: case X86::BI__builtin_ia32_storesd128_mask: @@ -14836,6 +14929,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_vfmaddph512_mask: case X86::BI__builtin_ia32_vfmaddph512_maskz: case X86::BI__builtin_ia32_vfmaddph512_mask3: + case X86::BI__builtin_ia32_vfmaddnepbh128: + case X86::BI__builtin_ia32_vfmaddnepbh256: + case X86::BI__builtin_ia32_vfmaddnepbh512: case X86::BI__builtin_ia32_vfmaddps512_mask: case X86::BI__builtin_ia32_vfmaddps512_maskz: case X86::BI__builtin_ia32_vfmaddps512_mask3: @@ -14920,6 +15016,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_loaddqudi512_mask: return EmitX86MaskedLoad(*this, Ops, Align(1)); + case X86::BI__builtin_ia32_loadsbf16128_mask: case X86::BI__builtin_ia32_loadsh128_mask: case X86::BI__builtin_ia32_loadss128_mask: case X86::BI__builtin_ia32_loadsd128_mask: @@ -16074,6 +16171,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_sqrtph256: case X86::BI__builtin_ia32_sqrtph: case X86::BI__builtin_ia32_sqrtph512: + case X86::BI__builtin_ia32_vsqrtnepbf16256: + case X86::BI__builtin_ia32_vsqrtnepbf16: + case X86::BI__builtin_ia32_vsqrtnepbf16512: case X86::BI__builtin_ia32_sqrtps512: case X86::BI__builtin_ia32_sqrtpd512: { if (Ops.size() == 2) { @@ -16293,6 +16393,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_fpclassps128_mask: case X86::BI__builtin_ia32_fpclassps256_mask: case X86::BI__builtin_ia32_fpclassps512_mask: + case X86::BI__builtin_ia32_vfpclasspbf16128_mask: + case X86::BI__builtin_ia32_vfpclasspbf16256_mask: + case X86::BI__builtin_ia32_vfpclasspbf16512_mask: case X86::BI__builtin_ia32_fpclassph128_mask: case X86::BI__builtin_ia32_fpclassph256_mask: case X86::BI__builtin_ia32_fpclassph512_mask: @@ -16307,6 +16410,15 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID; switch (BuiltinID) { default: llvm_unreachable("Unsupported intrinsic!"); + case X86::BI__builtin_ia32_vfpclasspbf16128_mask: + ID = Intrinsic::x86_avx10_fpclass_nepbf16_128; + break; + case X86::BI__builtin_ia32_vfpclasspbf16256_mask: + ID = Intrinsic::x86_avx10_fpclass_nepbf16_256; + break; + case X86::BI__builtin_ia32_vfpclasspbf16512_mask: + ID = Intrinsic::x86_avx10_fpclass_nepbf16_512; + break; case X86::BI__builtin_ia32_fpclassph128_mask: ID = Intrinsic::x86_avx512fp16_fpclass_ph_128; break; @@ -16465,6 +16577,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_vcmppd256_round_mask: case X86::BI__builtin_ia32_vcmpps256_round_mask: case X86::BI__builtin_ia32_vcmpph256_round_mask: + case X86::BI__builtin_ia32_vcmppbf16512_mask: + case X86::BI__builtin_ia32_vcmppbf16256_mask: + case X86::BI__builtin_ia32_vcmppbf16128_mask: IsMaskFCmp = true; [[fallthrough]]; case X86::BI__builtin_ia32_cmpps: @@ -18700,6 +18815,10 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index", {}, false, true)); } + case Builtin::BI__builtin_hlsl_wave_is_first_lane: { + Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic(); + return EmitRuntimeCall(Intrinsic::getDeclaration(&CGM.getModule(), ID)); + } } return nullptr; } @@ -19489,6 +19608,9 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, F, {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2)), EmitScalarExpr(E->getArg(3))}); } + case AMDGPU::BI__builtin_amdgcn_s_prefetch_data: + return emitBuiltinWithOneOverloadedType<2>( + *this, E, Intrinsic::amdgcn_s_prefetch_data); default: return nullptr; } diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 6fa65e1916183..92e0cc43919ca 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -450,12 +450,12 @@ inline FnInfoOpts operator&(FnInfoOpts A, FnInfoOpts B) { llvm::to_underlying(B)); } -inline FnInfoOpts operator|=(FnInfoOpts A, FnInfoOpts B) { +inline FnInfoOpts &operator|=(FnInfoOpts &A, FnInfoOpts B) { A = A | B; return A; } -inline FnInfoOpts operator&=(FnInfoOpts A, FnInfoOpts B) { +inline FnInfoOpts &operator&=(FnInfoOpts &A, FnInfoOpts B) { A = A & B; return A; } diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 2f56355cff90e..c44f38ef02a3f 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -586,31 +586,50 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, PrioritizedCXXGlobalInits.size()); PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) || - getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR || + !isUniqueGVALinkage(getContext().GetGVALinkageForVariable(D)) || D->hasAttr()) { + // For vague linkage globals, put the initializer into its own global_ctors + // entry with the global as a comdat key. This ensures at most one + // initializer per DSO runs during DSO dynamic initialization. + // + // For ELF platforms, this is an important code size and startup time + // optimization. For dynamic, non-hidden symbols, the weak guard variable + // remains to ensure that other DSOs do not re-initialize the global. + // + // For PE-COFF platforms, there is no guard variable, and COMDAT + // associativity is the only way to ensure vauge linkage globals are + // initialized exactly once. + // + // MachO is the only remaining platform with no comdats that doesn't + // benefit from this optimization. The rest are mainly modeled on ELF + // behavior. + // + // C++ requires that inline global variables are initialized in source + // order, but this requirement does not exist for templated entities. + // llvm.global_ctors does not guarantee initialization order, so in + // general, Clang does not fully conform to the ordering requirement. + // However, in practice, LLVM emits global_ctors in the provided order, and + // users typically don't rely on ordering between inline globals in + // different headers which are then transitively included in varying order. + // Clang's current behavior is a practical tradeoff, since dropping the + // comdat would lead to unacceptable impact on code size and startup time. + // + // FIXME: Find a solution to guarantee source-order initialization of + // inline variables. + // // C++ [basic.start.init]p2: // Definitions of explicitly specialized class template static data // members have ordered initialization. Other class template static data // members (i.e., implicitly or explicitly instantiated specializations) // have unordered initialization. // - // As a consequence, we can put them into their own llvm.global_ctors entry. - // - // If the global is externally visible, put the initializer into a COMDAT - // group with the global being initialized. On most platforms, this is a - // minor startup time optimization. In the MS C++ ABI, there are no guard - // variables, so this COMDAT key is required for correctness. - // - // SelectAny globals will be comdat-folded. Put the initializer into a - // COMDAT group associated with the global, so the initializers get folded - // too. - I = DelayedCXXInitPosition.find(D); // CXXGlobalInits.size() is the lex order number for the next deferred // VarDecl. Use it when the current VarDecl is non-deferred. Although this // lex order number is shared between current VarDecl and some following // VarDecls, their order of insertion into `llvm.global_ctors` is the same // as the lexing order and the following stable sort would preserve such // order. + I = DelayedCXXInitPosition.find(D); unsigned LexOrder = I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second; AddGlobalCtor(Fn, 65535, LexOrder, COMDATKey); @@ -621,13 +640,13 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, addUsedGlobal(COMDATKey); } - // If we used a COMDAT key for the global ctor, the init function can be - // discarded if the global ctor entry is discarded. - // FIXME: Do we need to restrict this to ELF and Wasm? + // If comdats are in use and supported, place the initializer function into + // the comdat group of the global. In the MS ABI, initializers are mangled + // and have their own comdat, so we don't include them in the group for + // consistency with MSVC. llvm::Comdat *C = Addr->getComdat(); - if (COMDATKey && C && - (getTarget().getTriple().isOSBinFormatELF() || - getTarget().getTriple().isOSBinFormatWasm())) { + if (COMDATKey && C && getTriple().supportsCOMDAT() && + !getTarget().getCXXABI().isMicrosoft()) { Fn->setComdat(C); } } else { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index af11bc20a3b63..88fbbe6c4c965 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -36,6 +36,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/FixedPointBuilder.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GEPNoWrapFlags.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Intrinsics.h" @@ -2865,19 +2866,22 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, llvm::AtomicOrdering::SequentiallyConsistent); return isPre ? Builder.CreateBinOp(op, old, amt) : old; } - // Special case for atomic increment/decrement on floats + // Special case for atomic increment/decrement on floats. + // Bail out non-power-of-2-sized floating point types (e.g., x86_fp80). if (type->isFloatingType()) { - llvm::AtomicRMWInst::BinOp aop = - isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub; - llvm::Instruction::BinaryOps op = - isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub; - llvm::Value *amt = llvm::ConstantFP::get( - VMContext, llvm::APFloat(static_cast(1.0))); - llvm::AtomicRMWInst *old = - CGF.emitAtomicRMWInst(aop, LV.getAddress(), amt, - llvm::AtomicOrdering::SequentiallyConsistent); + llvm::Type *Ty = ConvertType(type); + if (llvm::has_single_bit(Ty->getScalarSizeInBits())) { + llvm::AtomicRMWInst::BinOp aop = + isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub; + llvm::Instruction::BinaryOps op = + isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub; + llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0); + llvm::AtomicRMWInst *old = + CGF.emitAtomicRMWInst(aop, LV.getAddress(), amt, + llvm::AtomicOrdering::SequentiallyConsistent); - return isPre ? Builder.CreateBinOp(op, old, amt) : old; + return isPre ? Builder.CreateBinOp(op, old, amt) : old; + } } value = EmitLoadOfLValue(LV, E->getExprLoc()); input = value; @@ -5756,7 +5760,12 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name) { llvm::Type *PtrTy = Ptr->getType(); - Value *GEPVal = Builder.CreateInBoundsGEP(ElemTy, Ptr, IdxList, Name); + + llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds(); + if (!SignedIndices && !IsSubtraction) + NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap(); + + Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags); // If the pointer overflow sanitizer isn't enabled, do nothing. if (!SanOpts.has(SanitizerKind::PointerOverflow)) @@ -5871,8 +5880,13 @@ Address CodeGenFunction::EmitCheckedInBoundsGEP( Address Addr, ArrayRef IdxList, llvm::Type *elementType, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, CharUnits Align, const Twine &Name) { - if (!SanOpts.has(SanitizerKind::PointerOverflow)) - return Builder.CreateInBoundsGEP(Addr, IdxList, elementType, Align, Name); + if (!SanOpts.has(SanitizerKind::PointerOverflow)) { + llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds(); + if (!SignedIndices && !IsSubtraction) + NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap(); + + return Builder.CreateGEP(Addr, IdxList, elementType, Align, Name, NWFlags); + } return RawAddress( EmitCheckedInBoundsGEP(Addr.getElementType(), Addr.emitRawPointer(*this), diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 4bd7b6ba58de0..b6e6555e63fca 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -295,13 +295,14 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) { // inside the record decl for (auto *FD : RD->fields()) { const auto *HLSLResAttr = FD->getAttr(); - const auto *HLSLResClassAttr = FD->getAttr(); - if (!HLSLResAttr || !HLSLResClassAttr) + const HLSLAttributedResourceType *AttrResType = + dyn_cast(FD->getType().getTypePtr()); + if (!HLSLResAttr || !AttrResType) continue; - llvm::hlsl::ResourceClass RC = HLSLResClassAttr->getResourceClass(); + llvm::hlsl::ResourceClass RC = AttrResType->getAttrs().ResourceClass; + bool IsROV = AttrResType->getAttrs().IsROV; llvm::hlsl::ResourceKind RK = HLSLResAttr->getResourceKind(); - bool IsROV = FD->hasAttr(); llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty); BufferResBinding Binding(D->getAttr()); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 55a4b97c160cd..40dcd74b7dd24 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -84,6 +84,7 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot) GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot) GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot) + GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) //===----------------------------------------------------------------------===// // End of reserved area for HLSL intrinsic getters. diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 34120486996fb..9cf597a65be04 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1149,10 +1149,8 @@ void CGOpenMPRuntime::emitUserDefinedReduction( /*IsCombiner=*/false); } UDRMap.try_emplace(D, Combiner, Initializer); - if (CGF) { - auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->CurFn); - Decls.second.push_back(D); - } + if (CGF) + FunctionUDRMap[CGF->CurFn].push_back(D); } std::pair @@ -1329,25 +1327,24 @@ llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction( void CGOpenMPRuntime::setLocThreadIdInsertPt(CodeGenFunction &CGF, bool AtCurrentPoint) { - auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); - assert(!Elem.second.ServiceInsertPt && "Insert point is set already."); + auto &Elem = OpenMPLocThreadIDMap[CGF.CurFn]; + assert(!Elem.ServiceInsertPt && "Insert point is set already."); llvm::Value *Undef = llvm::UndefValue::get(CGF.Int32Ty); if (AtCurrentPoint) { - Elem.second.ServiceInsertPt = new llvm::BitCastInst( - Undef, CGF.Int32Ty, "svcpt", CGF.Builder.GetInsertBlock()); + Elem.ServiceInsertPt = new llvm::BitCastInst(Undef, CGF.Int32Ty, "svcpt", + CGF.Builder.GetInsertBlock()); } else { - Elem.second.ServiceInsertPt = - new llvm::BitCastInst(Undef, CGF.Int32Ty, "svcpt"); - Elem.second.ServiceInsertPt->insertAfter(CGF.AllocaInsertPt); + Elem.ServiceInsertPt = new llvm::BitCastInst(Undef, CGF.Int32Ty, "svcpt"); + Elem.ServiceInsertPt->insertAfter(CGF.AllocaInsertPt); } } void CGOpenMPRuntime::clearLocThreadIdInsertPt(CodeGenFunction &CGF) { - auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); - if (Elem.second.ServiceInsertPt) { - llvm::Instruction *Ptr = Elem.second.ServiceInsertPt; - Elem.second.ServiceInsertPt = nullptr; + auto &Elem = OpenMPLocThreadIDMap[CGF.CurFn]; + if (Elem.ServiceInsertPt) { + llvm::Instruction *Ptr = Elem.ServiceInsertPt; + Elem.ServiceInsertPt = nullptr; Ptr->eraseFromParent(); } } @@ -1432,10 +1429,8 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, ThreadID = CGF.EmitLoadOfScalar(LVal, Loc); // If value loaded in entry block, cache it and use it everywhere in // function. - if (CGF.Builder.GetInsertBlock() == TopBlock) { - auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); - Elem.second.ThreadID = ThreadID; - } + if (CGF.Builder.GetInsertBlock() == TopBlock) + OpenMPLocThreadIDMap[CGF.CurFn].ThreadID = ThreadID; return ThreadID; } } @@ -1445,18 +1440,18 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, // kmpc_global_thread_num(ident_t *loc). // Generate thread id value and cache this value for use across the // function. - auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); - if (!Elem.second.ServiceInsertPt) + auto &Elem = OpenMPLocThreadIDMap[CGF.CurFn]; + if (!Elem.ServiceInsertPt) setLocThreadIdInsertPt(CGF); CGBuilderTy::InsertPointGuard IPG(CGF.Builder); - CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt); + CGF.Builder.SetInsertPoint(Elem.ServiceInsertPt); auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc); llvm::CallInst *Call = CGF.Builder.CreateCall( OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), OMPRTL___kmpc_global_thread_num), emitUpdateLocation(CGF, Loc)); Call->setCallingConv(CGF.getRuntimeCC()); - Elem.second.ThreadID = Call; + Elem.ThreadID = Call; return Call; } @@ -8640,8 +8635,7 @@ class MappableExprsHandler { const MapData &BaseData = CI == CE ? L : L1; OMPClauseMappableExprCommon::MappableExprComponentListRef SubData = SI == SE ? Components : Components1; - auto &OverlappedElements = OverlappedData.FindAndConstruct(&BaseData); - OverlappedElements.getSecond().push_back(SubData); + OverlappedData[&BaseData].push_back(SubData); } } } @@ -9316,10 +9310,8 @@ void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D, MapperCGF.EmitBlock(DoneBB, /*IsFinished=*/true); MapperCGF.FinishFunction(); UDMMap.try_emplace(D, Fn); - if (CGF) { - auto &Decls = FunctionUDMMap.FindAndConstruct(CGF->CurFn); - Decls.second.push_back(D); - } + if (CGF) + FunctionUDMMap[CGF->CurFn].push_back(D); } /// Emit the array initialization or deletion portion for user-defined mapper @@ -11682,9 +11674,7 @@ CGOpenMPRuntime::LastprivateConditionalRAII::~LastprivateConditionalRAII() { Address CGOpenMPRuntime::emitLastprivateConditionalInit(CodeGenFunction &CGF, const VarDecl *VD) { ASTContext &C = CGM.getContext(); - auto I = LastprivateConditionalToTypes.find(CGF.CurFn); - if (I == LastprivateConditionalToTypes.end()) - I = LastprivateConditionalToTypes.try_emplace(CGF.CurFn).first; + auto I = LastprivateConditionalToTypes.try_emplace(CGF.CurFn).first; QualType NewType; const FieldDecl *VDField; const FieldDecl *FiredField; diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 7158a06e6bc3b..b138c87a85349 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -752,7 +752,7 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { } break; case attr::CXXAssume: { const Expr *Assumption = cast(A)->getAssumption(); - if (getLangOpts().CXXAssumptions && + if (getLangOpts().CXXAssumptions && Builder.GetInsertBlock() && !Assumption->HasSideEffects(getContext())) { llvm::Value *AssumptionVal = EvaluateExprAsBool(Assumption); Builder.CreateAssumption(AssumptionVal); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 0cde8a192eda0..fb1eb72d9f340 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -442,7 +442,10 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { continue; const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); - if (!Method->getCanonicalDecl()->isInlined()) + const FunctionDecl *FD = Method->getDefinition(); + const bool IsInlined = + Method->getCanonicalDecl()->isInlined() || (FD && FD->isInlined()); + if (!IsInlined) continue; StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl()); @@ -2279,8 +2282,18 @@ bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass( if (CGM.getCodeGenOpts().ForceEmitVTables) return true; - // If we don't have any not emitted inline virtual function then we are safe - // to emit an available_externally copy of vtable. + // A speculative vtable can only be generated if all virtual inline functions + // defined by this class are emitted. The vtable in the final program contains + // for each virtual inline function not used in the current TU a function that + // is equivalent to the unused function. The function in the actual vtable + // does not have to be declared under the same symbol (e.g., a virtual + // destructor that can be substituted with its base class's destructor). Since + // inline functions are emitted lazily and this emissions does not account for + // speculative emission of a vtable, we might generate a speculative vtable + // with references to inline functions that are not emitted under that name. + // This can lead to problems when devirtualizing a call to such a function, + // that result in linking errors. Hence, if there are any unused virtual + // inline function, we cannot emit the speculative vtable. // FIXME we can still emit a copy of the vtable if we // can emit definition of the inline functions. if (hasAnyUnusedVirtualInlineFunction(RD)) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 64f23d43e87ee..16f9b629fc538 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -126,7 +126,7 @@ ToolChain::executeToolChainProgram(StringRef Executable) const { "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected " "an integer, got '" + *Str + "'"); - SecondsToWait = std::min(SecondsToWait, 0); // infinite + SecondsToWait = std::max(SecondsToWait, 0); // infinite } if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects, SecondsToWait, /*MemoryLimit=*/0, &ErrorMessage)) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index baac1215215b9..3fe4ce5d893b8 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4853,7 +4853,8 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, // This controls whether or not we perform JustMyCode instrumentation. if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) { - if (TC.getTriple().isOSBinFormatELF() || D.IsCLMode()) { + if (TC.getTriple().isOSBinFormatELF() || + TC.getTriple().isWindowsMSVCEnvironment()) { if (DebugInfoKind >= llvm::codegenoptions::DebugInfoConstructor) CmdArgs.push_back("-fjmc"); else if (D.IsCLMode()) @@ -6785,8 +6786,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--offload-new-driver"); } - SanitizeArgs.addArgs(TC, Args, CmdArgs, InputType); - const XRayArgs &XRay = TC.getXRayArgs(); XRay.addArgs(TC, Args, CmdArgs, InputType); @@ -7676,6 +7675,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + // This needs to run after -Xclang argument forwarding to pick up the target + // features enabled through -Xclang -target-feature flags. + SanitizeArgs.addArgs(TC, Args, CmdArgs, InputType); + // With -save-temps, we want to save the unoptimized bitcode output from the // CompileJobAction, use -disable-llvm-passes to get pristine IR generated // by the frontend. diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 3f9885b196ec5..ef44ffa5594da 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -17,6 +17,7 @@ #include "clang/Driver/InputInfo.h" #include "clang/Driver/Options.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Config/llvm-config.h" // for LLVM_HOST_TRIPLE #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatAdapters.h" diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp index c81a7ed170296..85f40893e5424 100644 --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -15,6 +15,7 @@ #include "clang/Driver/InputInfo.h" #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" +#include "llvm/Config/llvm-config.h" // for LLVM_HOST_TRIPLE #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp index 22103eb50803a..48d824171303c 100644 --- a/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -272,6 +272,8 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(D.getLTOMode() == LTOK_Thin ? "--lto=thin" : "--lto=full"); + AddLTOFlag("-emit-jump-table-sizes-section"); + if (UseJMC) AddLTOFlag("-enable-jmc-instrument"); @@ -354,9 +356,7 @@ toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const llvm::Triple &Triple, SmallString<512> SDKLibDir(SDKRootDir); llvm::sys::path::append(SDKLibDir, "target/lib"); - if (!Args.hasArg(options::OPT_nostdlib) && - !Args.hasArg(options::OPT_nodefaultlibs) && - !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) && + if (!Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_ast) && !llvm::sys::fs::exists(SDKLibDir)) { @@ -486,6 +486,12 @@ void toolchains::PS4PS5Base::addClangTargetOptions( else CC1Args.push_back("-fvisibility-externs-nodllstorageclass=keep"); } + + // Enable jump table sizes section for PS5. + if (getTriple().isPS5()) { + CC1Args.push_back("-mllvm"); + CC1Args.push_back("-emit-jump-table-sizes-section"); + } } // PS4 toolchain. diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index 9aacda5fd5702..9aec11e69fde1 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -15,6 +15,7 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "llvm/Config/llvm-config.h" // for LLVM_VERSION_STRING #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index d77bb1d424f7c..06ce5ed6a6475 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -276,6 +276,19 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( DeclarationFragments Fragments; + if (const MacroQualifiedType *MQT = dyn_cast(T)) { + Fragments.append( + getFragmentsForType(MQT->getUnderlyingType(), Context, After)); + return Fragments; + } + + if (const AttributedType *AT = dyn_cast(T)) { + // FIXME: Serialize Attributes correctly + Fragments.append( + getFragmentsForType(AT->getModifiedType(), Context, After)); + return Fragments; + } + // An ElaboratedType is a sugar for types that are referred to using an // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a // qualified name, e.g., `N::M::type`, or both. diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 64e936f627d43..6a1cf61659fd9 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -137,9 +137,8 @@ class AnnotatingParser { private: ScopeType getScopeType(const FormatToken &Token) const { switch (Token.getType()) { - case TT_FunctionLBrace: case TT_LambdaLBrace: - return ST_Function; + return ST_ChildBlock; case TT_ClassLBrace: case TT_StructLBrace: case TT_UnionLBrace: @@ -400,7 +399,8 @@ class AnnotatingParser { OpeningParen.Previous->MatchingParen->isOneOf( TT_ObjCBlockLParen, TT_FunctionTypeLParen)) { Contexts.back().IsExpression = false; - } else if (!Line.MustBeDeclaration && !Line.InPPDirective) { + } else if (!Line.MustBeDeclaration && + (!Line.InPPDirective || (Line.InMacroBody && !Scopes.empty()))) { bool IsForOrCatch = OpeningParen.Previous && OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch); @@ -3588,8 +3588,7 @@ static FormatToken *getFunctionName(const AnnotatedLine &Line, // Make sure the name is followed by a pair of parentheses. if (Name) { - if (Tok->is(tok::l_paren) && Tok->isNot(TT_FunctionTypeLParen) && - Tok->MatchingParen) { + if (Tok->is(tok::l_paren) && Tok->is(TT_Unknown) && Tok->MatchingParen) { OpeningParen = Tok; return Name; } @@ -3650,11 +3649,21 @@ static bool isCtorOrDtorName(const FormatToken *Tok) { } void TokenAnnotator::annotate(AnnotatedLine &Line) { - AnnotatingParser Parser(Style, Line, Keywords, Scopes); + if (!Line.InMacroBody) + MacroBodyScopes.clear(); + + auto &ScopeStack = Line.InMacroBody ? MacroBodyScopes : Scopes; + AnnotatingParser Parser(Style, Line, Keywords, ScopeStack); Line.Type = Parser.parseLine(); - for (auto &Child : Line.Children) - annotate(*Child); + if (!Line.Children.empty()) { + ScopeStack.push_back(ST_ChildBlock); + for (auto &Child : Line.Children) + annotate(*Child); + // ScopeStack can become empty if Child has an unmatched `}`. + if (!ScopeStack.empty()) + ScopeStack.pop_back(); + } // With very deep nesting, ExpressionParser uses lots of stack and the // formatting algorithm is very slow. We're not going to do a good job here @@ -3672,7 +3681,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { if (IsCpp) { FormatToken *OpeningParen = nullptr; auto *Tok = getFunctionName(Line, OpeningParen); - if (Tok && ((!Scopes.empty() && Scopes.back() == ST_Class) || + if (Tok && ((!ScopeStack.empty() && ScopeStack.back() == ST_Class) || Line.endsWith(TT_FunctionLBrace) || isCtorOrDtorName(Tok))) { Tok->setFinalizedType(TT_CtorDtorDeclName); assert(OpeningParen); diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h index f4f2bba0eb217..5a02030e5ba7f 100644 --- a/clang/lib/Format/TokenAnnotator.h +++ b/clang/lib/Format/TokenAnnotator.h @@ -36,11 +36,11 @@ enum LineType { }; enum ScopeType { + // Contained in child block. + ST_ChildBlock, // Contained in class declaration/definition. ST_Class, - // Contained within function definition. - ST_Function, - // Contained within other scope block (loop, if/else, etc). + // Contained within other scope block (function, loop, if/else, etc). ST_Other, }; @@ -269,7 +269,7 @@ class TokenAnnotator { const AdditionalKeywords &Keywords; - SmallVector Scopes; + SmallVector Scopes, MacroBodyScopes; }; } // end namespace format diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 0d42a6c2bfb5c..1727ed93822b1 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -570,7 +570,8 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in, Keywords.kw_as)); ProbablyBracedList = - ProbablyBracedList || (IsCpp && NextTok->is(tok::l_paren)); + ProbablyBracedList || (IsCpp && (PrevTok->Tok.isLiteral() || + NextTok->is(tok::l_paren))); // If there is a comma, semicolon or right paren after the closing // brace, we assume this is a braced initializer list. @@ -609,8 +610,9 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { ProbablyBracedList = NextTok->isNot(tok::l_square); } - // Cpp macro definition body containing nonempty braced list or block: + // Cpp macro definition body that is a nonempty braced list or block: if (IsCpp && Line->InMacroBody && PrevTok != FormatTok && + !FormatTok->Previous && NextTok->is(tok::eof) && // A statement can end with only `;` (simple statement), a block // closing brace (compound statement), or `:` (label statement). // If PrevTok is a block opening brace, Tok ends an empty block. diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 9f5d09e33ce24..64f90c493c105 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -26,6 +26,7 @@ #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" #include "clang/Serialization/ModuleFile.h" +#include "llvm/Config/llvm-config.h" // for LLVM_HOST_TRIPLE #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 61260a3379828..9a0fdb175ff29 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -671,10 +671,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, LangOpts.CPlusPlus23 ? "202211L" : LangOpts.CPlusPlus17 ? "201603L" : "200907"); - Builder.defineMacro("__cpp_static_assert", LangOpts.CPlusPlus26 ? "202306L" - : LangOpts.CPlusPlus17 - ? "201411L" - : "200410"); + // C++17 / C++26 static_assert supported as an extension in earlier language + // modes, so we use the C++26 value. + Builder.defineMacro("__cpp_static_assert", "202306L"); Builder.defineMacro("__cpp_decltype", "200707L"); Builder.defineMacro("__cpp_attributes", "200809L"); Builder.defineMacro("__cpp_rvalue_references", "200610L"); diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 5a62538792f30..e928b5b142827 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -147,10 +147,12 @@ set(x86_files amxcomplexintrin.h amxfp16intrin.h amxintrin.h + avx10_2_512bf16intrin.h avx10_2_512convertintrin.h avx10_2_512minmaxintrin.h avx10_2_512niintrin.h avx10_2_512satcvtintrin.h + avx10_2bf16intrin.h avx10_2convertintrin.h avx10_2minmaxintrin.h avx10_2niintrin.h diff --git a/clang/lib/Headers/avx10_2_512bf16intrin.h b/clang/lib/Headers/avx10_2_512bf16intrin.h new file mode 100644 index 0000000000000..392b7ae770c5b --- /dev/null +++ b/clang/lib/Headers/avx10_2_512bf16intrin.h @@ -0,0 +1,565 @@ +/*===----------- avx10_2_512bf16intrin.h - AVX10-BF16 intrinsics ---------=== + * + * 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 __IMMINTRIN_H +#error \ + "Never use directly; include instead." +#endif + +#ifdef __SSE2__ + +#ifndef __AVX10_2_512BF16INTRIN_H +#define __AVX10_2_512BF16INTRIN_H + +/* Define the default attributes for the functions in this file. */ +typedef __bf16 __m512bh_u __attribute__((__vector_size__(64), __aligned__(1))); + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS512 \ + __attribute__((__always_inline__, __nodebug__, __target__("avx10.2-512"), \ + __min_vector_width__(512))) + +static __inline __m512bh __DEFAULT_FN_ATTRS512 _mm512_setzero_pbh(void) { + return __builtin_bit_cast(__m512bh, _mm512_setzero_ps()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_undefined_pbh(void) { + return (__m512bh)__builtin_ia32_undef512(); +} + +static __inline __m512bh __DEFAULT_FN_ATTRS512 _mm512_set1_pbh(__bf16 bf) { + return (__m512bh)(__v32bf){bf, bf, bf, bf, bf, bf, bf, bf, bf, bf, bf, + bf, bf, bf, bf, bf, bf, bf, bf, bf, bf, bf, + bf, bf, bf, bf, bf, bf, bf, bf, bf, bf}; +} + +static __inline __m512bh __DEFAULT_FN_ATTRS512 _mm512_set_pbh( + __bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, __bf16 bf5, __bf16 bf6, + __bf16 bf7, __bf16 bf8, __bf16 bf9, __bf16 bf10, __bf16 bf11, __bf16 bf12, + __bf16 bf13, __bf16 bf14, __bf16 bf15, __bf16 bf16, __bf16 bf17, + __bf16 bf18, __bf16 bf19, __bf16 bf20, __bf16 bf21, __bf16 bf22, + __bf16 bf23, __bf16 bf24, __bf16 bf25, __bf16 bf26, __bf16 bf27, + __bf16 bf28, __bf16 bf29, __bf16 bf30, __bf16 bf31, __bf16 bf32) { + return (__m512bh)(__v32bf){bf32, bf31, bf30, bf29, bf28, bf27, bf26, bf25, + bf24, bf23, bf22, bf21, bf20, bf19, bf18, bf17, + bf16, bf15, bf14, bf13, bf12, bf11, bf10, bf9, + bf8, bf7, bf6, bf5, bf4, bf3, bf2, bf1}; +} + +#define _mm512_setr_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9, bf10, \ + bf11, bf12, bf13, bf14, bf15, bf16, bf17, bf18, bf19, \ + bf20, bf21, bf22, bf23, bf24, bf25, bf26, bf27, bf28, \ + bf29, bf30, bf31, bf32) \ + _mm512_set_pbh((bf32), (bf31), (bf30), (bf29), (bf28), (bf27), (bf26), \ + (bf25), (bf24), (bf23), (bf22), (bf21), (bf20), (bf19), \ + (bf18), (bf17), (bf16), (bf15), (bf14), (bf13), (bf12), \ + (bf11), (bf10), (bf9), (bf8), (bf7), (bf6), (bf5), (bf4), \ + (bf3), (bf2), (bf1)) + +static __inline__ __m512 __DEFAULT_FN_ATTRS512 +_mm512_castpbf16_ps(__m512bh __a) { + return (__m512)__a; +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS512 +_mm512_castpbf16_pd(__m512bh __a) { + return (__m512d)__a; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS512 +_mm512_castpbf16_si512(__m512bh __a) { + return (__m512i)__a; +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_castps_pbh(__m512 __a) { + return (__m512bh)__a; +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_castpd_pbh(__m512d __a) { + return (__m512bh)__a; +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_castsi512_pbh(__m512i __a) { + return (__m512bh)__a; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS512 +_mm512_castpbf16512_pbh128(__m512bh __a) { + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS512 +_mm512_castpbf16512_pbh256(__m512bh __a) { + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_castpbf16128_pbh512(__m128bh __a) { + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_castpbf16256_pbh512(__m256bh __a) { + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_zextpbf16128_pbh512(__m128bh __a) { + return __builtin_shufflevector( + __a, (__v8bf)_mm_setzero_pbh(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_zextpbf16256_pbh512(__m256bh __a) { + return __builtin_shufflevector(__a, (__v16bf)_mm256_setzero_pbh(), 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_abs_pbh(__m512bh __A) { + return (__m512bh)_mm512_and_epi32(_mm512_set1_epi32(0x7FFF7FFF), + (__m512i)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_load_pbh(void const *__p) { + return *(const __m512bh *)__p; +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_loadu_pbh(void const *__p) { + struct __loadu_pbh { + __m512bh_u __v; + } __attribute__((__packed__, __may_alias__)); + return ((const struct __loadu_pbh *)__p)->__v; +} + +static __inline__ void __DEFAULT_FN_ATTRS512 _mm512_store_pbh(void *__P, + __m512bh __A) { + *(__m512bh *)__P = __A; +} + +static __inline__ void __DEFAULT_FN_ATTRS512 _mm512_storeu_pbh(void *__P, + __m512bh __A) { + struct __storeu_pbh { + __m512bh_u __v; + } __attribute__((__packed__, __may_alias__)); + ((struct __storeu_pbh *)__P)->__v = __A; +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_blend_pbh(__mmask32 __U, __m512bh __A, __m512bh __W) { + return (__m512bh)__builtin_ia32_selectpbf_512((__mmask32)__U, (__v32bf)__W, + (__v32bf)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_permutex2var_pbh(__m512bh __A, __m512i __I, __m512bh __B) { + return (__m512bh)__builtin_ia32_vpermi2varhi512((__v32hi)__A, (__v32hi)__I, + (__v32hi)__B); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_permutexvar_pbh(__m512i __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_permvarhi512((__v32hi)__B, (__v32hi)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_addne_pbh(__m512bh __A, __m512bh __B) { + return (__m512bh)((__v32bf)__A + (__v32bf)__B); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_addne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_addne_pbh(__A, __B), (__v32bf)__W); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_addne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_addne_pbh(__A, __B), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_subne_pbh(__m512bh __A, __m512bh __B) { + return (__m512bh)((__v32bf)__A - (__v32bf)__B); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_subne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_subne_pbh(__A, __B), (__v32bf)__W); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_subne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_subne_pbh(__A, __B), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mulne_pbh(__m512bh __A, __m512bh __B) { + return (__m512bh)((__v32bf)__A * (__v32bf)__B); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_mulne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_mulne_pbh(__A, __B), (__v32bf)__W); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_mulne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_mulne_pbh(__A, __B), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_divne_pbh(__m512bh __A, __m512bh __B) { + return (__m512bh)((__v32bf)__A / (__v32bf)__B); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_divne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_divne_pbh(__A, __B), (__v32bf)__W); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_divne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_divne_pbh(__A, __B), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_max_pbh(__m512bh __A, + __m512bh __B) { + return (__m512bh)__builtin_ia32_vmaxpbf16512((__v32bf)__A, (__v32bf)__B); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_max_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_max_pbh(__A, __B), (__v32bf)__W); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_max_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_max_pbh(__A, __B), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_min_pbh(__m512bh __A, + __m512bh __B) { + return (__m512bh)__builtin_ia32_vminpbf16512((__v32bf)__A, (__v32bf)__B); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_min_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_min_pbh(__A, __B), (__v32bf)__W); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_min_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_min_pbh(__A, __B), + (__v32bf)_mm512_setzero_pbh()); +} + +#define _mm512_cmp_pbh_mask(__A, __B, __P) \ + ((__mmask32)__builtin_ia32_vcmppbf16512_mask((__v32bf)(__m512bh)(__A), \ + (__v32bf)(__m512bh)(__B), \ + (int)(__P), (__mmask32) - 1)) + +#define _mm512_mask_cmp_pbh_mask(__U, __A, __B, __P) \ + ((__mmask32)__builtin_ia32_vcmppbf16512_mask((__v32bf)(__m512bh)(__A), \ + (__v32bf)(__m512bh)(__B), \ + (int)(__P), (__mmask32)(__U))) + +#define _mm512_mask_fpclass_pbh_mask(__U, __A, imm) \ + ((__mmask32)__builtin_ia32_vfpclasspbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__mmask32)(__U))) + +#define _mm512_fpclass_pbh_mask(__A, imm) \ + ((__mmask32)__builtin_ia32_vfpclasspbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__mmask32) - 1)) + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_scalef_pbh(__m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_vscalefpbf16512_mask( + (__v32bf)__A, (__v32bf)__B, (__v32bf)_mm512_undefined_pbh(), + (__mmask32)-1); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask_scalef_pbh( + __m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_vscalefpbf16512_mask( + (__v32bf)__A, (__v32bf)__B, (__v32bf)__W, (__mmask32)__U); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_scalef_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + return (__m512bh)__builtin_ia32_vscalefpbf16512_mask( + (__v32bf)__A, (__v32bf)__B, (__v32bf)_mm512_setzero_pbh(), + (__mmask32)__U); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_rcp_pbh(__m512bh __A) { + return (__m512bh)__builtin_ia32_vrcppbf16512_mask( + (__v32bf)__A, (__v32bf)_mm512_undefined_pbh(), (__mmask32)-1); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_rcp_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_vrcppbf16512_mask((__v32bf)__A, (__v32bf)__W, + (__mmask32)__U); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_rcp_pbh(__mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_vrcppbf16512_mask( + (__v32bf)__A, (__v32bf)_mm512_setzero_pbh(), (__mmask32)__U); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_getexp_pbh(__m512bh __A) { + return (__m512bh)__builtin_ia32_vgetexppbf16512_mask( + (__v32bf)__A, (__v32bf)_mm512_undefined_pbh(), (__mmask32)-1); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_getexp_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_vgetexppbf16512_mask( + (__v32bf)__A, (__v32bf)__W, (__mmask32)__U); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_getexp_pbh(__mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_vgetexppbf16512_mask( + (__v32bf)__A, (__v32bf)_mm512_setzero_pbh(), (__mmask32)__U); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_rsqrt_pbh(__m512bh __A) { + return (__m512bh)__builtin_ia32_vrsqrtpbf16512_mask( + (__v32bf)__A, (__v32bf)_mm512_undefined_pbh(), (__mmask32)-1); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_rsqrt_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_vrsqrtpbf16512_mask( + (__v32bf)__A, (__v32bf)__W, (__mmask32)__U); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_rsqrt_pbh(__mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_vrsqrtpbf16512_mask( + (__v32bf)__A, (__v32bf)_mm512_setzero_pbh(), (__mmask32)__U); +} + +#define _mm512_reducene_pbh(__A, imm) \ + ((__m512bh)__builtin_ia32_vreducenepbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__v32bf)_mm512_undefined_pbh(), \ + (__mmask32) - 1)) + +#define _mm512_mask_reducene_pbh(__W, __U, __A, imm) \ + ((__m512bh)__builtin_ia32_vreducenepbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__v32bf)(__m512bh)(__W), \ + (__mmask32)(__U))) + +#define _mm512_maskz_reducene_pbh(__U, __A, imm) \ + ((__m512bh)__builtin_ia32_vreducenepbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__v32bf)_mm512_setzero_pbh(), \ + (__mmask32)(__U))) + +#define _mm512_roundscalene_pbh(__A, imm) \ + ((__m512bh)__builtin_ia32_vrndscalenepbf16_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__v32bf)_mm512_setzero_pbh(), \ + (__mmask32) - 1)) + +#define _mm512_mask_roundscalene_pbh(__W, __U, __A, imm) \ + ((__m512bh)__builtin_ia32_vrndscalenepbf16_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__v32bf)(__m512bh)(__W), \ + (__mmask32)(__U))) + +#define _mm512_maskz_roundscalene_pbh(__U, __A, imm) \ + ((__m512bh)__builtin_ia32_vrndscalenepbf16_mask( \ + (__v32bf)(__m512bh)(__A), (int)(imm), (__v32bf)_mm512_setzero_pbh(), \ + (__mmask32)(__U))) + +#define _mm512_getmant_pbh(__A, __B, __C) \ + ((__m512bh)__builtin_ia32_vgetmantpbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v32bf)_mm512_undefined_pbh(), (__mmask32) - 1)) + +#define _mm512_mask_getmant_pbh(__W, __U, __A, __B, __C) \ + ((__m512bh)__builtin_ia32_vgetmantpbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v32bf)(__m512bh)(__W), (__mmask32)(__U))) + +#define _mm512_maskz_getmant_pbh(__U, __A, __B, __C) \ + ((__m512bh)__builtin_ia32_vgetmantpbf16512_mask( \ + (__v32bf)(__m512bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v32bf)_mm512_setzero_pbh(), (__mmask32)(__U))) + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_sqrt_pbh(__m512bh __A) { + return (__m512bh)__builtin_ia32_vsqrtnepbf16512((__v32bf)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_mask_sqrt_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, (__v32bf)_mm512_sqrt_pbh(__A), (__v32bf)__W); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_maskz_sqrt_pbh(__mmask32 __U, __m512bh __A) { + return (__m512bh)__builtin_ia32_selectpbf_512((__mmask32)__U, + (__v32bf)_mm512_sqrt_pbh(__A), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_fmaddne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_vfmaddnepbh512((__v32bf)__A, (__v32bf)__B, + (__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask_fmaddne_pbh( + __m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fmaddne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask3_fmaddne_pbh( + __m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fmaddne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_maskz_fmaddne_pbh( + __mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fmaddne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_fmsubne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_vfmaddnepbh512((__v32bf)__A, (__v32bf)__B, + -(__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask_fmsubne_pbh( + __m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fmsubne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask3_fmsubne_pbh( + __m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fmsubne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_maskz_fmsubne_pbh( + __mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fmsubne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_fnmaddne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_vfmaddnepbh512((__v32bf)__A, -(__v32bf)__B, + (__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask_fnmaddne_pbh( + __m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fnmaddne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask3_fnmaddne_pbh( + __m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fnmaddne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_maskz_fnmaddne_pbh( + __mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fnmaddne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)_mm512_setzero_pbh()); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 +_mm512_fnmsubne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_vfmaddnepbh512((__v32bf)__A, -(__v32bf)__B, + -(__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask_fnmsubne_pbh( + __m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fnmsubne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__A); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_mask3_fnmsubne_pbh( + __m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fnmsubne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)__C); +} + +static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_maskz_fnmsubne_pbh( + __mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + return (__m512bh)__builtin_ia32_selectpbf_512( + (__mmask32)__U, + _mm512_fnmsubne_pbh((__v32bf)__A, (__v32bf)__B, (__v32bf)__C), + (__v32bf)_mm512_setzero_pbh()); +} + +#undef __DEFAULT_FN_ATTRS512 + +#endif +#endif diff --git a/clang/lib/Headers/avx10_2bf16intrin.h b/clang/lib/Headers/avx10_2bf16intrin.h new file mode 100644 index 0000000000000..0a427b9b7418b --- /dev/null +++ b/clang/lib/Headers/avx10_2bf16intrin.h @@ -0,0 +1,1091 @@ +/*===-------------- avx10_2bf16intrin.h - AVX10-BF16 intrinsics ------------=== + * + * 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 __IMMINTRIN_H +#error \ + "Never use directly; include instead." +#endif + +#ifdef __SSE2__ + +#ifndef __AVX10_2BF16INTRIN_H +#define __AVX10_2BF16INTRIN_H + +typedef __bf16 __m128bh_u __attribute__((__vector_size__(16), __aligned__(1))); +typedef __bf16 __m256bh_u __attribute__((__vector_size__(32), __aligned__(1))); + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS256 \ + __attribute__((__always_inline__, __nodebug__, __target__("avx10.2-256"), \ + __min_vector_width__(256))) +#define __DEFAULT_FN_ATTRS128 \ + __attribute__((__always_inline__, __nodebug__, __target__("avx10.2-256"), \ + __min_vector_width__(128))) + +static __inline __m256bh __DEFAULT_FN_ATTRS256 _mm256_setzero_pbh(void) { + return __builtin_bit_cast(__m256bh, _mm256_setzero_ps()); +} + +static __inline __m128bh __DEFAULT_FN_ATTRS128 _mm_setzero_pbh(void) { + return __builtin_bit_cast(__m128bh, _mm_setzero_ps()); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS128 _mm_castpbf16_ps(__m128bh __a) { + return (__m128)__a; +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS256 +_mm256_castpbf16_ps(__m256bh __a) { + return (__m256)__a; +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS256 +_mm256_castpbf16_pd(__m256bh __a) { + return (__m256d)__a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS128 _mm_castpbf16_pd(__m128bh __a) { + return (__m128d)__a; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS128 +_mm_castpbf16_si128(__m128bh __a) { + return (__m128i)__a; +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS256 +_mm256_castpbf16_si256(__m256bh __a) { + return (__m256i)__a; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_castps_pbh(__m128 __a) { + return (__m128bh)__a; +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_castps_pbh(__m256 __a) { + return (__m256bh)__a; +} + +static __inline__ __bf16 __DEFAULT_FN_ATTRS128 _mm_cvtsbh_bf16(__m128bh __a) { + return __a[0]; +} + +static __inline__ __bf16 __DEFAULT_FN_ATTRS256 +_mm256_cvtsbh_bf16(__m256bh __a) { + return __a[0]; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_castpd_pbh(__m128d __a) { + return (__m128bh)__a; +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_castpd_pbh(__m256d __a) { + return (__m256bh)__a; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_castsi128_pbh(__m128i __a) { + return (__m128bh)__a; +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_castsi256_pbh(__m256i __a) { + return (__m256bh)__a; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS256 +_mm256_castpbf16256_pbh128(__m256bh __a) { + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_castpbf16128_pbh256(__m128bh __a) { + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, + -1, -1, -1, -1, -1); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_zextpbf16128_pbh256(__m128bh __a) { + return __builtin_shufflevector(__a, (__v8bf)_mm_setzero_pbh(), 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_undefined_pbh(void) { + return (__m256bh)__builtin_ia32_undef256(); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_load_sbh(void const *__dp) { + __m128bh src = (__v8bf)_mm_setzero_pbh(); + return (__m128bh)__builtin_ia32_loadsbf16128_mask((const __v8bf *)__dp, src, + 1); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_load_sbh(__m128bh __W, __mmask8 __U, const void *__A) { + __m128bh src = (__v8bf)__builtin_shufflevector( + (__v8bf)__W, (__v8bf)_mm_setzero_pbh(), 0, 8, 8, 8, 8, 8, 8, 8); + + return (__m128bh)__builtin_ia32_loadsbf16128_mask((const __v8bf *)__A, src, + __U & 1); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_load_sbh(__mmask8 __U, const void *__A) { + return (__m128bh)__builtin_ia32_loadsbf16128_mask( + (const __v8bf *)__A, (__v8bf)_mm_setzero_pbh(), __U & 1); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_load_pbh(void const *__p) { + return *(const __m256bh *)__p; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_load_pbh(void const *__p) { + return *(const __m128bh *)__p; +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_loadu_pbh(void const *__p) { + struct __loadu_pbh { + __m256bh_u __v; + } __attribute__((__packed__, __may_alias__)); + return ((const struct __loadu_pbh *)__p)->__v; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_loadu_pbh(void const *__p) { + struct __loadu_pbh { + __m128bh_u __v; + } __attribute__((__packed__, __may_alias__)); + return ((const struct __loadu_pbh *)__p)->__v; +} + +static __inline__ void __DEFAULT_FN_ATTRS128 _mm_store_sbh(void *__dp, + __m128bh __a) { + struct __mm_store_sbh_struct { + __bf16 __u; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_store_sbh_struct *)__dp)->__u = __a[0]; +} + +static __inline__ void __DEFAULT_FN_ATTRS128 _mm_mask_store_sbh(void *__W, + __mmask8 __U, + __m128bh __A) { + __builtin_ia32_storesbf16128_mask((__v8bf *)__W, __A, __U & 1); +} + +static __inline__ void __DEFAULT_FN_ATTRS256 _mm256_store_pbh(void *__P, + __m256bh __A) { + *(__m256bh *)__P = __A; +} + +static __inline__ void __DEFAULT_FN_ATTRS128 _mm_store_pbh(void *__P, + __m128bh __A) { + *(__m128bh *)__P = __A; +} + +static __inline__ void __DEFAULT_FN_ATTRS256 _mm256_storeu_pbh(void *__P, + __m256bh __A) { + struct __storeu_pbh { + __m256bh_u __v; + } __attribute__((__packed__, __may_alias__)); + ((struct __storeu_pbh *)__P)->__v = __A; +} + +static __inline__ void __DEFAULT_FN_ATTRS128 _mm_storeu_pbh(void *__P, + __m128bh __A) { + struct __storeu_pbh { + __m128bh_u __v; + } __attribute__((__packed__, __may_alias__)); + ((struct __storeu_pbh *)__P)->__v = __A; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_move_sbh(__m128bh __a, + __m128bh __b) { + __a[0] = __b[0]; + return __a; +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_move_sbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return __builtin_ia32_selectsbf_128(__U, _mm_move_sbh(__A, __B), __W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_move_sbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return __builtin_ia32_selectsbf_128(__U, _mm_move_sbh(__A, __B), + _mm_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_undefined_pbh(void) { + return (__m128bh)__builtin_ia32_undef128(); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_set_sbh(__bf16 bf) { + return (__v8bf)__builtin_shufflevector( + (__v8bf){bf, bf, bf, bf, bf, bf, bf, bf}, (__v8bf)_mm_setzero_pbh(), 0, 8, + 8, 8, 8, 8, 8, 8); +} + +static __inline __m128bh __DEFAULT_FN_ATTRS128 _mm_set1_pbh(__bf16 bf) { + return (__m128bh)(__v8bf){bf, bf, bf, bf, bf, bf, bf, bf}; +} + +static __inline __m256bh __DEFAULT_FN_ATTRS256 _mm256_set1_pbh(__bf16 bf) { + return (__m256bh)(__v16bf){bf, bf, bf, bf, bf, bf, bf, bf, + bf, bf, bf, bf, bf, bf, bf, bf}; +} + +static __inline __m128bh __DEFAULT_FN_ATTRS128 +_mm_set_pbh(__bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, __bf16 bf5, + __bf16 bf6, __bf16 bf7, __bf16 bf8) { + return (__m128bh)(__v8bf){bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8}; +} + +static __inline __m256bh __DEFAULT_FN_ATTRS256 _mm256_set_pbh( + __bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, __bf16 bf5, __bf16 bf6, + __bf16 bf7, __bf16 bf8, __bf16 bf9, __bf16 bf10, __bf16 bf11, __bf16 bf12, + __bf16 bf13, __bf16 bf14, __bf16 bf15, __bf16 bf16) { + return (__m256bh)(__v16bf){bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, + bf9, bf10, bf11, bf12, bf13, bf14, bf15, bf16}; +} + +#define _mm_setr_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8) \ + _mm_set_pbh((bf8), (bf7), (bf6), (bf5), (bf4), (bf3), (bf2), (bf1)) + +#define _mm256_setr_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9, bf10, \ + bf11, bf12, bf13, bf14, bf15, bf16) \ + _mm256_set_pbh((bf16), (bf15), (bf14), (bf13), (bf12), (bf11), (bf10), \ + (bf9), (bf8), (bf7), (bf6), (bf5), (bf4), (bf3), (bf2), \ + (bf1)) + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_abs_pbh(__m256bh __A) { + return (__m256bh)_mm256_and_epi32(_mm256_set1_epi32(0x7FFF7FFF), + (__m256i)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_abs_pbh(__m128bh __A) { + return (__m128bh)_mm_and_epi32(_mm_set1_epi32(0x7FFF7FFF), (__m128i)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_blend_pbh(__mmask8 __U, __m128bh __A, __m128bh __W) { + return (__m128bh)__builtin_ia32_selectpbf_128((__mmask8)__U, (__v8bf)__W, + (__v8bf)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_blend_pbh(__mmask16 __U, __m256bh __A, __m256bh __W) { + return (__m256bh)__builtin_ia32_selectpbf_256((__mmask16)__U, (__v16bf)__W, + (__v16bf)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_permutex2var_pbh(__m128bh __A, __m128i __I, __m128bh __B) { + return (__m128bh)__builtin_ia32_vpermi2varhi128((__v8hi)__A, (__v8hi)__I, + (__v8hi)__B); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_permutex2var_pbh(__m256bh __A, __m256i __I, __m256bh __B) { + return (__m256bh)__builtin_ia32_vpermi2varhi256((__v16hi)__A, (__v16hi)__I, + (__v16hi)__B); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_permutexvar_pbh(__m128i __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_permvarhi128((__v8hi)__B, (__v8hi)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_permutexvar_pbh(__m256i __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_permvarhi256((__v16hi)__B, (__v16hi)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_addne_pbh(__m256bh __A, __m256bh __B) { + return (__m256bh)((__v16bf)__A + (__v16bf)__B); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_addne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_addne_pbh(__A, __B), (__v16bf)__W); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_addne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_addne_pbh(__A, __B), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_addne_pbh(__m128bh __A, + __m128bh __B) { + return (__m128bh)((__v8bf)__A + (__v8bf)__B); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_addne_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_addne_pbh(__A, __B), (__v8bf)__W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_addne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128((__mmask8)__U, + (__v8bf)_mm_addne_pbh(__A, __B), + (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_subne_pbh(__m256bh __A, __m256bh __B) { + return (__m256bh)((__v16bf)__A - (__v16bf)__B); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_subne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_subne_pbh(__A, __B), (__v16bf)__W); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_subne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_subne_pbh(__A, __B), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_subne_pbh(__m128bh __A, + __m128bh __B) { + return (__m128bh)((__v8bf)__A - (__v8bf)__B); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_subne_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_subne_pbh(__A, __B), (__v8bf)__W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_subne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128((__mmask8)__U, + (__v8bf)_mm_subne_pbh(__A, __B), + (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mulne_pbh(__m256bh __A, __m256bh __B) { + return (__m256bh)((__v16bf)__A * (__v16bf)__B); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_mulne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_mulne_pbh(__A, __B), (__v16bf)__W); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_mulne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_mulne_pbh(__A, __B), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_mulne_pbh(__m128bh __A, + __m128bh __B) { + return (__m128bh)((__v8bf)__A * (__v8bf)__B); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_mulne_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_mulne_pbh(__A, __B), (__v8bf)__W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_mulne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128((__mmask8)__U, + (__v8bf)_mm_mulne_pbh(__A, __B), + (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_divne_pbh(__m256bh __A, __m256bh __B) { + return (__m256bh)((__v16bf)__A / (__v16bf)__B); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_divne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_divne_pbh(__A, __B), (__v16bf)__W); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_divne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_divne_pbh(__A, __B), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_divne_pbh(__m128bh __A, + __m128bh __B) { + return (__m128bh)((__v8bf)__A / (__v8bf)__B); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_divne_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_divne_pbh(__A, __B), (__v8bf)__W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_divne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128((__mmask8)__U, + (__v8bf)_mm_divne_pbh(__A, __B), + (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_max_pbh(__m256bh __A, + __m256bh __B) { + return (__m256bh)__builtin_ia32_vmaxpbf16256((__v16bf)__A, (__v16bf)__B); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_max_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_max_pbh(__A, __B), (__v16bf)__W); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_max_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_max_pbh(__A, __B), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_max_pbh(__m128bh __A, + __m128bh __B) { + return (__m128bh)__builtin_ia32_vmaxpbf16128((__v8bf)__A, (__v8bf)__B); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_max_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_max_pbh(__A, __B), (__v8bf)__W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_max_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_max_pbh(__A, __B), (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_min_pbh(__m256bh __A, + __m256bh __B) { + return (__m256bh)__builtin_ia32_vminpbf16256((__v16bf)__A, (__v16bf)__B); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_min_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_min_pbh(__A, __B), (__v16bf)__W); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_min_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_min_pbh(__A, __B), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_min_pbh(__m128bh __A, + __m128bh __B) { + return (__m128bh)__builtin_ia32_vminpbf16128((__v8bf)__A, (__v8bf)__B); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_min_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_min_pbh(__A, __B), (__v8bf)__W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_min_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_min_pbh(__A, __B), (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ int __DEFAULT_FN_ATTRS128 _mm_comeqsbh(__m128bh A, + __m128bh B) { + return __builtin_ia32_vcomsbf16eq((__v8bf)A, (__v8bf)B); +} + +static __inline__ int __DEFAULT_FN_ATTRS128 _mm_comltsbh(__m128bh A, + __m128bh B) { + return __builtin_ia32_vcomsbf16lt((__v8bf)A, (__v8bf)B); +} + +static __inline__ int __DEFAULT_FN_ATTRS128 _mm_comlesbh(__m128bh A, + __m128bh B) { + return __builtin_ia32_vcomsbf16le((__v8bf)A, (__v8bf)B); +} + +static __inline__ int __DEFAULT_FN_ATTRS128 _mm_comgtsbh(__m128bh A, + __m128bh B) { + return __builtin_ia32_vcomsbf16gt((__v8bf)A, (__v8bf)B); +} + +static __inline__ int __DEFAULT_FN_ATTRS128 _mm_comgesbh(__m128bh A, + __m128bh B) { + return __builtin_ia32_vcomsbf16ge((__v8bf)A, (__v8bf)B); +} + +static __inline__ int __DEFAULT_FN_ATTRS128 _mm_comneqsbh(__m128bh A, + __m128bh B) { + return __builtin_ia32_vcomsbf16neq((__v8bf)A, (__v8bf)B); +} + +#define _mm256_cmp_pbh_mask(__A, __B, __P) \ + ((__mmask16)__builtin_ia32_vcmppbf16256_mask((__v16bf)(__m256bh)(__A), \ + (__v16bf)(__m256bh)(__B), \ + (int)(__P), (__mmask16) - 1)) + +#define _mm256_mask_cmp_pbh_mask(__U, __A, __B, __P) \ + ((__mmask16)__builtin_ia32_vcmppbf16256_mask((__v16bf)(__m256bh)(__A), \ + (__v16bf)(__m256bh)(__B), \ + (int)(__P), (__mmask16)(__U))) + +#define _mm_cmp_pbh_mask(__A, __B, __P) \ + ((__mmask8)__builtin_ia32_vcmppbf16128_mask((__v8bf)(__m128bh)(__A), \ + (__v8bf)(__m128bh)(__B), \ + (int)(__P), (__mmask8) - 1)) + +#define _mm_mask_cmp_pbh_mask(__U, __A, __B, __P) \ + ((__mmask8)__builtin_ia32_vcmppbf16128_mask((__v8bf)(__m128bh)(__A), \ + (__v8bf)(__m128bh)(__B), \ + (int)(__P), (__mmask8)(__U))) + +#define _mm256_mask_fpclass_pbh_mask(__U, __A, imm) \ + ((__mmask16)__builtin_ia32_vfpclasspbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__mmask16)(__U))) + +#define _mm256_fpclass_pbh_mask(__A, imm) \ + ((__mmask16)__builtin_ia32_vfpclasspbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__mmask16) - 1)) + +#define _mm_mask_fpclass_pbh_mask(__U, __A, imm) \ + ((__mmask8)__builtin_ia32_vfpclasspbf16128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(imm), (__mmask8)(__U))) + +#define _mm_fpclass_pbh_mask(__A, imm) \ + ((__mmask8)__builtin_ia32_vfpclasspbf16128_mask((__v8bf)(__m128bh)(__A), \ + (int)(imm), (__mmask8) - 1)) + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_scalef_pbh(__m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_vscalefpbf16256_mask( + (__v16bf)__A, (__v16bf)__B, (__v16bf)_mm256_undefined_pbh(), + (__mmask16)-1); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask_scalef_pbh( + __m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_vscalefpbf16256_mask( + (__v16bf)__A, (__v16bf)__B, (__v16bf)__W, (__mmask16)__U); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_scalef_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + return (__m256bh)__builtin_ia32_vscalefpbf16256_mask( + (__v16bf)__A, (__v16bf)__B, (__v16bf)_mm256_setzero_pbh(), + (__mmask16)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_scalef_pbh(__m128bh __A, + __m128bh __B) { + return (__m128bh)__builtin_ia32_vscalefpbf16128_mask( + (__v8bf)__A, (__v8bf)__B, (__v8bf)_mm_undefined_pbh(), (__mmask8)-1); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_scalef_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_vscalefpbf16128_mask( + (__v8bf)__A, (__v8bf)__B, (__v8bf)__W, (__mmask8)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_scalef_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + return (__m128bh)__builtin_ia32_vscalefpbf16128_mask( + (__v8bf)__A, (__v8bf)__B, (__v8bf)_mm_setzero_pbh(), (__mmask8)__U); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_rcp_pbh(__m256bh __A) { + return (__m256bh)__builtin_ia32_vrcppbf16256_mask( + (__v16bf)__A, (__v16bf)_mm256_undefined_pbh(), (__mmask16)-1); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_rcp_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_vrcppbf16256_mask((__v16bf)__A, (__v16bf)__W, + (__mmask16)__U); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_rcp_pbh(__mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_vrcppbf16256_mask( + (__v16bf)__A, (__v16bf)_mm256_setzero_pbh(), (__mmask16)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_rcp_pbh(__m128bh __A) { + return (__m128bh)__builtin_ia32_vrcppbf16128_mask( + (__v8bf)__A, (__v8bf)_mm_undefined_pbh(), (__mmask8)-1); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_rcp_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_vrcppbf16128_mask((__v8bf)__A, (__v8bf)__W, + (__mmask8)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_rcp_pbh(__mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_vrcppbf16128_mask( + (__v8bf)__A, (__v8bf)_mm_setzero_pbh(), (__mmask8)__U); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_getexp_pbh(__m256bh __A) { + return (__m256bh)__builtin_ia32_vgetexppbf16256_mask( + (__v16bf)__A, (__v16bf)_mm256_undefined_pbh(), (__mmask16)-1); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_getexp_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_vgetexppbf16256_mask( + (__v16bf)__A, (__v16bf)__W, (__mmask16)__U); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_getexp_pbh(__mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_vgetexppbf16256_mask( + (__v16bf)__A, (__v16bf)_mm256_setzero_pbh(), (__mmask16)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_getexp_pbh(__m128bh __A) { + return (__m128bh)__builtin_ia32_vgetexppbf16128_mask( + (__v8bf)__A, (__v8bf)_mm_undefined_pbh(), (__mmask8)-1); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_getexp_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_vgetexppbf16128_mask((__v8bf)__A, (__v8bf)__W, + (__mmask8)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_getexp_pbh(__mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_vgetexppbf16128_mask( + (__v8bf)__A, (__v8bf)_mm_setzero_pbh(), (__mmask8)__U); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_rsqrt_pbh(__m256bh __A) { + return (__m256bh)__builtin_ia32_vrsqrtpbf16256_mask( + (__v16bf)__A, (__v16bf)_mm256_undefined_pbh(), (__mmask16)-1); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_rsqrt_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_vrsqrtpbf16256_mask( + (__v16bf)__A, (__v16bf)__W, (__mmask16)__U); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_rsqrt_pbh(__mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_vrsqrtpbf16256_mask( + (__v16bf)__A, (__v16bf)_mm256_setzero_pbh(), (__mmask16)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_rsqrt_pbh(__m128bh __A) { + return (__m128bh)__builtin_ia32_vrsqrtpbf16128_mask( + (__v8bf)__A, (__v8bf)_mm_undefined_pbh(), (__mmask8)-1); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_rsqrt_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_vrsqrtpbf16128_mask((__v8bf)__A, (__v8bf)__W, + (__mmask8)__U); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_rsqrt_pbh(__mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_vrsqrtpbf16128_mask( + (__v8bf)__A, (__v8bf)_mm_setzero_pbh(), (__mmask8)__U); +} + +#define _mm256_reducene_pbh(__A, imm) \ + ((__m256bh)__builtin_ia32_vreducenepbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__v16bf)_mm256_undefined_pbh(), \ + (__mmask16) - 1)) + +#define _mm256_mask_reducene_pbh(__W, __U, __A, imm) \ + ((__m256bh)__builtin_ia32_vreducenepbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__v16bf)(__m256bh)(__W), \ + (__mmask16)(__U))) + +#define _mm256_maskz_reducene_pbh(__U, __A, imm) \ + ((__m256bh)__builtin_ia32_vreducenepbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__v16bf)_mm256_setzero_pbh(), \ + (__mmask16)(__U))) + +#define _mm_reducene_pbh(__A, imm) \ + ((__m128bh)__builtin_ia32_vreducenepbf16128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(imm), (__v8bf)_mm_undefined_pbh(), \ + (__mmask8) - 1)) + +#define _mm_mask_reducene_pbh(__W, __U, __A, imm) \ + ((__m128bh)__builtin_ia32_vreducenepbf16128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(imm), (__v8bf)(__m128bh)(__W), \ + (__mmask8)(__U))) + +#define _mm_maskz_reducene_pbh(__U, __A, imm) \ + ((__m128bh)__builtin_ia32_vreducenepbf16128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(imm), (__v8bf)_mm_setzero_pbh(), \ + (__mmask8)(__U))) + +#define _mm256_roundscalene_pbh(__A, imm) \ + ((__m256bh)__builtin_ia32_vrndscalenepbf16_256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__v16bf)_mm256_setzero_pbh(), \ + (__mmask16) - 1)) + +#define _mm256_mask_roundscalene_pbh(__W, __U, __A, imm) \ + ((__m256bh)__builtin_ia32_vrndscalenepbf16_256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__v16bf)(__m256bh)(__W), \ + (__mmask16)(__U))) + +#define _mm256_maskz_roundscalene_pbh(__U, __A, imm) \ + ((__m256bh)__builtin_ia32_vrndscalenepbf16_256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(imm), (__v16bf)_mm256_setzero_pbh(), \ + (__mmask16)(__U))) + +#define _mm_roundscalene_pbh(__A, imm) \ + ((__m128bh)__builtin_ia32_vrndscalenepbf16_128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(imm), (__v8bf)_mm_setzero_pbh(), \ + (__mmask8) - 1)) + +#define _mm_mask_roundscalene_pbh(__W, __U, __A, imm) \ + ((__m128bh)__builtin_ia32_vrndscalenepbf16_128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(imm), (__v8bf)(__m128bh)(__W), \ + (__mmask8)(__U))) + +#define _mm_maskz_roundscalene_pbh(__U, __A, imm) \ + ((__m128bh)__builtin_ia32_vrndscalenepbf16_128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(imm), (__v8bf)_mm_setzero_pbh(), \ + (__mmask8)(__U))) + +#define _mm256_getmant_pbh(__A, __B, __C) \ + ((__m256bh)__builtin_ia32_vgetmantpbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v16bf)_mm256_undefined_pbh(), (__mmask16) - 1)) + +#define _mm256_mask_getmant_pbh(__W, __U, __A, __B, __C) \ + ((__m256bh)__builtin_ia32_vgetmantpbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v16bf)(__m256bh)(__W), (__mmask16)(__U))) + +#define _mm256_maskz_getmant_pbh(__U, __A, __B, __C) \ + ((__m256bh)__builtin_ia32_vgetmantpbf16256_mask( \ + (__v16bf)(__m256bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v16bf)_mm256_setzero_pbh(), (__mmask16)(__U))) + +#define _mm_getmant_pbh(__A, __B, __C) \ + ((__m128bh)__builtin_ia32_vgetmantpbf16128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v8bf)_mm_undefined_pbh(), (__mmask8) - 1)) + +#define _mm_mask_getmant_pbh(__W, __U, __A, __B, __C) \ + ((__m128bh)__builtin_ia32_vgetmantpbf16128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v8bf)(__m128bh)(__W), (__mmask8)(__U))) + +#define _mm_maskz_getmant_pbh(__U, __A, __B, __C) \ + ((__m128bh)__builtin_ia32_vgetmantpbf16128_mask( \ + (__v8bf)(__m128bh)(__A), (int)(((__C) << 2) | (__B)), \ + (__v8bf)_mm_setzero_pbh(), (__mmask8)(__U))) + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_sqrt_pbh(__m256bh __A) { + return (__m256bh)__builtin_ia32_vsqrtnepbf16256((__v16bf)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_mask_sqrt_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, (__v16bf)_mm256_sqrt_pbh(__A), (__v16bf)__W); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_maskz_sqrt_pbh(__mmask16 __U, __m256bh __A) { + return (__m256bh)__builtin_ia32_selectpbf_256((__mmask16)__U, + (__v16bf)_mm256_sqrt_pbh(__A), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_sqrt_pbh(__m128bh __A) { + return (__m128bh)__builtin_ia32_vsqrtnepbf16((__v8bf)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_sqrt_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_sqrt_pbh(__A), (__v8bf)__W); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_sqrt_pbh(__mmask8 __U, __m128bh __A) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, (__v8bf)_mm_sqrt_pbh(__A), (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_fmaddne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_vfmaddnepbh256((__v16bf)__A, (__v16bf)__B, + (__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask_fmaddne_pbh( + __m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fmaddne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask3_fmaddne_pbh( + __m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fmaddne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_maskz_fmaddne_pbh( + __mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fmaddne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_fmsubne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_vfmaddnepbh256((__v16bf)__A, (__v16bf)__B, + -(__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask_fmsubne_pbh( + __m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fmsubne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask3_fmsubne_pbh( + __m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fmsubne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_maskz_fmsubne_pbh( + __mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fmsubne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_fnmaddne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_vfmaddnepbh256((__v16bf)__A, -(__v16bf)__B, + (__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask_fnmaddne_pbh( + __m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fnmaddne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask3_fnmaddne_pbh( + __m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fnmaddne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_maskz_fnmaddne_pbh( + __mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fnmaddne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 +_mm256_fnmsubne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_vfmaddnepbh256((__v16bf)__A, -(__v16bf)__B, + -(__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask_fnmsubne_pbh( + __m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fnmsubne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__A); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_mask3_fnmsubne_pbh( + __m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fnmsubne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)__C); +} + +static __inline__ __m256bh __DEFAULT_FN_ATTRS256 _mm256_maskz_fnmsubne_pbh( + __mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + return (__m256bh)__builtin_ia32_selectpbf_256( + (__mmask16)__U, + _mm256_fnmsubne_pbh((__v16bf)__A, (__v16bf)__B, (__v16bf)__C), + (__v16bf)_mm256_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_fmaddne_pbh(__m128bh __A, + __m128bh __B, + __m128bh __C) { + return (__m128bh)__builtin_ia32_vfmaddnepbh128((__v8bf)__A, (__v8bf)__B, + (__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_fmaddne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fmaddne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask3_fmaddne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fmaddne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_fmaddne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fmaddne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 _mm_fmsubne_pbh(__m128bh __A, + __m128bh __B, + __m128bh __C) { + return (__m128bh)__builtin_ia32_vfmaddnepbh128((__v8bf)__A, (__v8bf)__B, + -(__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_fmsubne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fmsubne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask3_fmsubne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fmsubne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_fmsubne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fmsubne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_fnmaddne_pbh(__m128bh __A, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_vfmaddnepbh128((__v8bf)__A, -(__v8bf)__B, + (__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_fnmaddne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fnmaddne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask3_fnmaddne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fnmaddne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_fnmaddne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fnmaddne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)_mm_setzero_pbh()); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_fnmsubne_pbh(__m128bh __A, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_vfmaddnepbh128((__v8bf)__A, -(__v8bf)__B, + -(__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask_fnmsubne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fnmsubne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__A); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_mask3_fnmsubne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fnmsubne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)__C); +} + +static __inline__ __m128bh __DEFAULT_FN_ATTRS128 +_mm_maskz_fnmsubne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + return (__m128bh)__builtin_ia32_selectpbf_128( + (__mmask8)__U, _mm_fnmsubne_pbh((__v8bf)__A, (__v8bf)__B, (__v8bf)__C), + (__v8bf)_mm_setzero_pbh()); +} + +#undef __DEFAULT_FN_ATTRS128 +#undef __DEFAULT_FN_ATTRS256 + +#endif +#endif diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 6d38b668fe770..5c08a45a35377 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1796,5 +1796,9 @@ _HLSL_AVAILABILITY(shadermodel, 6.0) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_get_lane_index) __attribute__((convergent)) uint WaveGetLaneIndex(); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_is_first_lane) +__attribute__((convergent)) bool WaveIsFirstLane(); + } // namespace hlsl #endif //_HLSL_HLSL_INTRINSICS_H_ diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index a922056622e79..30fcc028958f3 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -649,6 +649,7 @@ _storebe_i64(void * __P, long long __D) { #endif #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2__) +#include #include #include #include @@ -656,6 +657,7 @@ _storebe_i64(void * __P, long long __D) { #endif #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2_512__) +#include #include #include #include diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index ef1e1f4bd9aeb..8647e9f2f27c3 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -2428,7 +2428,9 @@ bool Lexer::LexCharConstant(Token &Result, const char *CurPtr, ? diag::warn_cxx98_compat_unicode_literal : diag::warn_c99_compat_unicode_literal); else if (Kind == tok::utf8_char_constant) - Diag(BufferPtr, diag::warn_cxx14_compat_u8_character_literal); + Diag(BufferPtr, LangOpts.CPlusPlus + ? diag::warn_cxx14_compat_u8_character_literal + : diag::warn_c17_compat_u8_character_literal); } char C = getAndAdvanceChar(CurPtr, Result); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 7ca27d00c0bcb..6370da1fab004 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1076,7 +1076,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { } bool ParseAsExpression = false; - if (getLangOpts().CPlusPlus26) { + if (getLangOpts().CPlusPlus11) { for (unsigned I = 0;; ++I) { const Token &T = GetLookAheadToken(I); if (T.is(tok::r_paren)) @@ -1088,9 +1088,13 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { } } - if (ParseAsExpression) + if (ParseAsExpression) { + Diag(Tok, + getLangOpts().CPlusPlus26 + ? diag::warn_cxx20_compat_static_assert_user_generated_message + : diag::ext_cxx_static_assert_user_generated_message); AssertMessage = ParseConstantExpressionInExprEvalContext(); - else if (tokenIsLikeStringLiteral(Tok, getLangOpts())) + } else if (tokenIsLikeStringLiteral(Tok, getLangOpts())) AssertMessage = ParseUnevaluatedStringLiteralExpression(); else { Diag(Tok, diag::err_expected_string_literal) diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 6ecfc15757f3d..de29652abbfd9 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -959,7 +959,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { ++CurTemplateDepthTracker; EnterExpressionEvaluationContext ConstantEvaluated( Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); - DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseInitializer()); + DefaultArg = Actions.ActOnConstantExpression(ParseInitializer()); if (DefaultArg.isInvalid()) SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index e6ce89dc7ec40..117b2c8bc5793 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -2304,6 +2304,20 @@ class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler { } } + void handleUnsafeLibcCall(const CallExpr *Call, unsigned PrintfInfo, + ASTContext &Ctx, + const Expr *UnsafeArg = nullptr) override { + S.Diag(Call->getBeginLoc(), diag::warn_unsafe_buffer_libc_call) + << Call->getDirectCallee() // We've checked there is a direct callee + << Call->getSourceRange(); + if (PrintfInfo > 0) { + SourceRange R = + UnsafeArg ? UnsafeArg->getSourceRange() : Call->getSourceRange(); + S.Diag(R.getBegin(), diag::note_unsafe_buffer_printf_call) + << PrintfInfo << R; + } + } + void handleUnsafeOperationInContainer(const Stmt *Operation, bool IsRelatedToDecl, ASTContext &Ctx) override { @@ -2382,6 +2396,10 @@ class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler { return S.Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container, Loc); } + bool ignoreUnsafeBufferInLibcCall(const SourceLocation &Loc) const override { + return S.Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, Loc); + } + // Returns the text representation of clang::unsafe_buffer_usage attribute. // `WSSuffix` holds customized "white-space"s, e.g., newline or whilespace // characters. @@ -2548,6 +2566,8 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings( !Diags.isIgnored(diag::warn_unsafe_buffer_variable, Node->getBeginLoc()) || !Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container, + Node->getBeginLoc()) || + !Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, Node->getBeginLoc())) { clang::checkUnsafeBufferUsage(Node, R, UnsafeBufferUsageShouldEmitSuggestions); @@ -2560,7 +2580,8 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings( if (!Diags.isIgnored(diag::warn_unsafe_buffer_operation, SourceLocation()) || !Diags.isIgnored(diag::warn_unsafe_buffer_variable, SourceLocation()) || !Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container, - SourceLocation())) { + SourceLocation()) || + !Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, SourceLocation())) { CallableVisitor(CallAnalyzers).TraverseTranslationUnitDecl(TU); } } diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index f28789dba34e1..f1507ebb9a506 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -237,13 +237,11 @@ static bool pathContainsInit(IndirectLocalPath &Path) { static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Expr *Init, LocalVisitor Visit, - bool RevisitSubinits, - bool EnableLifetimeWarnings); + bool RevisitSubinits); static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, Expr *Init, ReferenceKind RK, - LocalVisitor Visit, - bool EnableLifetimeWarnings); + LocalVisitor Visit); template static bool isRecordWithAttr(QualType Type) { if (auto *RD = Type->getAsCXXRecordDecl()) @@ -290,7 +288,8 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { // Map and set types. .Cases("find", "equal_range", "lower_bound", "upper_bound", true) .Default(false); - } else if (Callee->getReturnType()->isReferenceType()) { + } + if (Callee->getReturnType()->isReferenceType()) { if (!Callee->getIdentifier()) { auto OO = Callee->getOverloadedOperator(); return OO == OverloadedOperatorKind::OO_Subscript || @@ -318,7 +317,8 @@ static bool shouldTrackFirstArgument(const FunctionDecl *FD) { .Cases("end", "rend", "cend", "crend", true) .Case("data", true) .Default(false); - } else if (FD->getReturnType()->isReferenceType()) { + } + if (FD->getReturnType()->isReferenceType()) { return llvm::StringSwitch(FD->getName()) .Cases("get", "any_cast", true) .Default(false); @@ -326,24 +326,11 @@ static bool shouldTrackFirstArgument(const FunctionDecl *FD) { return false; } -static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) { - const TypeSourceInfo *TSI = FD->getTypeSourceInfo(); - if (!TSI) - return false; - // Don't declare this variable in the second operand of the for-statement; - // GCC miscompiles that by ending its lifetime before evaluating the - // third operand. See gcc.gnu.org/PR86769. - AttributedTypeLoc ATL; - for (TypeLoc TL = TSI->getTypeLoc(); - (ATL = TL.getAsAdjusted()); - TL = ATL.getModifiedLoc()) { - if (ATL.getAttrAs()) - return true; - } - - // Assume that all assignment operators with a "normal" return type return - // *this, that is, an lvalue reference that is the same type as the implicit - // object parameter (or the LHS for a non-member operator$=). +// Return true if this is an "normal" assignment operator. +// We assuments that a normal assingment operator always returns *this, that is, +// an lvalue reference that is the same type as the implicit object parameter +// (or the LHS for a non-member operator$=). +static bool isNormalAssignmentOperator(const FunctionDecl *FD) { OverloadedOperatorKind OO = FD->getDeclName().getCXXOverloadedOperator(); if (OO == OO_Equal || isCompoundAssignmentOperator(OO)) { QualType RetT = FD->getReturnType(); @@ -359,14 +346,30 @@ static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) { return true; } } - return false; } +static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) { + const TypeSourceInfo *TSI = FD->getTypeSourceInfo(); + if (!TSI) + return false; + // Don't declare this variable in the second operand of the for-statement; + // GCC miscompiles that by ending its lifetime before evaluating the + // third operand. See gcc.gnu.org/PR86769. + AttributedTypeLoc ATL; + for (TypeLoc TL = TSI->getTypeLoc(); + (ATL = TL.getAsAdjusted()); + TL = ATL.getModifiedLoc()) { + if (ATL.getAttrAs()) + return true; + } + + return isNormalAssignmentOperator(FD); +} + // Visit lifetimebound or gsl-pointer arguments. static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call, - LocalVisitor Visit, - bool EnableLifetimeWarnings) { + LocalVisitor Visit) { const FunctionDecl *Callee; ArrayRef Args; @@ -381,6 +384,8 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call, if (!Callee) return; + bool EnableGSLAnalysis = !Callee->getASTContext().getDiagnostics().isIgnored( + diag::warn_dangling_lifetime_pointer, SourceLocation()); Expr *ObjectArg = nullptr; if (isa(Call) && Callee->isCXXInstanceMember()) { ObjectArg = Args[0]; @@ -393,22 +398,25 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call, Path.push_back({IndirectLocalPathEntry::LifetimeBoundCall, Arg, D}); if (Arg->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding, - Visit, - /*EnableLifetimeWarnings=*/false); + Visit); else - visitLocalsRetainedByInitializer(Path, Arg, Visit, true, - /*EnableLifetimeWarnings=*/false); + visitLocalsRetainedByInitializer(Path, Arg, Visit, true); Path.pop_back(); }; - auto VisitGSLPointerArg = [&](const Decl *D, Expr *Arg, bool Value) { + auto VisitGSLPointerArg = [&](const FunctionDecl *Callee, Expr *Arg) { // We are not interested in the temporary base objects of gsl Pointers: // Temp().ptr; // Here ptr might not dangle. if (isa(Arg->IgnoreImpCasts())) return; - // Once we initialized a value with a reference, it can no longer dangle. - if (!Value) { + auto ReturnType = Callee->getReturnType(); + + // Once we initialized a value with a non gsl-owner reference, it can no + // longer dangle. + if (ReturnType->isReferenceType() && + !isRecordWithAttr(ReturnType->getPointeeType())) { for (const IndirectLocalPathEntry &PE : llvm::reverse(Path)) { - if (PE.Kind == IndirectLocalPathEntry::GslReferenceInit) + if (PE.Kind == IndirectLocalPathEntry::GslReferenceInit || + PE.Kind == IndirectLocalPathEntry::LifetimeBoundCall) continue; if (PE.Kind == IndirectLocalPathEntry::GslPointerInit || PE.Kind == IndirectLocalPathEntry::GslPointerAssignment) @@ -416,16 +424,15 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call, break; } } - Path.push_back({Value ? IndirectLocalPathEntry::GslPointerInit - : IndirectLocalPathEntry::GslReferenceInit, - Arg, D}); + Path.push_back({ReturnType->isReferenceType() + ? IndirectLocalPathEntry::GslReferenceInit + : IndirectLocalPathEntry::GslPointerInit, + Arg, Callee}); if (Arg->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding, - Visit, - /*EnableLifetimeWarnings=*/true); + Visit); else - visitLocalsRetainedByInitializer(Path, Arg, Visit, true, - /*EnableLifetimeWarnings=*/true); + visitLocalsRetainedByInitializer(Path, Arg, Visit, true); Path.pop_back(); }; @@ -448,11 +455,10 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call, CheckCoroObjArg = false; if (implicitObjectParamIsLifetimeBound(Callee) || CheckCoroObjArg) VisitLifetimeBoundArg(Callee, ObjectArg); - else if (EnableLifetimeWarnings) { + else if (EnableGSLAnalysis) { if (auto *CME = dyn_cast(Callee); CME && shouldTrackImplicitObjectArg(CME)) - VisitGSLPointerArg(Callee, ObjectArg, - !Callee->getReturnType()->isReferenceType()); + VisitGSLPointerArg(Callee, ObjectArg); } } @@ -461,15 +467,13 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call, I != N; ++I) { if (CheckCoroCall || Callee->getParamDecl(I)->hasAttr()) VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]); - else if (EnableLifetimeWarnings && I == 0) { + else if (EnableGSLAnalysis && I == 0) { if (shouldTrackFirstArgument(Callee)) { - VisitGSLPointerArg(Callee, Args[0], - !Callee->getReturnType()->isReferenceType()); - } else { - if (auto *CCE = dyn_cast(Call); - CCE && CCE->getConstructor()->getParent()->hasAttr()) - VisitGSLPointerArg(CCE->getConstructor()->getParamDecl(0), Args[0], - true); + VisitGSLPointerArg(Callee, Args[0]); + } else if (auto *CCE = dyn_cast(Call); + CCE && + CCE->getConstructor()->getParent()->hasAttr()) { + VisitGSLPointerArg(CCE->getConstructor(), Args[0]); } } } @@ -479,8 +483,7 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call, /// glvalue expression \c Init. static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, Expr *Init, ReferenceKind RK, - LocalVisitor Visit, - bool EnableLifetimeWarnings) { + LocalVisitor Visit) { RevertToOldSizeRAII RAII(Path); // Walk past any constructs which we can lifetime-extend across. @@ -517,8 +520,7 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, else // We can't lifetime extend through this but we might still find some // retained temporaries. - return visitLocalsRetainedByInitializer(Path, Init, Visit, true, - EnableLifetimeWarnings); + return visitLocalsRetainedByInitializer(Path, Init, Visit, true); } // Step into CXXDefaultInitExprs so we can diagnose cases where a @@ -532,21 +534,18 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, if (auto *MTE = dyn_cast(Init)) { if (Visit(Path, Local(MTE), RK)) - visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit, true); } if (auto *M = dyn_cast(Init)) { // Lifetime of a non-reference type field is same as base object. if (auto *F = dyn_cast(M->getMemberDecl()); F && !F->getType()->isReferenceType()) - visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true); } if (isa(Init)) - return visitFunctionCallArguments(Path, Init, Visit, - EnableLifetimeWarnings); + return visitFunctionCallArguments(Path, Init, Visit); switch (Init->getStmtClass()) { case Stmt::DeclRefExprClass: { @@ -565,8 +564,7 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, } else if (VD->getInit() && !isVarOnPath(Path, VD)) { Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD}); visitLocalsRetainedByReferenceBinding(Path, VD->getInit(), - RK_ReferenceBinding, Visit, - EnableLifetimeWarnings); + RK_ReferenceBinding, Visit); } } break; @@ -578,15 +576,13 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, // handling all sorts of rvalues passed to a unary operator. const UnaryOperator *U = cast(Init); if (U->getOpcode() == UO_Deref) - visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true); break; } case Stmt::ArraySectionExprClass: { - visitLocalsRetainedByInitializer(Path, - cast(Init)->getBase(), - Visit, true, EnableLifetimeWarnings); + visitLocalsRetainedByInitializer( + Path, cast(Init)->getBase(), Visit, true); break; } @@ -594,11 +590,9 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, case Stmt::BinaryConditionalOperatorClass: { auto *C = cast(Init); if (!C->getTrueExpr()->getType()->isVoidType()) - visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit, - EnableLifetimeWarnings); + visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit); if (!C->getFalseExpr()->getType()->isVoidType()) - visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit, - EnableLifetimeWarnings); + visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit); break; } @@ -621,8 +615,7 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, /// the prvalue expression \c Init. static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Expr *Init, LocalVisitor Visit, - bool RevisitSubinits, - bool EnableLifetimeWarnings) { + bool RevisitSubinits) { RevertToOldSizeRAII RAII(Path); Expr *Old; @@ -663,18 +656,16 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, if (VD && VD->getType().isConstQualified() && VD->getInit() && !isVarOnPath(Path, VD)) { Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD}); - visitLocalsRetainedByInitializer( - Path, VD->getInit(), Visit, true, EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, VD->getInit(), Visit, + true); } } else if (auto *MTE = dyn_cast(L)) { if (MTE->getType().isConstQualified()) visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), - Visit, true, - EnableLifetimeWarnings); + Visit, true); } return false; - }, - EnableLifetimeWarnings); + }); // We assume that objects can be retained by pointers cast to integers, // but not if the integer is cast to floating-point type or to _Complex. @@ -703,9 +694,8 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, // Model array-to-pointer decay as taking the address of the array // lvalue. Path.push_back({IndirectLocalPathEntry::AddressOf, CE}); - return visitLocalsRetainedByReferenceBinding(Path, CE->getSubExpr(), - RK_ReferenceBinding, Visit, - EnableLifetimeWarnings); + return visitLocalsRetainedByReferenceBinding( + Path, CE->getSubExpr(), RK_ReferenceBinding, Visit); default: return; @@ -720,8 +710,7 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, // lifetime of the array exactly like binding a reference to a temporary. if (auto *ILE = dyn_cast(Init)) return visitLocalsRetainedByReferenceBinding(Path, ILE->getSubExpr(), - RK_StdInitializerList, Visit, - EnableLifetimeWarnings); + RK_StdInitializerList, Visit); if (InitListExpr *ILE = dyn_cast(Init)) { // We already visited the elements of this initializer list while @@ -732,14 +721,12 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, if (ILE->isTransparent()) return visitLocalsRetainedByInitializer(Path, ILE->getInit(0), Visit, - RevisitSubinits, - EnableLifetimeWarnings); + RevisitSubinits); if (ILE->getType()->isArrayType()) { for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I) visitLocalsRetainedByInitializer(Path, ILE->getInit(I), Visit, - RevisitSubinits, - EnableLifetimeWarnings); + RevisitSubinits); return; } @@ -752,14 +739,12 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, if (RD->isUnion() && ILE->getInitializedFieldInUnion() && ILE->getInitializedFieldInUnion()->getType()->isReferenceType()) visitLocalsRetainedByReferenceBinding(Path, ILE->getInit(0), - RK_ReferenceBinding, Visit, - EnableLifetimeWarnings); + RK_ReferenceBinding, Visit); else { unsigned Index = 0; for (; Index < RD->getNumBases() && Index < ILE->getNumInits(); ++Index) visitLocalsRetainedByInitializer(Path, ILE->getInit(Index), Visit, - RevisitSubinits, - EnableLifetimeWarnings); + RevisitSubinits); for (const auto *I : RD->fields()) { if (Index >= ILE->getNumInits()) break; @@ -768,14 +753,13 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Expr *SubInit = ILE->getInit(Index); if (I->getType()->isReferenceType()) visitLocalsRetainedByReferenceBinding(Path, SubInit, - RK_ReferenceBinding, Visit, - EnableLifetimeWarnings); + RK_ReferenceBinding, Visit); else // This might be either aggregate-initialization of a member or // initialization of a std::initializer_list object. Regardless, // we should recursively lifetime-extend that initializer. - visitLocalsRetainedByInitializer( - Path, SubInit, Visit, RevisitSubinits, EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, SubInit, Visit, + RevisitSubinits); ++Index; } } @@ -796,10 +780,9 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Path.push_back({IndirectLocalPathEntry::LambdaCaptureInit, E, &Cap}); if (E->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding, - Visit, EnableLifetimeWarnings); + Visit); else - visitLocalsRetainedByInitializer(Path, E, Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, E, Visit, true); if (Cap.capturesVariable()) Path.pop_back(); } @@ -813,16 +796,14 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Expr *Arg = MTE->getSubExpr(); Path.push_back({IndirectLocalPathEntry::TemporaryCopy, Arg, CCE->getConstructor()}); - visitLocalsRetainedByInitializer(Path, Arg, Visit, true, - /*EnableLifetimeWarnings*/ false); + visitLocalsRetainedByInitializer(Path, Arg, Visit, true); Path.pop_back(); } } } if (isa(Init) || isa(Init)) - return visitFunctionCallArguments(Path, Init, Visit, - EnableLifetimeWarnings); + return visitFunctionCallArguments(Path, Init, Visit); switch (Init->getStmtClass()) { case Stmt::UnaryOperatorClass: { @@ -838,8 +819,7 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Path.push_back({IndirectLocalPathEntry::AddressOf, UO}); visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(), - RK_ReferenceBinding, Visit, - EnableLifetimeWarnings); + RK_ReferenceBinding, Visit); } break; } @@ -852,11 +832,9 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, break; if (BO->getLHS()->getType()->isPointerType()) - visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true); else if (BO->getRHS()->getType()->isPointerType()) - visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true); break; } @@ -866,11 +844,9 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, // In C++, we can have a throw-expression operand, which has 'void' type // and isn't interesting from a lifetime perspective. if (!C->getTrueExpr()->getType()->isVoidType()) - visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true); if (!C->getFalseExpr()->getType()->isVoidType()) - visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true, - EnableLifetimeWarnings); + visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true); break; } @@ -968,12 +944,27 @@ static bool pathOnlyHandlesGslPointer(IndirectLocalPath &Path) { return false; } +static bool isAssignmentOperatorLifetimeBound(CXXMethodDecl *CMD) { + if (!CMD) + return false; + return isNormalAssignmentOperator(CMD) && CMD->param_size() == 1 && + CMD->getParamDecl(0)->hasAttr(); +} + +static bool shouldRunGSLAssignmentAnalysis(const Sema &SemaRef, + const AssignedEntity &Entity) { + bool EnableGSLAssignmentWarnings = !SemaRef.getDiagnostics().isIgnored( + diag::warn_dangling_lifetime_pointer_assignment, SourceLocation()); + return (EnableGSLAssignmentWarnings && + (isRecordWithAttr(Entity.LHS->getType()) || + isAssignmentOperatorLifetimeBound(Entity.AssignmentOperator))); +} + static void checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, const InitializedEntity *ExtendingEntity, LifetimeKind LK, - const AssignedEntity *AEntity, Expr *Init, - bool EnableLifetimeWarnings) { + const AssignedEntity *AEntity, Expr *Init) { assert((AEntity && LK == LK_Assignment) || (InitEntity && LK != LK_Assignment)); // If this entity doesn't have an interesting lifetime, don't bother looking @@ -1267,19 +1258,17 @@ static void checkExprLifetimeImpl(Sema &SemaRef, }; llvm::SmallVector Path; - if (EnableLifetimeWarnings && LK == LK_Assignment && - isRecordWithAttr(AEntity->LHS->getType())) + if (LK == LK_Assignment && shouldRunGSLAssignmentAnalysis(SemaRef, *AEntity)) Path.push_back({IndirectLocalPathEntry::GslPointerAssignment, Init}); if (Init->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding, - TemporaryVisitor, - EnableLifetimeWarnings); + TemporaryVisitor); else visitLocalsRetainedByInitializer( Path, Init, TemporaryVisitor, // Don't revisit the sub inits for the intialization case. - /*RevisitSubinits=*/!InitEntity, EnableLifetimeWarnings); + /*RevisitSubinits=*/!InitEntity); } void checkExprLifetime(Sema &SemaRef, const InitializedEntity &Entity, @@ -1287,29 +1276,24 @@ void checkExprLifetime(Sema &SemaRef, const InitializedEntity &Entity, auto LTResult = getEntityLifetime(&Entity); LifetimeKind LK = LTResult.getInt(); const InitializedEntity *ExtendingEntity = LTResult.getPointer(); - bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored( - diag::warn_dangling_lifetime_pointer, SourceLocation()); checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK, - /*AEntity*/ nullptr, Init, EnableLifetimeWarnings); + /*AEntity*/ nullptr, Init); } void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity, Expr *Init) { - bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored( - diag::warn_dangling_lifetime_pointer, SourceLocation()); bool EnableDanglingPointerAssignment = !SemaRef.getDiagnostics().isIgnored( diag::warn_dangling_pointer_assignment, SourceLocation()); bool RunAnalysis = (EnableDanglingPointerAssignment && Entity.LHS->getType()->isPointerType()) || - (EnableLifetimeWarnings && - isRecordWithAttr(Entity.LHS->getType())); + shouldRunGSLAssignmentAnalysis(SemaRef, Entity); if (!RunAnalysis) return; checkExprLifetimeImpl(SemaRef, /*InitEntity=*/nullptr, /*ExtendingEntity=*/nullptr, LK_Assignment, &Entity, - Init, EnableLifetimeWarnings); + Init); } } // namespace clang::sema diff --git a/clang/lib/Sema/CheckExprLifetime.h b/clang/lib/Sema/CheckExprLifetime.h index af381fb96c4d6..8c8d0806dee0a 100644 --- a/clang/lib/Sema/CheckExprLifetime.h +++ b/clang/lib/Sema/CheckExprLifetime.h @@ -22,6 +22,7 @@ namespace clang::sema { struct AssignedEntity { // The left-hand side expression of the assignment. Expr *LHS = nullptr; + CXXMethodDecl *AssignmentOperator = nullptr; }; /// Check that the lifetime of the given expr (and its subobjects) is diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 9aacbe4ad9548..071e64fe56d48 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -13,10 +13,13 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/HLSLRuntime.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaHLSL.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/HLSL/HLSLResource.h" #include @@ -107,7 +110,7 @@ struct BuiltinTypeDeclBuilder { } BuiltinTypeDeclBuilder & - addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV, + addHandleMember(Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV, AccessSpecifier Access = AccessSpecifier::AS_private) { if (Record->isCompleteDefinition()) return *this; @@ -118,16 +121,16 @@ struct BuiltinTypeDeclBuilder { Ty = Record->getASTContext().getPointerType( QualType(TTD->getTypeForDecl(), 0)); } - // add handle member - Attr *ResourceClassAttr = - HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC); + + // add handle member with resource type attributes + QualType AttributedResTy = QualType(); + SmallVector Attrs = { + HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC), + IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr}; Attr *ResourceAttr = HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK); - Attr *ROVAttr = - IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr; - addMemberVariable("h", Ty, {ResourceClassAttr, ResourceAttr, ROVAttr}, - Access); - + if (CreateHLSLAttributedResourceType(S, Ty, Attrs, AttributedResTy)) + addMemberVariable("h", AttributedResTy, {ResourceAttr}, Access); return *this; } @@ -494,7 +497,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV) { return BuiltinTypeDeclBuilder(Decl) - .addHandleMember(RC, RK, IsROV) + .addHandleMember(S, RC, RK, IsROV) .addDefaultHandleConstructor(S, RC); } diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index 185e0427d5c99..efde354860de4 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -315,40 +315,6 @@ bool SemaARM::BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, return false; } -// Get the valid immediate range for the specified NEON type code. -static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { - NeonTypeFlags Type(t); - int IsQuad = ForceQuad ? true : Type.isQuad(); - switch (Type.getEltType()) { - case NeonTypeFlags::Int8: - case NeonTypeFlags::Poly8: - return shift ? 7 : (8 << IsQuad) - 1; - case NeonTypeFlags::Int16: - case NeonTypeFlags::Poly16: - return shift ? 15 : (4 << IsQuad) - 1; - case NeonTypeFlags::Int32: - return shift ? 31 : (2 << IsQuad) - 1; - case NeonTypeFlags::Int64: - case NeonTypeFlags::Poly64: - return shift ? 63 : (1 << IsQuad) - 1; - case NeonTypeFlags::Poly128: - return shift ? 127 : (1 << IsQuad) - 1; - case NeonTypeFlags::Float16: - assert(!shift && "cannot shift float types!"); - return (4 << IsQuad) - 1; - case NeonTypeFlags::Float32: - assert(!shift && "cannot shift float types!"); - return (2 << IsQuad) - 1; - case NeonTypeFlags::Float64: - assert(!shift && "cannot shift float types!"); - return (1 << IsQuad) - 1; - case NeonTypeFlags::BFloat16: - assert(!shift && "cannot shift float types!"); - return (4 << IsQuad) - 1; - } - llvm_unreachable("Invalid NeonTypeFlag!"); -} - /// getNeonEltType - Return the QualType corresponding to the elements of /// the vector type specified by the NeonTypeFlags. This is used to check /// the pointer arguments for Neon load/store intrinsics. @@ -404,142 +370,171 @@ enum ArmSMEState : unsigned { ArmZT0Mask = 0b11 << 2 }; -bool SemaARM::ParseSVEImmChecks( - CallExpr *TheCall, SmallVector, 3> &ImmChecks) { - // Perform all the immediate checks for this builtin call. +bool SemaARM::CheckImmediateArg(CallExpr *TheCall, unsigned CheckTy, + unsigned ArgIdx, unsigned EltBitWidth, + unsigned VecBitWidth) { + // Function that checks whether the operand (ArgIdx) is an immediate + // that is one of a given set of values. + auto CheckImmediateInSet = [&](std::initializer_list Set, + int ErrDiag) -> bool { + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgIdx); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + llvm::APSInt Imm; + if (SemaRef.BuiltinConstantArg(TheCall, ArgIdx, Imm)) + return true; + + if (std::find(Set.begin(), Set.end(), Imm.getSExtValue()) == Set.end()) + return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange(); + return false; + }; + + switch ((ImmCheckType)CheckTy) { + case ImmCheckType::ImmCheck0_31: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 31)) + return true; + break; + case ImmCheckType::ImmCheck0_13: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 13)) + return true; + break; + case ImmCheckType::ImmCheck0_63: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 63)) + return true; + break; + case ImmCheckType::ImmCheck1_16: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 16)) + return true; + break; + case ImmCheckType::ImmCheck0_7: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 7)) + return true; + break; + case ImmCheckType::ImmCheck1_1: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 1)) + return true; + break; + case ImmCheckType::ImmCheck1_3: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 3)) + return true; + break; + case ImmCheckType::ImmCheck1_7: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 7)) + return true; + break; + case ImmCheckType::ImmCheckExtract: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, + (2048 / EltBitWidth) - 1)) + return true; + break; + case ImmCheckType::ImmCheckCvt: + case ImmCheckType::ImmCheckShiftRight: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth)) + return true; + break; + case ImmCheckType::ImmCheckShiftRightNarrow: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth / 2)) + return true; + break; + case ImmCheckType::ImmCheckShiftLeft: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, EltBitWidth - 1)) + return true; + break; + case ImmCheckType::ImmCheckLaneIndex: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, + (VecBitWidth / EltBitWidth) - 1)) + return true; + break; + case ImmCheckType::ImmCheckLaneIndexCompRotate: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, + (VecBitWidth / (2 * EltBitWidth)) - 1)) + return true; + break; + case ImmCheckType::ImmCheckLaneIndexDot: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, + (VecBitWidth / (4 * EltBitWidth)) - 1)) + return true; + break; + case ImmCheckType::ImmCheckComplexRot90_270: + if (CheckImmediateInSet({90, 270}, diag::err_rotation_argument_to_cadd)) + return true; + break; + case ImmCheckType::ImmCheckComplexRotAll90: + if (CheckImmediateInSet({0, 90, 180, 270}, + diag::err_rotation_argument_to_cmla)) + return true; + break; + case ImmCheckType::ImmCheck0_1: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 1)) + return true; + break; + case ImmCheckType::ImmCheck0_2: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 2)) + return true; + break; + case ImmCheckType::ImmCheck0_3: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 3)) + return true; + break; + case ImmCheckType::ImmCheck0_0: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 0)) + return true; + break; + case ImmCheckType::ImmCheck0_15: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 15)) + return true; + break; + case ImmCheckType::ImmCheck0_255: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 255)) + return true; + break; + case ImmCheckType::ImmCheck1_32: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 32)) + return true; + break; + case ImmCheckType::ImmCheck1_64: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 64)) + return true; + break; + case ImmCheckType::ImmCheck2_4_Mul2: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 2, 4) || + SemaRef.BuiltinConstantArgMultiple(TheCall, ArgIdx, 2)) + return true; + break; + } + return false; +} + +bool SemaARM::PerformNeonImmChecks( + CallExpr *TheCall, + SmallVectorImpl> &ImmChecks, + int OverloadType) { bool HasError = false; - for (auto &I : ImmChecks) { - int ArgNum, CheckTy, ElementSizeInBits; - std::tie(ArgNum, CheckTy, ElementSizeInBits) = I; - - typedef bool (*OptionSetCheckFnTy)(int64_t Value); - - // Function that checks whether the operand (ArgNum) is an immediate - // that is one of the predefined values. - auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm, - int ErrDiag) -> bool { - // We can't check the value of a dependent argument. - Expr *Arg = TheCall->getArg(ArgNum); - if (Arg->isTypeDependent() || Arg->isValueDependent()) - return false; - - // Check constant-ness first. - llvm::APSInt Imm; - if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Imm)) - return true; - if (!CheckImm(Imm.getSExtValue())) - return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange(); - return false; - }; + for (const auto &I : ImmChecks) { + auto [ArgIdx, CheckTy, ElementSizeInBits, VecSizeInBits] = I; - switch ((SVETypeFlags::ImmCheckType)CheckTy) { - case SVETypeFlags::ImmCheck0_31: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 31)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_13: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 13)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_16: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 16)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_7: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 7)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_1: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_3: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 3)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_7: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 7)) - HasError = true; - break; - case SVETypeFlags::ImmCheckExtract: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, - (2048 / ElementSizeInBits) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckShiftRight: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, - ElementSizeInBits)) - HasError = true; - break; - case SVETypeFlags::ImmCheckShiftRightNarrow: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, - ElementSizeInBits / 2)) - HasError = true; - break; - case SVETypeFlags::ImmCheckShiftLeft: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, - ElementSizeInBits - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckLaneIndex: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, - (128 / (1 * ElementSizeInBits)) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckLaneIndexCompRotate: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, - (128 / (2 * ElementSizeInBits)) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckLaneIndexDot: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, - (128 / (4 * ElementSizeInBits)) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckComplexRot90_270: - if (CheckImmediateInSet([](int64_t V) { return V == 90 || V == 270; }, - diag::err_rotation_argument_to_cadd)) - HasError = true; - break; - case SVETypeFlags::ImmCheckComplexRotAll90: - if (CheckImmediateInSet( - [](int64_t V) { - return V == 0 || V == 90 || V == 180 || V == 270; - }, - diag::err_rotation_argument_to_cmla)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_1: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_2: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 2)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_3: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 3)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_0: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 0)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_15: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 15)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_255: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 255)) - HasError = true; - break; - case SVETypeFlags::ImmCheck2_4_Mul2: - if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 2, 4) || - SemaRef.BuiltinConstantArgMultiple(TheCall, ArgNum, 2)) - HasError = true; - break; - } + if (OverloadType >= 0) + ElementSizeInBits = NeonTypeFlags(OverloadType).getEltSizeInBits(); + + HasError |= CheckImmediateArg(TheCall, CheckTy, ArgIdx, ElementSizeInBits, + VecSizeInBits); + } + + return HasError; +} + +bool SemaARM::PerformSVEImmChecks( + CallExpr *TheCall, SmallVectorImpl> &ImmChecks) { + bool HasError = false; + + for (const auto &I : ImmChecks) { + auto [ArgIdx, CheckTy, ElementSizeInBits] = I; + HasError |= + CheckImmediateArg(TheCall, CheckTy, ArgIdx, ElementSizeInBits, 128); } return HasError; @@ -694,7 +689,7 @@ bool SemaARM::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, #undef GET_SME_IMMEDIATE_CHECK } - return ParseSVEImmChecks(TheCall, ImmChecks); + return PerformSVEImmChecks(TheCall, ImmChecks); } bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, @@ -722,7 +717,7 @@ bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, #undef GET_SVE_IMMEDIATE_CHECK } - return ParseSVEImmChecks(TheCall, ImmChecks); + return PerformSVEImmChecks(TheCall, ImmChecks); } bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, @@ -749,7 +744,7 @@ bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, llvm::APSInt Result; uint64_t mask = 0; - unsigned TV = 0; + int TV = -1; int PtrArgNum = -1; bool HasConstPtr = false; switch (BuiltinID) { @@ -802,7 +797,7 @@ bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, // For NEON intrinsics which take an immediate value as part of the // instruction, range check them here. - unsigned i = 0, l = 0, u = 0; + SmallVector, 2> ImmChecks; switch (BuiltinID) { default: return false; @@ -812,7 +807,7 @@ bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, #undef GET_NEON_IMMEDIATE_CHECK } - return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u + l); + return PerformNeonImmChecks(TheCall, ImmChecks, TV); } bool SemaARM::CheckMVEBuiltinFunctionCall(unsigned BuiltinID, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index b01765b6833a1..99500daca295c 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1844,6 +1844,44 @@ static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall) { return TheCall; } +static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall) { + if (S.checkArgCount(TheCall, 1)) + return ExprError(); + + ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); + if (Arg.isInvalid()) + return ExprError(); + QualType ParamTy = Arg.get()->getType(); + TheCall->setArg(0, Arg.get()); + TheCall->setType(S.Context.BoolTy); + + // Only accept pointers to objects as arguments, which should have object + // pointer or void pointer types. + if (const auto *PT = ParamTy->getAs()) { + // LWG4138: Function pointer types not allowed + if (PT->getPointeeType()->isFunctionType()) { + S.Diag(TheCall->getArg(0)->getExprLoc(), + diag::err_builtin_is_within_lifetime_invalid_arg) + << 1; + return ExprError(); + } + // Disallow VLAs too since those shouldn't be able to + // be a template parameter for `std::is_within_lifetime` + if (PT->getPointeeType()->isVariableArrayType()) { + S.Diag(TheCall->getArg(0)->getExprLoc(), diag::err_vla_unsupported) + << 1 << "__builtin_is_within_lifetime"; + return ExprError(); + } + } else { + S.Diag(TheCall->getArg(0)->getExprLoc(), + diag::err_builtin_is_within_lifetime_invalid_arg) + << 0; + return ExprError(); + } + + return TheCall; +} + // Emit an error and return true if the current object format type is in the // list of unsupported types. static bool CheckBuiltinTargetNotInUnsupported( @@ -2276,6 +2314,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, } case Builtin::BI__builtin_launder: return BuiltinLaunder(*this, TheCall); + case Builtin::BI__builtin_is_within_lifetime: + return BuiltinIsWithinLifetime(*this, TheCall); case Builtin::BI__sync_fetch_and_add: case Builtin::BI__sync_fetch_and_add_1: case Builtin::BI__sync_fetch_and_add_2: @@ -4896,10 +4936,19 @@ bool Sema::BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, // Usual Unary Conversions will convert half to float, which we want for // machines that use fp16 conversion intrinsics. Else, we wnat to leave the // type how it is, but do normal L->Rvalue conversions. - if (Context.getTargetInfo().useFP16ConversionIntrinsics()) - OrigArg = UsualUnaryConversions(OrigArg).get(); - else - OrigArg = DefaultFunctionArrayLvalueConversion(OrigArg).get(); + if (Context.getTargetInfo().useFP16ConversionIntrinsics()) { + ExprResult Res = UsualUnaryConversions(OrigArg); + + if (!Res.isUsable()) + return true; + OrigArg = Res.get(); + } else { + ExprResult Res = DefaultFunctionArrayLvalueConversion(OrigArg); + + if (!Res.isUsable()) + return true; + OrigArg = Res.get(); + } TheCall->setArg(FPArgNo, OrigArg); QualType VectorResultTy; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 33547c2e6e145..d068cb6a78f26 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6907,12 +6907,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_HLSLResourceBinding: S.HLSL().handleResourceBindingAttr(D, AL); break; - case ParsedAttr::AT_HLSLROV: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_HLSLResourceClass: - S.HLSL().handleResourceClassAttr(D, AL); - break; case ParsedAttr::AT_HLSLParamModifier: S.HLSL().handleParamModifierAttr(D, AL); break; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 3044f1218f5b2..f90f16c2923d0 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -8450,10 +8450,12 @@ class DefaultedComparisonSynthesizer if (Obj.first.isInvalid() || Obj.second.isInvalid()) return {ExprError(), ExprError()}; CXXCastPath Path = {Base}; - return {S.ImpCastExprToType(Obj.first.get(), Base->getType(), - CK_DerivedToBase, VK_LValue, &Path), - S.ImpCastExprToType(Obj.second.get(), Base->getType(), - CK_DerivedToBase, VK_LValue, &Path)}; + const auto CastToBase = [&](Expr *E) { + QualType ToType = S.Context.getQualifiedType( + Base->getType(), E->getType().getQualifiers()); + return S.ImpCastExprToType(E, ToType, CK_DerivedToBase, VK_LValue, &Path); + }; + return {CastToBase(Obj.first.get()), CastToBase(Obj.second.get())}; } ExprPair getField(FieldDecl *Field) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 94bb938b53b44..32dac4440fb82 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5443,11 +5443,24 @@ struct EnsureImmediateInvocationInDefaultArgs // Rewrite to source location to refer to the context in which they are used. ExprResult TransformSourceLocExpr(SourceLocExpr *E) { - if (E->getParentContext() == SemaRef.CurContext) + DeclContext *DC = E->getParentContext(); + if (DC == SemaRef.CurContext) return E; - return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(), - E->getBeginLoc(), E->getEndLoc(), - SemaRef.CurContext); + + // FIXME: During instantiation, because the rebuild of defaults arguments + // is not always done in the context of the template instantiator, + // we run the risk of producing a dependent source location + // that would never be rebuilt. + // This usually happens during overload resolution, or in contexts + // where the value of the source location does not matter. + // However, we should find a better way to deal with source location + // of function templates. + if (!SemaRef.CurrentInstantiationScope || + !SemaRef.CurContext->isDependentContext() || DC->isDependentContext()) + DC = SemaRef.CurContext; + + return getDerived().RebuildSourceLocExpr( + E->getIdentKind(), E->getType(), E->getBeginLoc(), E->getEndLoc(), DC); } }; @@ -17609,7 +17622,8 @@ HandleImmediateInvocations(Sema &SemaRef, (SemaRef.inTemplateInstantiation() && !ImmediateEscalating)) { SemaRef.Diag(DR->getBeginLoc(), diag::err_invalid_consteval_take_address) << ND << isa(ND) << FD->isConsteval(); - SemaRef.Diag(ND->getLocation(), diag::note_declared_at); + if (!FD->getBuiltinID()) + SemaRef.Diag(ND->getLocation(), diag::note_declared_at); if (auto Context = SemaRef.InnermostDeclarationWithDelayedImmediateInvocations()) { SemaRef.Diag(Context->Loc, diag::note_invalid_consteval_initializer) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b7531581d37ff..14feafd1e6b17 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -5111,6 +5111,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, case UTT_IsDestructible: case UTT_IsNothrowDestructible: case UTT_IsTriviallyDestructible: + case UTT_IsIntangibleType: if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType()) return true; @@ -5696,6 +5697,16 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return true; return false; } + case UTT_IsIntangibleType: + assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature"); + if (!T->isVoidType() && !T->isIncompleteArrayType()) + if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T, + diag::err_incomplete_type)) + return false; + if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, + tok::kw___builtin_hlsl_is_intangible)) + return false; + return Self.HLSL().IsIntangibleType(T); } } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 778d524a00548..3b40769939f12 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -9,9 +9,13 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaHLSL.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Type.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" @@ -19,7 +23,9 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/ParsedAttr.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" @@ -27,6 +33,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/TargetParser/Triple.h" #include +#include using namespace clang; @@ -556,46 +563,125 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } -void SemaHLSL::handleResourceClassAttr(Decl *D, const ParsedAttr &AL) { - if (!AL.isArgIdent(0)) { - Diag(AL.getLoc(), diag::err_attribute_argument_type) - << AL << AANT_ArgumentIdentifier; - return; - } +bool clang::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, + ArrayRef AttrList, + QualType &ResType) { + assert(AttrList.size() && "expected list of resource attributes"); - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Identifier = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; + QualType Contained = QualType(); + HLSLAttributedResourceType::Attributes ResAttrs = {}; - // Validate. - llvm::dxil::ResourceClass RC; - if (!HLSLResourceClassAttr::ConvertStrToResourceClass(Identifier, RC)) { - Diag(ArgLoc, diag::warn_attribute_type_not_supported) - << "ResourceClass" << Identifier; - return; + bool HasResourceClass = false; + for (const Attr *A : AttrList) { + if (!A) + continue; + switch (A->getKind()) { + case attr::HLSLResourceClass: { + llvm::dxil::ResourceClass RC = + cast(A)->getResourceClass(); + if (HasResourceClass) { + S.Diag(A->getLocation(), ResAttrs.ResourceClass == RC + ? diag::warn_duplicate_attribute_exact + : diag::warn_duplicate_attribute) + << A; + return false; + } + ResAttrs.ResourceClass = RC; + HasResourceClass = true; + break; + } + case attr::HLSLROV: + ResAttrs.IsROV = true; + break; + default: + llvm_unreachable("unhandled resource attribute type"); + } + } + + if (!HasResourceClass) { + S.Diag(AttrList.back()->getRange().getEnd(), + diag::err_hlsl_missing_resource_class); + return false; } - D->addAttr(HLSLResourceClassAttr::Create(getASTContext(), RC, ArgLoc)); + ResType = S.getASTContext().getHLSLAttributedResourceType(Wrapped, Contained, + ResAttrs); + return true; } -// Validates HLSL resource type attribute and adds it to the list to be -// processed into a single HLSLAttributedResourceType later on. -// Returns false if the attribute is invalid. +// Validates and creates an HLSL attribute that is applied as type attribute on +// HLSL resource. The attributes are collected in HLSLResourcesTypeAttrs and at +// the end of the declaration they are applied to the declaration type by +// wrapping it in HLSLAttributedResourceType. bool SemaHLSL::handleResourceTypeAttr(const ParsedAttr &AL) { - // FIXME: placeholder - not yet implemented + Attr *A = nullptr; + + // validate number of arguments + if (!AL.checkExactlyNumArgs(SemaRef, AL.getMinArgs())) + return false; + + switch (AL.getKind()) { + case ParsedAttr::AT_HLSLResourceClass: { + if (!AL.isArgIdent(0)) { + Diag(AL.getLoc(), diag::err_attribute_argument_type) + << AL << AANT_ArgumentIdentifier; + return false; + } + + IdentifierLoc *Loc = AL.getArgAsIdent(0); + StringRef Identifier = Loc->Ident->getName(); + SourceLocation ArgLoc = Loc->Loc; + + // Validate resource class value + llvm::dxil::ResourceClass RC; + if (!HLSLResourceClassAttr::ConvertStrToResourceClass(Identifier, RC)) { + Diag(ArgLoc, diag::warn_attribute_type_not_supported) + << "ResourceClass" << Identifier; + return false; + } + A = HLSLResourceClassAttr::Create(getASTContext(), RC, AL.getLoc()); + break; + } + case ParsedAttr::AT_HLSLROV: + A = HLSLROVAttr::Create(getASTContext(), AL.getLoc()); + break; + default: + llvm_unreachable("unhandled HLSL attribute"); + } + + HLSLResourcesTypeAttrs.emplace_back(A); return true; } -// Combines all resource type attributes and create HLSLAttributedResourceType. +// Combines all resource type attributes and creates HLSLAttributedResourceType. QualType SemaHLSL::ProcessResourceTypeAttributes(QualType CurrentType) { - // FIXME: placeholder - not yet implemented - return CurrentType; + if (!HLSLResourcesTypeAttrs.size()) + return CurrentType; + + QualType QT = CurrentType; + if (CreateHLSLAttributedResourceType(SemaRef, CurrentType, + HLSLResourcesTypeAttrs, QT)) { + const HLSLAttributedResourceType *RT = + dyn_cast(QT.getTypePtr()); + // Use the location of the first attribute as the location of the aggregated + // type. The attributes are stored in HLSLResourceTypeAttrs in the same + // order as they are parsed. + SourceLocation Loc = HLSLResourcesTypeAttrs[0]->getLoc(); + LocsForHLSLAttributedResources.insert(std::pair(RT, Loc)); + } + HLSLResourcesTypeAttrs.clear(); + return QT; } // Returns source location for the HLSLAttributedResourceType SourceLocation SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) { - // FIXME: placeholder - not yet implemented + auto I = LocsForHLSLAttributedResources.find(RT); + if (I != LocsForHLSLAttributedResources.end()) { + SourceLocation Loc = I->second; + LocsForHLSLAttributedResources.erase(I); + return Loc; + } return SourceLocation(); } @@ -653,33 +739,19 @@ static void updateResourceClassFlagsFromDeclResourceClass( } } -template -static const T *getSpecifiedHLSLAttrFromRecordDecl(RecordDecl *TheRecordDecl) { - if (!TheRecordDecl) - return nullptr; - - if (TheRecordDecl->hasAttr()) - return TheRecordDecl->getAttr(); - for (auto *FD : TheRecordDecl->fields()) { - const T *Attr = FD->getAttr(); - if (Attr) - return Attr; +const HLSLAttributedResourceType * +findAttributedResourceTypeOnField(VarDecl *VD) { + assert(VD != nullptr && "expected VarDecl"); + if (RecordDecl *RD = getRecordDeclFromVarDecl(VD)) { + for (auto *FD : RD->fields()) { + if (const HLSLAttributedResourceType *AttrResType = + dyn_cast(FD->getType().getTypePtr())) + return AttrResType; + } } return nullptr; } -template -static const T *getSpecifiedHLSLAttrFromVarDecl(VarDecl *VD) { - RecordDecl *TheRecordDecl = nullptr; - if (VD) { - TheRecordDecl = getRecordDeclFromVarDecl(VD); - if (!TheRecordDecl) - return nullptr; - } - - return getSpecifiedHLSLAttrFromRecordDecl(TheRecordDecl); -} - static void updateResourceClassFlagsFromRecordType(RegisterBindingFlags &Flags, const RecordType *RT) { llvm::SmallVector TypesToScan; @@ -699,10 +771,11 @@ static void updateResourceClassFlagsFromRecordType(RegisterBindingFlags &Flags, const RecordDecl *RD = RT->getDecl(); for (FieldDecl *FD : RD->fields()) { - if (HLSLResourceClassAttr *RCAttr = - FD->getAttr()) { + const Type *FieldTy = FD->getType().getTypePtr(); + if (const HLSLAttributedResourceType *AttrResType = + dyn_cast(FieldTy)) { updateResourceClassFlagsFromDeclResourceClass( - Flags, RCAttr->getResourceClass()); + Flags, AttrResType->getAttrs().ResourceClass); continue; } TypesToScan.emplace_back(FD->getType().getTypePtr()); @@ -729,11 +802,10 @@ static RegisterBindingFlags HLSLFillRegisterBindingFlags(Sema &S, } // Samplers, UAVs, and SRVs are VarDecl types else if (VarDecl *TheVarDecl = dyn_cast(TheDecl)) { - const HLSLResourceClassAttr *resClassAttr = - getSpecifiedHLSLAttrFromVarDecl(TheVarDecl); - if (resClassAttr) { + if (const HLSLAttributedResourceType *AttrResType = + findAttributedResourceTypeOnField(TheVarDecl)) { Flags.Resource = true; - Flags.ResourceClass = resClassAttr->getResourceClass(); + Flags.ResourceClass = AttrResType->getAttrs().ResourceClass; } else { const clang::Type *TheBaseType = TheVarDecl->getType().getTypePtr(); while (TheBaseType->isArrayType()) @@ -834,17 +906,10 @@ static void ValidateMultipleRegisterAnnotations(Sema &S, Decl *TheDecl, static void DiagnoseHLSLRegisterAttribute(Sema &S, SourceLocation &ArgLoc, Decl *TheDecl, RegisterType regType) { - // Samplers, UAVs, and SRVs are VarDecl types - VarDecl *TheVarDecl = dyn_cast(TheDecl); - // Cbuffers and Tbuffers are HLSLBufferDecl types - HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(TheDecl); - // exactly one of these two types should be set - assert(((TheVarDecl && !CBufferOrTBuffer) || - (!TheVarDecl && CBufferOrTBuffer)) && - "either TheVarDecl or CBufferOrTBuffer should be set"); - (void)TheVarDecl; - (void)CBufferOrTBuffer; + assert(((isa(TheDecl) && !isa(TheDecl)) || + (!isa(TheDecl) && isa(TheDecl))) && + "expecting VarDecl or HLSLBufferDecl"); RegisterBindingFlags Flags = HLSLFillRegisterBindingFlags(S, TheDecl); assert((int)Flags.Other + (int)Flags.Resource + (int)Flags.Basic + @@ -1609,6 +1674,31 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return false; } +bool SemaHLSL::IsIntangibleType(clang::QualType QT) { + if (QT.isNull()) + return false; + + const Type *Ty = QT->getUnqualifiedDesugaredType(); + + // check if it's a builtin type first (simple check, no need to cache it) + if (Ty->isBuiltinType()) + return Ty->isHLSLIntangibleType(); + + // unwrap arrays + while (isa(Ty)) + Ty = Ty->getArrayElementTypeNoTypeQual(); + + const RecordType *RT = + dyn_cast(Ty->getUnqualifiedDesugaredType()); + if (!RT) + return false; + + CXXRecordDecl *RD = RT->getAsCXXRecordDecl(); + assert(RD != nullptr && + "all HLSL struct and classes should be CXXRecordDecl"); + return RD->isHLSLIntangible(); +} + static void BuildFlattenedTypeList(QualType BaseTy, llvm::SmallVectorImpl &List) { llvm::SmallVector WorkList; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 95551173df91a..861b0a91240b3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14768,7 +14768,9 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // Check for a self move. DiagnoseSelfMove(Args[0], Args[1], OpLoc); // lifetime check. - checkExprLifetime(*this, AssignedEntity{Args[0]}, Args[1]); + checkExprLifetime( + *this, AssignedEntity{Args[0], dyn_cast(FnDecl)}, + Args[1]); } if (ImplicitThis) { QualType ThisType = Context.getPointerType(ImplicitThis->getType()); diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index abf8e4ac2f3e8..56d6f12fbc6e4 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -733,7 +733,7 @@ bool SemaRISCV::CheckBuiltinFunctionCall(const TargetInfo &TI, if (ElemSize == 64 && !TI.hasFeature("zvknhb")) return Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension) - << /* IsExtension */ true << TheCall->getSourceRange() << "zvknb"; + << /* IsExtension */ true << TheCall->getSourceRange() << "zvknhb"; return CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op1Type, ElemSize * 4) || diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7df8f663da26a..520dce870b7b7 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6490,6 +6490,15 @@ static void HandleBTFTypeTagAttribute(QualType &Type, const ParsedAttr &Attr, TypeProcessingState &State) { Sema &S = State.getSema(); + // This attribute is only supported in C. + // FIXME: we should implement checkCommonAttributeFeatures() in SemaAttr.cpp + // such that it handles type attributes, and then call that from + // processTypeAttrs() instead of one-off checks like this. + if (!Attr.diagnoseLangOpts(S)) { + Attr.setInvalid(); + return; + } + // Check the number of attribute arguments. if (Attr.getNumArgs() != 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) diff --git a/clang/lib/Sema/SemaX86.cpp b/clang/lib/Sema/SemaX86.cpp index 311e574537059..233a068c8574c 100644 --- a/clang/lib/Sema/SemaX86.cpp +++ b/clang/lib/Sema/SemaX86.cpp @@ -875,6 +875,9 @@ bool SemaX86::CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, case X86::BI__builtin_ia32_rndscaleps_mask: case X86::BI__builtin_ia32_rndscalepd_mask: case X86::BI__builtin_ia32_rndscaleph_mask: + case X86::BI__builtin_ia32_vrndscalenepbf16_128_mask: + case X86::BI__builtin_ia32_vrndscalenepbf16_256_mask: + case X86::BI__builtin_ia32_vrndscalenepbf16_mask: case X86::BI__builtin_ia32_reducepd128_mask: case X86::BI__builtin_ia32_reducepd256_mask: case X86::BI__builtin_ia32_reducepd512_mask: @@ -884,6 +887,9 @@ bool SemaX86::CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, case X86::BI__builtin_ia32_reduceph128_mask: case X86::BI__builtin_ia32_reduceph256_mask: case X86::BI__builtin_ia32_reduceph512_mask: + case X86::BI__builtin_ia32_vreducenepbf16128_mask: + case X86::BI__builtin_ia32_vreducenepbf16256_mask: + case X86::BI__builtin_ia32_vreducenepbf16512_mask: case X86::BI__builtin_ia32_vreducepd256_round_mask: case X86::BI__builtin_ia32_vreduceps256_round_mask: case X86::BI__builtin_ia32_vreduceph256_round_mask: @@ -911,6 +917,9 @@ bool SemaX86::CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, case X86::BI__builtin_ia32_fpclassph128_mask: case X86::BI__builtin_ia32_fpclassph256_mask: case X86::BI__builtin_ia32_fpclassph512_mask: + case X86::BI__builtin_ia32_vfpclasspbf16128_mask: + case X86::BI__builtin_ia32_vfpclasspbf16256_mask: + case X86::BI__builtin_ia32_vfpclasspbf16512_mask: case X86::BI__builtin_ia32_fpclasssd_mask: case X86::BI__builtin_ia32_fpclassss_mask: case X86::BI__builtin_ia32_fpclasssh_mask: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 66e3f27fed9de..0daf620b4123e 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6687,10 +6687,10 @@ TreeTransform::TransformPackIndexingType(TypeLocBuilder &TLB, bool NotYetExpanded = Types.empty(); bool FullySubstituted = true; - if (Types.empty()) + if (Types.empty() && !PIT->expandsToEmptyPack()) Types = llvm::ArrayRef(&Pattern, 1); - for (const QualType &T : Types) { + for (QualType T : Types) { if (!T->containsUnexpandedParameterPack()) { QualType Transformed = getDerived().TransformType(T); if (Transformed.isNull()) @@ -7462,8 +7462,26 @@ QualType TreeTransform::TransformBTFTagAttributedType( template QualType TreeTransform::TransformHLSLAttributedResourceType( TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) { - llvm_unreachable( - "Unexpected TreeTransform for HLSLAttributedResourceTypeLoc"); + + const HLSLAttributedResourceType *oldType = TL.getTypePtr(); + + QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc()); + if (WrappedTy.isNull()) + return QualType(); + + QualType ContainedTy = QualType(); + if (!oldType->getContainedType().isNull()) + ContainedTy = getDerived().TransformType(TLB, TL.getContainedLoc()); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() || + ContainedTy != oldType->getContainedType()) { + Result = SemaRef.Context.getHLSLAttributedResourceType( + WrappedTy, ContainedTy, oldType->getAttrs()); + } + + TLB.push(Result); + return Result; } template diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index dfb7111b51255..315d85319a85a 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1207,9 +1207,14 @@ void ExprEngine::ProcessInitializer(const CFGInitializer CFGInit, Init = ASE->getBase()->IgnoreImplicit(); SVal LValue = State->getSVal(Init, stackFrame); - if (!Field->getType()->isReferenceType()) - if (std::optional LValueLoc = LValue.getAs()) + if (!Field->getType()->isReferenceType()) { + if (std::optional LValueLoc = LValue.getAs()) { InitVal = State->getSVal(*LValueLoc); + } else if (auto CV = LValue.getAs()) { + // Initializer list for an array. + InitVal = *CV; + } + } // If we fail to get the value for some reason, use a symbolic value. if (InitVal.isUnknownOrUndef()) { diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 1a21a4f5e30ff..09ad5ebc7954c 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -430,7 +430,9 @@ class DependencyScanningAction : public tooling::ToolAction { std::unique_ptr Action; - if (ModuleName) + if (Format == ScanningOutputFormat::P1689) + Action = std::make_unique(); + else if (ModuleName) Action = std::make_unique(*ModuleName); else Action = std::make_unique(); diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index 370d834846859..c775adc0ddd73 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -569,12 +569,11 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { return {}; // If this module has been handled already, just return its ID. - auto ModI = MDC.ModularDeps.insert({M, nullptr}); - if (!ModI.second) - return ModI.first->second->ID; + if (auto ModI = MDC.ModularDeps.find(M); ModI != MDC.ModularDeps.end()) + return ModI->second->ID; - ModI.first->second = std::make_unique(); - ModuleDeps &MD = *ModI.first->second; + auto OwnedMD = std::make_unique(); + ModuleDeps &MD = *OwnedMD; MD.ID.ModuleName = M->getFullModuleName(); MD.IsSystem = M->IsSystem; @@ -650,6 +649,8 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { MD.BuildInfo = std::move(CI); + MDC.ModularDeps.insert({M, std::move(OwnedMD)}); + return MD.ID; } diff --git a/clang/test/AST/ByteCode/constexpr-vectors.cpp b/clang/test/AST/ByteCode/constexpr-vectors.cpp index a738cfe617a0e..684c5810702cc 100644 --- a/clang/test/AST/ByteCode/constexpr-vectors.cpp +++ b/clang/test/AST/ByteCode/constexpr-vectors.cpp @@ -15,8 +15,50 @@ using FourI128ExtVec __attribute__((ext_vector_type(4))) = __int128; // Only int vs float makes a difference here, so we only need to test 1 of each. // Test Char to make sure the mixed-nature of shifts around char is evident. void CharUsage() { - constexpr auto H = FourCharsVecSize{-1, -1, 0, -1}; - constexpr auto InvH = -H; + constexpr auto w = FourCharsVecSize{1, 2, 3, 4} < + FourCharsVecSize{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourCharsVecSize{1, 2, 3, 4} > + FourCharsVecSize{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, ""); + + constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <= + FourCharsVecSize{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >= + FourCharsVecSize{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourCharsVecSize{1, 2, 3, 4} == + FourCharsVecSize{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourCharsVecSize{1, 2, 3, 4} != + FourCharsVecSize{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + + constexpr auto H1 = FourCharsVecSize{-1, -1, 0, -1}; + constexpr auto InvH = -H1; static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, ""); constexpr auto ae = ~FourCharsVecSize{1, 2, 10, 20}; @@ -27,8 +69,50 @@ void CharUsage() { } void CharExtVecUsage() { - constexpr auto H = FourCharsExtVec{-1, -1, 0, -1}; - constexpr auto InvH = -H; + constexpr auto w = FourCharsExtVec{1, 2, 3, 4} < + FourCharsExtVec{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourCharsExtVec{1, 2, 3, 4} > + FourCharsExtVec{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, ""); + + constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <= + FourCharsExtVec{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >= + FourCharsExtVec{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourCharsExtVec{1, 2, 3, 4} == + FourCharsExtVec{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourCharsExtVec{1, 2, 3, 4} != + FourCharsExtVec{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + + constexpr auto H1 = FourCharsExtVec{-1, -1, 0, -1}; + constexpr auto InvH = -H1; static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, ""); constexpr auto ae = ~FourCharsExtVec{1, 2, 10, 20}; @@ -39,6 +123,48 @@ void CharExtVecUsage() { } void FloatUsage() { + constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, ""); + + constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00}; constexpr auto Z = -Y; static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, ""); @@ -51,6 +177,48 @@ void FloatUsage() { } void FloatVecUsage() { + constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[2] == -1, ""); + + constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00}; constexpr auto Z = -Y; static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, ""); @@ -63,6 +231,12 @@ void FloatVecUsage() { } void I128Usage() { + constexpr auto a = FourI128VecSize{1, 2, 3, 4}; + static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, ""); + + constexpr auto b = a < 3; + static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, ""); + // Operator ~ is illegal on floats, so no test for that. constexpr auto c = ~FourI128VecSize{1, 2, 10, 20}; static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, ""); @@ -72,6 +246,12 @@ void I128Usage() { } void I128VecUsage() { + constexpr auto a = FourI128ExtVec{1, 2, 3, 4}; + static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, ""); + + constexpr auto b = a < 3; + static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, ""); + // Operator ~ is illegal on floats, so no test for that. constexpr auto c = ~FourI128ExtVec{1, 2, 10, 20}; static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, ""); @@ -82,6 +262,30 @@ void I128VecUsage() { using FourBoolsExtVec __attribute__((ext_vector_type(4))) = bool; void BoolVecUsage() { + constexpr auto a = FourBoolsExtVec{true, false, true, false} < + FourBoolsExtVec{false, false, true, true}; + static_assert(a[0] == false && a[1] == false && a[2] == false && a[3] == true, ""); + + constexpr auto b = FourBoolsExtVec{true, false, true, false} <= + FourBoolsExtVec{false, false, true, true}; + static_assert(b[0] == false && b[1] == true && b[2] == true && b[3] == true, ""); + + constexpr auto c = FourBoolsExtVec{true, false, true, false} == + FourBoolsExtVec{false, false, true, true}; + static_assert(c[0] == false && c[1] == true && c[2] == true && c[3] == false, ""); + + constexpr auto d = FourBoolsExtVec{true, false, true, false} != + FourBoolsExtVec{false, false, true, true}; + static_assert(d[0] == true && d[1] == false && d[2] == false && d[3] == true, ""); + + constexpr auto e = FourBoolsExtVec{true, false, true, false} >= + FourBoolsExtVec{false, false, true, true}; + static_assert(e[0] == true && e[1] == true && e[2] == true && e[3] == false, ""); + + constexpr auto f = FourBoolsExtVec{true, false, true, false} > + FourBoolsExtVec{false, false, true, true}; + static_assert(f[0] == true && f[1] == false && f[2] == false && f[3] == false, ""); + constexpr auto j = !FourBoolsExtVec{true, false, true, false}; static_assert(j[0] == false && j[1] == true && j[2] == false && j[3] == true, ""); diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp index 2329d4d973f01..13d6c4feb3500 100644 --- a/clang/test/AST/ByteCode/literals.cpp +++ b/clang/test/AST/ByteCode/literals.cpp @@ -199,12 +199,8 @@ namespace PointerComparison { constexpr bool v3 = null == pv; // ok constexpr bool v4 = qv == pv; // ok - /// FIXME: These two are rejected by the current interpreter, but - /// accepted by GCC. - constexpr bool v5 = qv >= pv; // ref-error {{constant expression}} \ - // ref-note {{unequal pointers to void}} - constexpr bool v8 = qv > (void*)&s.a; // ref-error {{constant expression}} \ - // ref-note {{unequal pointers to void}} + constexpr bool v5 = qv >= pv; + constexpr bool v8 = qv > (void*)&s.a; constexpr bool v6 = qv > null; // both-error {{must be initialized by a constant expression}} \ // both-note {{comparison between '&s.b' and 'nullptr' has unspecified value}} diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl index 1f6ef60e121ea..0e7803ce50a89 100644 --- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl @@ -30,8 +30,7 @@ RWBuffer Buffer; // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit class RWBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final -// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit h 'element_type *' -// CHECK-NEXT: HLSLResourceClassAttr 0x{{[0-9A-Fa-f]+}} <> Implicit UAV +// CHECK-NEXT: implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit TypedBuffer // CHECK: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'element_type &const (unsigned int) const' @@ -39,7 +38,7 @@ RWBuffer Buffer; // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type' lvalue -// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}} +// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}} // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'const RWBuffer' lvalue implicit this // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline @@ -49,7 +48,7 @@ RWBuffer Buffer; // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type' lvalue -// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}} +// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}} // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'RWBuffer' lvalue implicit this // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline @@ -59,6 +58,5 @@ RWBuffer Buffer; // CHECK: TemplateArgument type 'float' // CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float' // CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final -// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit referenced h 'float *' -// CHECK-NEXT: HLSLResourceClassAttr 0x{{[0-9A-Fa-f]+}} <> Implicit UAV +// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *' // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit TypedBuffer diff --git a/clang/test/Analysis/ctor-array.cpp b/clang/test/Analysis/ctor-array.cpp index 49412ee5a68c7..52600b314b010 100644 --- a/clang/test/Analysis/ctor-array.cpp +++ b/clang/test/Analysis/ctor-array.cpp @@ -234,16 +234,58 @@ struct Parent { void member() { Parent arr[2]; - // FIXME: Ideally these are TRUE, but at the moment InitListExpr has no - // knowledge about where the initializer list is used, so we can't bind - // the initializer list to the required region. - clang_analyzer_eval(arr[0].arr[0].x == 1); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(arr[0].arr[0].y == 2); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(arr[0].arr[1].x == 3); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(arr[0].arr[1].y == 4); // expected-warning{{UNKNOWN}} - - clang_analyzer_eval(arr[1].arr[0].x == 1); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(arr[1].arr[0].y == 2); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(arr[1].arr[1].x == 3); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(arr[1].arr[1].y == 4); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(arr[0].arr[0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(arr[0].arr[0].y == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(arr[0].arr[1].x == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(arr[0].arr[1].y == 4); // expected-warning{{TRUE}} + + clang_analyzer_eval(arr[1].arr[0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(arr[1].arr[0].y == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(arr[1].arr[1].x == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(arr[1].arr[1].y == 4); // expected-warning{{TRUE}} +} + +struct HasArr { + int arrDefault[2] = {1, 2}; + int arr[2]; + HasArr(int x, int y) : arr{x, y} {} +}; + +struct ArrCombination : public HasArr { + HasArr membDefault = {5, 6}; + HasArr memb; + ArrCombination(int x) : HasArr(3, 4), memb{7, x} {} +}; + +void derived_and_member() { + ArrCombination a{8}; + // FIXME: Default initializers for array members are not modeled. + clang_analyzer_eval(a.arrDefault[0] == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.arrDefault[1] == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.arr[0] == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(a.arr[1] == 4); // expected-warning{{TRUE}} + clang_analyzer_eval(a.membDefault.arrDefault[0] == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.membDefault.arrDefault[1] == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.membDefault.arr[0] == 5); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.membDefault.arr[1] == 6); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.memb.arrDefault[0] == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.memb.arrDefault[1] == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a.memb.arr[0] == 7); // expected-warning{{TRUE}} + clang_analyzer_eval(a.memb.arr[1] == 8); // expected-warning{{TRUE}} + +} + +struct IncompleteArrInit { + int arr[2]; + int arrDefault[3] = {1, 2, 3}; + IncompleteArrInit() : arr{1}, arrDefault{2, 3} {} +}; + +void incomplete_array_init() { + IncompleteArrInit a; + clang_analyzer_eval(a.arr[0] == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.arr[1] == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(a.arrDefault[0] == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.arrDefault[1] == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(a.arrDefault[2] == 0); // expected-warning{{TRUE}} } diff --git a/clang/test/Analysis/nullptr.cpp b/clang/test/Analysis/nullptr.cpp index 825f6570af591..73f10a08d96c8 100644 --- a/clang/test/Analysis/nullptr.cpp +++ b/clang/test/Analysis/nullptr.cpp @@ -173,3 +173,19 @@ void test_address_space_bind() { AS1 AS_ATTRIBUTE &r = *pa; r.x = 0; // no-warning } + +namespace ArrMemWithCtorInitializer { +struct ArrayMem { + int* ptrArr[1]; + int* memPtr; + ArrayMem() : ptrArr{nullptr}, memPtr{nullptr} {} + // expected-note@-1{{Storing null pointer value}} +}; + +void tp() { + ArrayMem obj; // expected-note{{Calling default constructor for 'ArrayMem'}} + // expected-note@-1{{Returning from default constructor for 'ArrayMem'}} + *obj.ptrArr[0] = 0; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // namespace ArrMemWithCtorInitializer diff --git a/clang/test/CXX/drs/cwg1818.cpp b/clang/test/CXX/drs/cwg1818.cpp new file mode 100644 index 0000000000000..bf2d12696a729 --- /dev/null +++ b/clang/test/CXX/drs/cwg1818.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++23 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++2c %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s + +// expected-no-diagnostics + +namespace cwg1818 { // cwg1818: 3.4 +extern "C" void f() { + // This declaration binds name 'g' in the scope of function 'f', + // but its target scope corresponds to namespace 'cwg1818' (_N4988_.[dcl.meaning]/3.5). + // Linkage specification of 'f' applies to 'g' per _N4988_.[dcl.link]/5. + void g(); +} +// Target scope of this declaration is naturally the one +// that corresponds to namespace 'cwg1818', +// which makes it declare the same entity +// as the previous declaration per _N4988_.[basic.link]/8, +// turning it into a redeclaration per _N4988_.[basic.def]/1. +// Then _N4988_.[dcl.link]/6 applies, making it inherit +// the (С) language linkage of the previous declaration. +void g(); +} // namespace cwg1818 + +// Check that the former 'g' has C language linkage, +// then that the latter 'g' is considered to be a redeclaration of it, +// which would make the latter 'g' inherit C language linkage from the former 'g'. + +// CHECK: LinkageSpecDecl [[LINKAGE_DECL:0x[0-9a-f]+]] {{.*}} C +// CHECK: FunctionDecl [[FIRST_DECL:0x[0-9a-f]+]] parent [[LINKAGE_DECL]] {{.*}} g 'void ()' +// CHECK: FunctionDecl {{.*}} prev [[FIRST_DECL]] {{.*}} g 'void ()' diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index adfdb738e81c9..61b7faa96a9fb 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -222,6 +222,8 @@ namespace cwg1815 { // cwg1815: no #endif } +// cwg1818 is in cwg1818.cpp + namespace cwg1820 { // cwg1820: 3.5 typedef int A; typedef int cwg1820::A; diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp index 00b6bb5a865df..79e9d031ef41c 100644 --- a/clang/test/CXX/drs/cwg24xx.cpp +++ b/clang/test/CXX/drs/cwg24xx.cpp @@ -1,15 +1,11 @@ -// RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected -// RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected -// RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected +// RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected,cxx98-14 +// RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected,cxx98-14 +// RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected,cxx98-14 // RUN: %clang_cc1 -std=c++17 -pedantic-errors %s -verify=expected,since-cxx17 // RUN: %clang_cc1 -std=c++20 -pedantic-errors %s -verify=expected,since-cxx17 // RUN: %clang_cc1 -std=c++23 -pedantic-errors %s -verify=expected,since-cxx17 // RUN: %clang_cc1 -std=c++2c -pedantic-errors %s -verify=expected,since-cxx17 -#if __cplusplus <= 201402L -// expected-no-diagnostics -#endif - namespace cwg2406 { // cwg2406: 5 #if __cplusplus >= 201703L void fallthrough(int n) { @@ -186,3 +182,36 @@ namespace cwg2445 { // cwg2445: 19 } #endif } + +namespace cwg2486 { // cwg2486: 4 c++17 +struct C { + void fn() throw(); +}; + +static void call(C& c, void (C::*f)()) { + (c.*f)(); +} + +static void callNE(C& c, void (C::*f)() throw()) { +// cxx98-14-warning@-1 {{mangled name of 'callNE' will change in C++17 due to non-throwing exception specification in function signature}} + (c.*f)(); +} + +void ref() { + C c; + call(c, &C::fn); // <= implicit cast removes noexcept + callNE(c, &C::fn); +} + +void (*p)(); +void (*pp)() throw() = p; +// since-cxx17-error@-1 {{cannot initialize a variable of type 'void (*)() throw()' with an lvalue of type 'void (*)()': different exception specifications}} + +struct S { + typedef void (*p)(); + operator p(); // #cwg2486-conv +}; +void (*q)() throw() = S(); +// since-cxx17-error@-1 {{no viable conversion from 'S' to 'void (*)() throw()'}} +// since-cxx17-note@#cwg2486-conv {{candidate function}} +} // namespace cwg2486 diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp index 406c8ea41f3b2..2b57dbc60aed7 100644 --- a/clang/test/CXX/drs/cwg27xx.cpp +++ b/clang/test/CXX/drs/cwg27xx.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++98 -pedantic-errors -verify=expected %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++98 -pedantic-errors -verify=expected,cxx98 %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -pedantic-errors -verify=expected %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++14 -pedantic-errors -verify=expected %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -pedantic-errors -verify=expected %s @@ -6,6 +6,29 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -pedantic-errors -verify=expected,since-cxx23 %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++2c -pedantic-errors -verify=expected,since-cxx23,since-cxx26 %s +#if __cplusplus == 199711L +#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) +// cxx98-error@-1 {{variadic macros are a C99 feature}} +#endif + +#if __cplusplus == 199711L +#define __enable_constant_folding(x) (__builtin_constant_p(x) ? (x) : (x)) +#else +#define __enable_constant_folding +#endif + +namespace std { +#if __cplusplus >= 202002L + struct strong_ordering { + int n; + constexpr operator int() const { return n; } + static const strong_ordering less, equal, greater; + }; + constexpr strong_ordering strong_ordering::less{-1}, + strong_ordering::equal{0}, strong_ordering::greater{1}; +#endif +} // namespace std + namespace cwg2718 { // cwg2718: 2.7 struct B {}; struct D; @@ -18,6 +41,27 @@ void f(B b) { struct D : B {}; } // namespace cwg2718 +namespace cwg2749 { // cwg2749: 20 + +extern int x[2]; +struct Y { + int i; + int j; +}; +extern Y y[2]; + +static_assert(__enable_constant_folding(static_cast(&x[0]) < static_cast(&x[1])), ""); +static_assert(__enable_constant_folding(static_cast(&y[0].i) < static_cast(&y[0].j)), ""); +static_assert(__enable_constant_folding(static_cast(&y[0].j) < static_cast(&y[1].i)), ""); + +#if __cplusplus >= 202002L +static_assert((static_cast(&x[0]) <=> static_cast(&x[1])) == std::strong_ordering::less); +static_assert((static_cast(&y[0].i) <=> static_cast(&y[0].j)) == std::strong_ordering::less); +static_assert((static_cast(&y[0].j) <=> static_cast(&y[1].i)) == std::strong_ordering::less); +#endif + +} // namespace cwg2749 + namespace cwg2759 { // cwg2759: 19 #if __cplusplus >= 201103L @@ -134,7 +178,7 @@ void test() { } namespace cwg2798 { // cwg2798: 17 -#if __cpp_static_assert >= 202306 +#if __cplusplus > 202302L struct string { constexpr string() { data_ = new char[6](); diff --git a/clang/test/CXX/drs/cwg563.cpp b/clang/test/CXX/drs/cwg563.cpp new file mode 100644 index 0000000000000..d585fefc44ffc --- /dev/null +++ b/clang/test/CXX/drs/cwg563.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++23 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++2c %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s + +// expected-no-diagnostics + +namespace cwg563 { // cwg563: 3.3 +extern "C" int a; +} // namespace cwg563 + +// CHECK: LinkageSpecDecl {{.*}} C +// CHECK-NEXT: `-VarDecl {{.*}} a 'int' diff --git a/clang/test/CXX/drs/cwg5xx.cpp b/clang/test/CXX/drs/cwg5xx.cpp index 6a0bb7a196669..ed0c7159dfc88 100644 --- a/clang/test/CXX/drs/cwg5xx.cpp +++ b/clang/test/CXX/drs/cwg5xx.cpp @@ -799,6 +799,7 @@ namespace cwg561 { // cwg561: yes } // cwg562: na +// cwg563 is in cwg563.cpp namespace cwg564 { // cwg564: yes extern "C++" void f(int); diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp index e3cd057baba75..767eee1c74f05 100644 --- a/clang/test/CXX/expr/expr.const/p2-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -571,18 +571,19 @@ namespace UnspecifiedRelations { // [expr.rel]p3: Pointers to void can be compared [...] if both pointers // represent the same address or are both the null pointer [...]; otherwise // the result is unspecified. + // Same address restriction removed by CWG2749 struct S { int a, b; } s; constexpr void *null = 0; constexpr void *pv = (void*)&s.a; constexpr void *qv = (void*)&s.b; constexpr bool v1 = null < (int*)0; constexpr bool v2 = null < pv; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&s.a' has unspecified value}} - constexpr bool v3 = null == pv; // ok - constexpr bool v4 = qv == pv; // ok - constexpr bool v5 = qv >= pv; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} + constexpr bool v3 = null == pv; + constexpr bool v4 = qv == pv; + constexpr bool v5 = qv >= pv; constexpr bool v6 = qv > null; // expected-error {{constant expression}} expected-note {{comparison between '&s.b' and 'nullptr' has unspecified value}} - constexpr bool v7 = qv <= (void*)&s.b; // ok - constexpr bool v8 = qv > (void*)&s.a; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} + constexpr bool v7 = qv <= (void*)&s.b; + constexpr bool v8 = qv > (void*)&s.a; } // - an assignment or a compound assignment (5.17); or diff --git a/clang/test/CodeGen/2005-01-02-ConstantInits.c b/clang/test/CodeGen/2005-01-02-ConstantInits.c index 7772a64331ffb..d90c2ea42da61 100644 --- a/clang/test/CodeGen/2005-01-02-ConstantInits.c +++ b/clang/test/CodeGen/2005-01-02-ConstantInits.c @@ -1,4 +1,4 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-globals --global-value-regex "@.+" +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-globals --global-value-regex "[A-Za-z].*" // RUN: %clang_cc1 -triple=x86_64-unknown-linux %s -emit-llvm -o - | FileCheck %s // This tests all kinds of hard cases with initializers and @@ -51,7 +51,7 @@ int foo(int i) { return bar(&Arr[49])+bar(&Arr[i]); } // CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 // CHECK-NEXT: store ptr @Arr, ptr [[P]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[P]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 // CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[TMP1]] to i64 diff --git a/clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c b/clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c index 6deff1116e1d8..a8fb989b64de5 100644 --- a/clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c +++ b/clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c @@ -99,20 +99,16 @@ float test_float_pre_inc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 8 -// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: ret double [[TMP1]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_post_inc.n to ptr), double 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: ret double [[TMP0]] // // UNSAFE-LABEL: define dso_local double @test_double_post_inc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] -// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: ret double [[TMP1]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_post_inc.n to ptr), double 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: ret double [[TMP0]] // double test_double_post_inc() { @@ -125,20 +121,16 @@ double test_double_post_inc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 8 -// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: ret double [[TMP1]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_post_dc.n to ptr), double 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: ret double [[TMP0]] // // UNSAFE-LABEL: define dso_local double @test_double_post_dc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] -// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: ret double [[TMP1]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_post_dc.n to ptr), double 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: ret double [[TMP0]] // double test_double_post_dc() { @@ -151,22 +143,18 @@ double test_double_post_dc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 8 -// SAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 -// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: ret double [[TMP2]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_pre_dc.n to ptr), double 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: [[TMP1:%.*]] = fsub double [[TMP0]], 1.000000e+00 +// SAFE-NEXT: ret double [[TMP1]] // // UNSAFE-LABEL: define dso_local double @test_double_pre_dc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] -// UNSAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 -// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: ret double [[TMP2]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_pre_dc.n to ptr), double 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fsub double [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: ret double [[TMP1]] // double test_double_pre_dc() { @@ -179,22 +167,18 @@ double test_double_pre_dc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 8 -// SAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 -// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// SAFE-NEXT: ret double [[TMP2]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_pre_inc.n to ptr), double 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: [[TMP1:%.*]] = fadd double [[TMP0]], 1.000000e+00 +// SAFE-NEXT: ret double [[TMP1]] // // UNSAFE-LABEL: define dso_local double @test_double_pre_inc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] -// UNSAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 -// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 -// UNSAFE-NEXT: ret double [[TMP2]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_pre_inc.n to ptr), double 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fadd double [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: ret double [[TMP1]] // double test_double_pre_inc() { @@ -207,20 +191,16 @@ double test_double_pre_inc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 2 -// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: ret half [[TMP1]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_post_inc.n to ptr), half 0xH3C00 seq_cst, align 2 +// SAFE-NEXT: ret half [[TMP0]] // // UNSAFE-LABEL: define dso_local half @test__Float16_post_inc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] -// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: ret half [[TMP1]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_post_inc.n to ptr), half 0xH3C00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: ret half [[TMP0]] // _Float16 test__Float16_post_inc() { @@ -233,20 +213,16 @@ _Float16 test__Float16_post_inc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 2 -// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: ret half [[TMP1]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_post_dc.n to ptr), half 0xH3C00 seq_cst, align 2 +// SAFE-NEXT: ret half [[TMP0]] // // UNSAFE-LABEL: define dso_local half @test__Float16_post_dc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] -// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: ret half [[TMP1]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_post_dc.n to ptr), half 0xH3C00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: ret half [[TMP0]] // _Float16 test__Float16_post_dc() { @@ -259,22 +235,18 @@ _Float16 test__Float16_post_dc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 2 -// SAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 -// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: ret half [[TMP2]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_dc.n to ptr), half 0xH3C00 seq_cst, align 2 +// SAFE-NEXT: [[TMP1:%.*]] = fsub half [[TMP0]], 0xH3C00 +// SAFE-NEXT: ret half [[TMP1]] // // UNSAFE-LABEL: define dso_local half @test__Float16_pre_dc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] -// UNSAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 -// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: ret half [[TMP2]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_dc.n to ptr), half 0xH3C00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fsub half [[TMP0]], 0xH3C00 +// UNSAFE-NEXT: ret half [[TMP1]] // _Float16 test__Float16_pre_dc() { @@ -287,22 +259,18 @@ _Float16 test__Float16_pre_dc() // SAFE-NEXT: [[ENTRY:.*:]] // SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 2 -// SAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 -// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// SAFE-NEXT: ret half [[TMP2]] +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_inc.n to ptr), half 0xH3C00 seq_cst, align 2 +// SAFE-NEXT: [[TMP1:%.*]] = fadd half [[TMP0]], 0xH3C00 +// SAFE-NEXT: ret half [[TMP1]] // // UNSAFE-LABEL: define dso_local half @test__Float16_pre_inc( // UNSAFE-SAME: ) #[[ATTR0]] { // UNSAFE-NEXT: [[ENTRY:.*:]] // UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) // UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr -// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] -// UNSAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 -// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 -// UNSAFE-NEXT: ret half [[TMP2]] +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_inc.n to ptr), half 0xH3C00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fadd half [[TMP0]], 0xH3C00 +// UNSAFE-NEXT: ret half [[TMP1]] // _Float16 test__Float16_pre_inc() { diff --git a/clang/test/CodeGen/PowerPC/ppc-emmintrin.c b/clang/test/CodeGen/PowerPC/ppc-emmintrin.c index a3650beec625f..4c4d0dfce05ea 100644 --- a/clang/test/CodeGen/PowerPC/ppc-emmintrin.c +++ b/clang/test/CodeGen/PowerPC/ppc-emmintrin.c @@ -1012,14 +1012,14 @@ test_shuffle() { // CHECK: %[[SHR:[0-9a-zA-Z_.]+]] = ashr i32 %{{[0-9a-zA-Z_.]+}}, 6 // CHECK: %[[AND4:[0-9a-zA-Z_.]+]] = and i32 %[[SHR]], 3 // CHECK: sext i32 %[[AND4]] to i64 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 0 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 1 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: %[[ADD:[0-9a-zA-Z_.]+]] = add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %[[ADD]], i32 2 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: call <4 x i32> @vec_perm(int vector[4], int vector[4], unsigned char vector[16]) @@ -1050,7 +1050,7 @@ test_shuffle() { // CHECK: sext i32 %[[AND4]] to i64 // CHECK-LE: store <2 x i64> , ptr %{{[0-9a-zA-Z_.]+}}, align 16 // CHECK-BE: store <2 x i64> , ptr %{{[0-9a-zA-Z_.]+}}, align 16 -// CHECK-COUNT-4: getelementptr inbounds [4 x i16], ptr @_mm_shufflehi_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} +// CHECK-COUNT-4: getelementptr inbounds nuw [4 x i16], ptr @_mm_shufflehi_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} // CHECK: call <2 x i64> @vec_perm(unsigned long long vector[2], unsigned long long vector[2], unsigned char vector[16]) // CHECK-LABEL: define available_externally <2 x i64> @_mm_shufflelo_epi16 @@ -1067,7 +1067,7 @@ test_shuffle() { // CHECK: sext i32 %[[AND4]] to i64 // CHECK-LE: store <2 x i64> , ptr %{{[0-9a-zA-Z_.]+}}, align 16 // CHECK-BE: store <2 x i64> , ptr %{{[0-9a-zA-Z_.]+}}, align 16 -// CHECK-COUNT-4: getelementptr inbounds [4 x i16], ptr @_mm_shufflelo_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} +// CHECK-COUNT-4: getelementptr inbounds nuw [4 x i16], ptr @_mm_shufflelo_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} // CHECK: call <2 x i64> @vec_perm(unsigned long long vector[2], unsigned long long vector[2], unsigned char vector[16]) void __attribute__((noinline)) diff --git a/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c b/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c index 95dfd1202f157..4a15fa9f76cee 100644 --- a/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c +++ b/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c @@ -894,16 +894,16 @@ test_shuffle() { // CHECK: %[[SHR3:[0-9a-zA-Z_.]+]] = ashr i32 %{{[0-9a-zA-Z_.]+}}, 6 // CHECK: %[[AND4:[0-9a-zA-Z_.]+]] = and i32 %[[SHR3]], 3 // CHECK: sext i32 %[[AND4]] to i64 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 0 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 3 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 1 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 2 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 2 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 1 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 3 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 0 // CHECK: call <2 x i64> @vec_splats(unsigned long long) @@ -923,14 +923,14 @@ test_shuffle() { // CHECK: %[[SHR3:[0-9a-zA-Z_.]+]] = ashr i32 %{{[0-9a-zA-Z_.]+}}, 6 // CHECK: %[[AND4:[0-9a-zA-Z_.]+]] = and i32 %[[SHR3]], 3 // CHECK: sext i32 %[[AND4]] to i64 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 0 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 1 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: %[[ADD:[0-9a-zA-Z_.]+]] = add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %[[ADD]], i32 2 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: %[[ADD2:[0-9a-zA-Z_.]+]] = add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %[[ADD2]], i32 3 // CHECK: call <4 x float> @vec_perm(float vector[4], float vector[4], unsigned char vector[16]) diff --git a/clang/test/CodeGen/X86/avx10_2_512bf16-builtins.c b/clang/test/CodeGen/X86/avx10_2_512bf16-builtins.c new file mode 100644 index 0000000000000..b00859c174fba --- /dev/null +++ b/clang/test/CodeGen/X86/avx10_2_512bf16-builtins.c @@ -0,0 +1,1085 @@ +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64 -target-feature +avx10.2-512 -emit-llvm -o - -Wno-invalid-feature-combination -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=i386 -target-feature +avx10.2-512 -emit-llvm -o - -Wno-invalid-feature-combination -Wall -Werror | FileCheck %s + +#include + +__m512bh test_mm512_setzero_pbh() { + // CHECK-LABEL: @test_mm512_setzero_pbh + // CHECK: zeroinitializer + return _mm512_setzero_pbh(); +} + +__m512bh test_mm512_undefined_pbh(void) { + // CHECK-LABEL: @test_mm512_undefined_pbh + // CHECK: ret <32 x bfloat> zeroinitializer + return _mm512_undefined_pbh(); +} + +__m512bh test_mm512_set1_pbh(__bf16 h) { + // CHECK-LABEL: @test_mm512_set1_pbh + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 7 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 8 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 9 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 10 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 11 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 12 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 13 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 14 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 15 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 16 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 17 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 18 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 19 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 20 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 21 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 22 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 23 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 24 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 25 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 26 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 27 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 28 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 29 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 30 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 31 + return _mm512_set1_pbh(h); +} + +__m512bh test_mm512_set_pbh(__bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, + __bf16 bf5, __bf16 bf6, __bf16 bf7, __bf16 bf8, + __bf16 bf9, __bf16 bf10, __bf16 bf11, __bf16 bf12, + __bf16 bf13, __bf16 bf14, __bf16 bf15, __bf16 bf16, + __bf16 bf17, __bf16 bf18, __bf16 bf19, __bf16 bf20, + __bf16 bf21, __bf16 bf22, __bf16 bf23, __bf16 bf24, + __bf16 bf25, __bf16 bf26, __bf16 bf27, __bf16 bf28, + __bf16 bf29, __bf16 bf30, __bf16 bf31, __bf16 bf32) { + // CHECK-LABEL: @test_mm512_set_pbh + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 7 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 8 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 9 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 10 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 11 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 12 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 13 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 14 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 15 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 16 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 17 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 18 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 19 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 20 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 21 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 22 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 23 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 24 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 25 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 26 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 27 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 28 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 29 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 30 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 31 + return _mm512_set_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, + bf9, bf10, bf11, bf12, bf13, bf14, bf15, bf16, + bf17, bf18, bf19, bf20, bf21, bf22, bf23, bf24, + bf25, bf26, bf27, bf28, bf29, bf30, bf31, bf32); +} + +__m512bh test_mm512_setr_pbh(__bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, + __bf16 bf5, __bf16 bf6, __bf16 bf7, __bf16 bf8, + __bf16 bf9, __bf16 bf10, __bf16 bf11, __bf16 bf12, + __bf16 bf13, __bf16 bf14, __bf16 bf15, __bf16 bf16, + __bf16 bf17, __bf16 bf18, __bf16 bf19, __bf16 bf20, + __bf16 bf21, __bf16 bf22, __bf16 bf23, __bf16 bf24, + __bf16 bf25, __bf16 bf26, __bf16 bf27, __bf16 bf28, + __bf16 bf29, __bf16 bf30, __bf16 bf31, __bf16 bf32) { + // CHECK-LABEL: @test_mm512_setr_pbh + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 7 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 8 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 9 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 10 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 11 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 12 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 13 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 14 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 15 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 16 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 17 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 18 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 19 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 20 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 21 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 22 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 23 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 24 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 25 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 26 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 27 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 28 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 29 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 30 + // CHECK: insertelement <32 x bfloat> {{.*}}, i32 31 + return _mm512_setr_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, + bf9, bf10, bf11, bf12, bf13, bf14, bf15, bf16, + bf17, bf18, bf19, bf20, bf21, bf22, bf23, bf24, + bf25, bf26, bf27, bf28, bf29, bf30, bf31, bf32); +} + +__m512 test_mm512_castpbf16_ps(__m512bh A) { + // CHECK-LABEL: test_mm512_castpbf16_ps + // CHECK: bitcast <32 x bfloat> %{{.*}} to <16 x float> + return _mm512_castpbf16_ps(A); +} + +__m512d test_mm512_castpbf16_pd(__m512bh A) { + // CHECK-LABEL: test_mm512_castpbf16_pd + // CHECK: bitcast <32 x bfloat> %{{.*}} to <8 x double> + return _mm512_castpbf16_pd(A); +} + +__m512i test_mm512_castpbf16_si512(__m512bh A) { + // CHECK-LABEL: test_mm512_castpbf16_si512 + // CHECK: bitcast <32 x bfloat> %{{.*}} to <8 x i64> + return _mm512_castpbf16_si512(A); +} + +__m512bh test_mm512_castps_pbh(__m512 A) { + // CHECK-LABEL: test_mm512_castps_pbh + // CHECK: bitcast <16 x float> %{{.*}} to <32 x bfloat> + return _mm512_castps_pbh(A); +} + +__m512bh test_mm512_castpd_pbh(__m512d A) { + // CHECK-LABEL: test_mm512_castpd_pbh + // CHECK: bitcast <8 x double> %{{.*}} to <32 x bfloat> + return _mm512_castpd_pbh(A); +} + +__m512bh test_mm512_castsi512_pbh(__m512i A) { + // CHECK-LABEL: test_mm512_castsi512_pbh + // CHECK: bitcast <8 x i64> %{{.*}} to <32 x bfloat> + return _mm512_castsi512_pbh(A); +} + +__m128bh test_mm512_castpbf16512_pbh128(__m512bh __a) { + // CHECK-LABEL: test_mm512_castpbf16512_pbh128 + // CHECK: shufflevector <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <8 x i32> + return _mm512_castpbf16512_pbh128(__a); +} + +__m256bh test_mm512_castpbf16512_pbh256(__m512bh __a) { + // CHECK-LABEL: test_mm512_castpbf16512_pbh256 + // CHECK: shufflevector <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <16 x i32> + return _mm512_castpbf16512_pbh256(__a); +} + +__m512bh test_mm512_castpbf16128_pbh512(__m128bh __a) { + // CHECK-LABEL: test_mm512_castpbf16128_pbh512 + // CHECK: shufflevector <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <32 x i32> + return _mm512_castpbf16128_pbh512(__a); +} + +__m512bh test_mm512_castpbf16256_pbh512(__m256bh __a) { + // CHECK-LABEL: test_mm512_castpbf16256_pbh512 + // CHECK: shufflevector <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <32 x i32> + return _mm512_castpbf16256_pbh512(__a); +} + +__m512bh test_mm512_zextpbf16128_pbh512(__m128bh __a) { + // CHECK-LABEL: test_mm512_zextpbf16128_pbh512 + // CHECK: shufflevector <8 x bfloat> %{{.*}}, <8 x bfloat> {{.*}}, <32 x i32> + return _mm512_zextpbf16128_pbh512(__a); +} + +__m512bh test_mm512_zextpbf16256_pbh512(__m256bh __a) { + // CHECK-LABEL: test_mm512_zextpbf16256_pbh512 + // CHECK: shufflevector <16 x bfloat> %{{.*}}, <16 x bfloat> {{.*}}, <32 x i32> + return _mm512_zextpbf16256_pbh512(__a); +} + +__m512bh test_mm512_abs_pbh(__m512bh a) { + // CHECK-LABEL: @test_mm512_abs_pbh + // CHECK: and <16 x i32> + return _mm512_abs_pbh(a); +} + +// VMOVSH + +__m512bh test_mm512_load_pbh(void *p) { + // CHECK-LABEL: @test_mm512_load_pbh + // CHECK: load <32 x bfloat>, ptr %{{.*}}, align 64 + return _mm512_load_pbh(p); +} + +__m512bh test_mm512_loadu_pbh(void *p) { + // CHECK-LABEL: @test_mm512_loadu_pbh + // CHECK: load <32 x bfloat>, ptr {{.*}}, align 1{{$}} + return _mm512_loadu_pbh(p); +} + +void test_mm512_store_pbh(void *p, __m512bh a) { + // CHECK-LABEL: @test_mm512_store_pbh + // CHECK: store <32 x bfloat> %{{.*}}, ptr %{{.*}}, align 64 + _mm512_store_pbh(p, a); +} + +void test_mm512_storeu_pbh(void *p, __m512bh a) { + // CHECK-LABEL: @test_mm512_storeu_pbh + // CHECK: store <32 x bfloat> %{{.*}}, ptr %{{.*}}, align 1{{$}} + // CHECK-NEXT: ret void + _mm512_storeu_pbh(p, a); +} + +__m512bh test_mm512_mask_blend_pbh(__mmask32 __U, __m512bh __A, __m512bh __W) { + // CHECK-LABEL: @test_mm512_mask_blend_pbh + // CHECK: %{{.*}} = bitcast i32 %{{.*}} to <32 x i1> + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_blend_pbh(__U, __A, __W); +} + +__m512bh test_mm512_permutex2var_pbh(__m512bh __A, __m512i __I, __m512bh __B) { + // CHECK-LABEL: @test_mm512_permutex2var_pbh + // CHECK: %{{.*}} = bitcast <32 x bfloat> %{{.*}} to <32 x i16> + // CHECK: %{{.*}} = bitcast <8 x i64> %{{.*}} to <32 x i16> + // CHECK: %{{.*}} = bitcast <32 x bfloat> %{{.*}} to <32 x i16> + // CHECK: %{{.*}} = call <32 x i16> @llvm.x86.avx512.vpermi2var.hi.512(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}) + // CHECK: %{{.*}} = bitcast <32 x i16> %{{.*}} to <32 x bfloat> + return _mm512_permutex2var_pbh(__A, __I, __B); +} + +__m512bh test_mm512_permutexvar_epi16(__m512i __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_permutexvar_epi16 + // CHECK: %{{.*}} = bitcast <32 x bfloat> %{{.*}} to <32 x i16> + // CHECK: %{{.*}} = bitcast <8 x i64> %{{.*}} to <32 x i16> + // CHECK: %{{.*}} = call <32 x i16> @llvm.x86.avx512.permvar.hi.512(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}) + // CHECK: %{{.*}} = bitcast <32 x i16> %{{.*}} to <32 x bfloat> + return _mm512_permutexvar_pbh(__A, __B); +} + +__m512bh test_mm512_addne_pbh(__m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_addne_pbh + // CHECK: %{{.*}} = fadd <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_addne_pbh(__A, __B); +} + +__m512bh test_mm512_mask_addne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fadd <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_addne_pbh(__W, __U, __A, __B); +} + +__m512bh test_mm512_maskz_addne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fadd <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_addne_pbh(__U, __A, __B); +} + +__m512bh test_mm512_subne_pbh(__m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_subne_pbh + // CHECK: %{{.*}} = fsub <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_subne_pbh(__A, __B); +} + +__m512bh test_mm512_mask_subne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fsub <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_subne_pbh(__W, __U, __A, __B); +} + +__m512bh test_mm512_maskz_subne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fsub <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_subne_pbh(__U, __A, __B); +} + +__m512bh test_mm512_mulne_pbh(__m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_mulne_pbh + // CHECK: %{{.*}} = fmul <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_mulne_pbh(__A, __B); +} + +__m512bh test_mm512_mask_mulne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fmul <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_mulne_pbh(__W, __U, __A, __B); +} + +__m512bh test_mm512_maskz_mulne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fmul <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_mulne_pbh(__U, __A, __B); +} + +__m512bh test_mm512_divne_pbh(__m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_divne_pbh + // CHECK: %{{.*}} = fdiv <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_divne_pbh(__A, __B); +} + +__m512bh test_mm512_mask_divne_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fdiv <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_divne_pbh(__W, __U, __A, __B); +} + +__m512bh test_mm512_maskz_divne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: %{{.*}} = fdiv <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_divne_pbh(__U, __A, __B); +} + +__m512bh test_mm512_max_pbh(__m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_max_pbh + // CHECK: @llvm.x86.avx10.vmaxpbf16512( + return _mm512_max_pbh(__A, __B); +} + +__m512bh test_mm512_mask_max_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: @llvm.x86.avx10.vmaxpbf16512 + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_max_pbh(__W, __U, __A, __B); +} + +__m512bh test_mm512_maskz_max_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: @llvm.x86.avx10.vmaxpbf16512 + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_max_pbh(__U, __A, __B); +} + +__m512bh test_mm512_min_pbh(__m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_min_pbh + // CHECK: @llvm.x86.avx10.vminpbf16512( + return _mm512_min_pbh(__A, __B); +} + +__m512bh test_mm512_mask_min_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: @llvm.x86.avx10.vminpbf16512 + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_min_pbh(__W, __U, __A, __B); +} + +__m512bh test_mm512_maskz_min_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK: @llvm.x86.avx10.vminpbf16512 + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_min_pbh(__U, __A, __B); +} + +__mmask32 test_mm512_cmp_pbh_mask_eq_oq(__m512bh a, __m512bh b) { + // CHECK-LABEL: @test_mm512_cmp_pbh_mask_eq_oq + // CHECK: fcmp oeq <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_EQ_OQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_lt_os(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_lt_os + // CHECK: fcmp olt <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_LT_OS); +} + +__mmask32 test_mm512_cmp_pbh_mask_le_os(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_le_os + // CHECK: fcmp ole <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_LE_OS); +} + +__mmask32 test_mm512_cmp_pbh_mask_unord_q(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_unord_q + // CHECK: fcmp uno <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_UNORD_Q); +} + +__mmask32 test_mm512_cmp_pbh_mask_neq_uq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_neq_uq + // CHECK: fcmp une <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NEQ_UQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_nlt_us(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_nlt_us + // CHECK: fcmp uge <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NLT_US); +} + +__mmask32 test_mm512_cmp_pbh_mask_nle_us(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_nle_us + // CHECK: fcmp ugt <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NLE_US); +} + +__mmask32 test_mm512_cmp_pbh_mask_ord_q(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_ord_q + // CHECK: fcmp ord <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_ORD_Q); +} + +__mmask32 test_mm512_cmp_pbh_mask_eq_uq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_eq_uq + // CHECK: fcmp ueq <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_EQ_UQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_nge_us(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_nge_us + // CHECK: fcmp ult <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NGE_US); +} + +__mmask32 test_mm512_cmp_pbh_mask_ngt_us(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_ngt_us + // CHECK: fcmp ule <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NGT_US); +} + +__mmask32 test_mm512_cmp_pbh_mask_false_oq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_false_oq + // CHECK: fcmp false <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_FALSE_OQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_neq_oq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_neq_oq + // CHECK: fcmp one <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NEQ_OQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_ge_os(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_ge_os + // CHECK: fcmp oge <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_GE_OS); +} + +__mmask32 test_mm512_cmp_pbh_mask_gt_os(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_gt_os + // CHECK: fcmp ogt <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_GT_OS); +} + +__mmask32 test_mm512_cmp_pbh_mask_true_uq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_true_uq + // CHECK: fcmp true <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_TRUE_UQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_eq_os(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_eq_os + // CHECK: fcmp oeq <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_EQ_OS); +} + +__mmask32 test_mm512_cmp_pbh_mask_lt_oq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_lt_oq + // CHECK: fcmp olt <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_LT_OQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_le_oq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_le_oq + // CHECK: fcmp ole <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_LE_OQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_unord_s(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_unord_s + // CHECK: fcmp uno <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_UNORD_S); +} + +__mmask32 test_mm512_cmp_pbh_mask_neq_us(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_neq_us + // CHECK: fcmp une <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NEQ_US); +} + +__mmask32 test_mm512_cmp_pbh_mask_nlt_uq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_nlt_uq + // CHECK: fcmp uge <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NLT_UQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_nle_uq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_nle_uq + // CHECK: fcmp ugt <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NLE_UQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_ord_s(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_ord_s + // CHECK: fcmp ord <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_ORD_S); +} + +__mmask32 test_mm512_cmp_pbh_mask_eq_us(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_eq_us + // CHECK: fcmp ueq <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_EQ_US); +} + +__mmask32 test_mm512_cmp_pbh_mask_nge_uq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_nge_uq + // CHECK: fcmp ult <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NGE_UQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_ngt_uq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_ngt_uq + // CHECK: fcmp ule <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NGT_UQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_false_os(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_false_os + // CHECK: fcmp false <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_FALSE_OS); +} + +__mmask32 test_mm512_cmp_pbh_mask_neq_os(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_neq_os + // CHECK: fcmp one <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_NEQ_OS); +} + +__mmask32 test_mm512_cmp_pbh_mask_ge_oq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_ge_oq + // CHECK: fcmp oge <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_GE_OQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_gt_oq(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_gt_oq + // CHECK: fcmp ogt <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_GT_OQ); +} + +__mmask32 test_mm512_cmp_pbh_mask_true_us(__m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_cmp_pbh_mask_true_us + // CHECK: fcmp true <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_cmp_pbh_mask(a, b, _CMP_TRUE_US); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_eq_oq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: @test_mm512_mask_cmp_pbh_mask_eq_oq + // CHECK: fcmp oeq <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_OQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_lt_os(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_lt_os + // CHECK: fcmp olt <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_LT_OS); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_le_os(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_le_os + // CHECK: fcmp ole <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_LE_OS); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_unord_q(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_unord_q + // CHECK: fcmp uno <32 x bfloat> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_UNORD_Q); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_neq_uq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_neq_uq + // CHECK: fcmp une <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_UQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_nlt_us(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_nlt_us + // CHECK: fcmp uge <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NLT_US); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_nle_us(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_nle_us + // CHECK: fcmp ugt <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NLE_US); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_ord_q(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_ord_q + // CHECK: fcmp ord <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_ORD_Q); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_eq_uq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_eq_uq + // CHECK: fcmp ueq <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_UQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_nge_us(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_nge_us + // CHECK: fcmp ult <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NGE_US); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_ngt_us(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_ngt_us + // CHECK: fcmp ule <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NGT_US); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_false_oq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_false_oq + // CHECK: fcmp false <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_FALSE_OQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_neq_oq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_neq_oq + // CHECK: fcmp one <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_OQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_ge_os(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_ge_os + // CHECK: fcmp oge <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_GE_OS); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_gt_os(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_gt_os + // CHECK: fcmp ogt <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_GT_OS); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_true_uq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_true_uq + // CHECK: fcmp true <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_TRUE_UQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_eq_os(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_eq_os + // CHECK: fcmp oeq <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_OS); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_lt_oq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_lt_oq + // CHECK: fcmp olt <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_LT_OQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_le_oq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_le_oq + // CHECK: fcmp ole <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_LE_OQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_unord_s(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_unord_s + // CHECK: fcmp uno <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_UNORD_S); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_neq_us(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_neq_us + // CHECK: fcmp une <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_US); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_nlt_uq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_nlt_uq + // CHECK: fcmp uge <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NLT_UQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_nle_uq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_nle_uq + // CHECK: fcmp ugt <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NLE_UQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_ord_s(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_ord_s + // CHECK: fcmp ord <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_ORD_S); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_eq_us(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_eq_us + // CHECK: fcmp ueq <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_US); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_nge_uq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_nge_uq + // CHECK: fcmp ult <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NGE_UQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_ngt_uq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_ngt_uq + // CHECK: fcmp ule <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NGT_UQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_false_os(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_false_os + // CHECK: fcmp false <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_FALSE_OS); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_neq_os(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_neq_os + // CHECK: fcmp one <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_OS); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_ge_oq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_ge_oq + // CHECK: fcmp oge <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_GE_OQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_gt_oq(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_gt_oq + // CHECK: fcmp ogt <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_GT_OQ); +} + +__mmask32 test_mm512_mask_cmp_pbh_mask_true_us(__mmask32 m, __m512bh a, __m512bh b) { + // CHECK-LABEL: test_mm512_mask_cmp_pbh_mask_true_us + // CHECK: fcmp true <32 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <32 x i1> %{{.*}}, %{{.*}} + return _mm512_mask_cmp_pbh_mask(m, a, b, _CMP_TRUE_US); +} + +__mmask32 test_mm512_mask_fpclass_pbh_mask(__mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_fpclass_pbh_mask + // CHECK: @llvm.x86.avx10.fpclass.nepbf16.512 + return _mm512_mask_fpclass_pbh_mask(__U, __A, 4); +} + +__mmask32 test_mm512_fpclass_pbh_mask(__m512bh __A) { + // CHECK-LABEL: @test_mm512_fpclass_pbh_mask + // CHECK: @llvm.x86.avx10.fpclass.nepbf16.512 + return _mm512_fpclass_pbh_mask(__A, 4); +} + +__m512bh test_mm512_scalef_pbh(__m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.512 + return _mm512_scalef_pbh(__A, __B); +} + +__m512bh test_mm512_mask_scalef_pbh(__m512bh __W, __mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_mask_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.512 + return _mm512_mask_scalef_pbh(__W, __U, __A, __B); +} + +__m512bh test_mm512_maskz_scalef_pbh(__mmask32 __U, __m512bh __A, __m512bh __B) { + // CHECK-LABEL: @test_mm512_maskz_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.512 + return _mm512_maskz_scalef_pbh(__U, __A, __B); +} + +__m512bh test_mm512_rcp_pbh(__m512bh __A) { + // CHECK-LABEL: @test_mm512_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.512 + return _mm512_rcp_pbh(__A); +} + +__m512bh test_mm512_mask_rcp_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.512 + return (__m512bh)_mm512_mask_rcp_pbh(__W, __U, __A); +} + +__m512bh test_mm512_maskz_rcp_pbh(__mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_maskz_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.512 + return _mm512_maskz_rcp_pbh(__U, __A); +} + +__m512bh test_mm512_getexp_pbh(__m512bh __A) { + // CHECK-LABEL: @test_mm512_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.512 + return _mm512_getexp_pbh(__A); +} + +__m512bh test_mm512_mask_getexp_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.512 + return _mm512_mask_getexp_pbh(__W, __U, __A); +} + +__m512bh test_mm512_maskz_getexp_pbh(__mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_maskz_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.512 + return _mm512_maskz_getexp_pbh(__U, __A); +} + +__m512bh test_mm512_rsqrt_pbh(__m512bh __A) { + // CHECK-LABEL: @test_mm512_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.512 + return _mm512_rsqrt_pbh(__A); +} + +__m512bh test_mm512_mask_rsqrt_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.512 + return (__m512bh)_mm512_mask_rsqrt_pbh(__W, __U, __A); +} + +__m512bh test_mm512_maskz_rsqrt_pbh(__mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_maskz_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.512 + return _mm512_maskz_rsqrt_pbh(__U, __A); +} + +__m512bh test_mm512_reducene_pbh(__m512bh __A) { + // CHECK-LABEL: @test_mm512_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.512 + return _mm512_reducene_pbh(__A, 3); +} + +__m512bh test_mm512_mask_reducene_pbh(__m512bh __W, __mmask16 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.512 + return _mm512_mask_reducene_pbh(__W, __U, __A, 1); +} + +__m512bh test_mm512_maskz_reducene_pbh(__mmask16 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_maskz_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.512 + return _mm512_maskz_reducene_pbh(__U, __A, 1); +} + +__m512bh test_mm512_roundscalene_pbh(__m512bh __A) { + // CHECK-LABEL: @test_mm512_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.512 + return _mm512_roundscalene_pbh(__A, 3); +} + +__m512bh test_mm512_mask_roundscalene_pbh(__m512bh __W, __mmask16 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.512 + return _mm512_mask_roundscalene_pbh(__W, __U, __A, 1); +} + +__m512bh test_mm512_maskz_roundscalene_pbh(__mmask16 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_maskz_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.512 + return _mm512_maskz_roundscalene_pbh(__U, __A, 1 ); +} + +__m512bh test_mm512_getmant_pbh(__m512bh __A) { + // CHECK-LABEL: @test_mm512_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.512 + return _mm512_getmant_pbh(__A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m512bh test_mm512_mask_getmant_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.512 + return _mm512_mask_getmant_pbh(__W, __U, __A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m512bh test_mm512_maskz_getmant_pbh(__mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_maskz_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.512 + return _mm512_maskz_getmant_pbh(__U, __A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m512bh test_mm512_sqrt_pbh(__m512bh __A) { + // CHECK-LABEL: @test_mm512_sqrt_pbh + // CHECK: %{{.*}} = call <32 x bfloat> @llvm.sqrt.v32bf16(<32 x bfloat> %{{.*}}) + return _mm512_sqrt_pbh(__A); +} + +__m512bh test_mm512_mask_sqrt_pbh(__m512bh __W, __mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_mask_sqrt_pbh + // CHECK: %{{.*}} = call <32 x bfloat> @llvm.sqrt.v32bf16(<32 x bfloat> %{{.*}}) + // CHECK: bitcast i32 %{{.*}} to <32 x i1> + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return (__m512bh)_mm512_mask_sqrt_pbh(__W, __U, __A); +} + +__m512bh test_mm512_maskz_sqrt_pbh(__mmask32 __U, __m512bh __A) { + // CHECK-LABEL: @test_mm512_maskz_sqrt_pbh + // CHECK: %{{.*}} = call <32 x bfloat> @llvm.sqrt.v32bf16(<32 x bfloat> %{{.*}}) + // CHECK: bitcast i32 %{{.*}} to <32 x i1> + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_sqrt_pbh(__U, __A); +} + +__m512bh test_mm512_fmaddne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_fmaddne_pbh + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + return _mm512_fmaddne_pbh(__A, __B, __C); +} + +__m512bh test_mm512_mask_fmaddne_pbh(__m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_mask_fmaddne_pbh + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_fmaddne_pbh(__A, __U, __B, __C); +} + +__m512bh test_mm512_mask3_fmaddne_pbh(__m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + // CHECK-LABEL: @test_mm512_mask3_fmaddne_pbh + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask3_fmaddne_pbh(__A, __B, __C, __U); +} + +__m512bh test_mm512_maskz_fmaddne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_maskz_fmaddne_pbh + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_fmaddne_pbh(__U, __A, __B, __C); +} + +__m512bh test_mm512_fmsubne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_fmsubne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + return _mm512_fmsubne_pbh(__A, __B, __C); +} + +__m512bh test_mm512_mask_fmsubne_pbh(__m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_mask_fmsubne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_fmsubne_pbh(__A, __U, __B, __C); +} + +__m512bh test_mm512_mask3_fmsubne_pbh(__m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + // CHECK-LABEL: @test_mm512_mask3_fmsubne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask3_fmsubne_pbh(__A, __B, __C, __U); +} + +__m512bh test_mm512_maskz_fmsubne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_maskz_fmsubne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_fmsubne_pbh(__U, __A, __B, __C); +} + +__m512bh test_mm512_fnmaddne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + return _mm512_fnmaddne_pbh(__A, __B, __C); +} + +__m512bh test_mm512_mask_fnmaddne_pbh(__m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_mask_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_fnmaddne_pbh(__A, __U, __B, __C); +} + +__m512bh test_mm512_mask3_fnmaddne_pbh(__m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + // CHECK-LABEL: @test_mm512_mask3_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask3_fnmaddne_pbh(__A, __B, __C, __U); +} + +__m512bh test_mm512_maskz_fnmaddne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_maskz_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_fnmaddne_pbh(__U, __A, __B, __C); +} + +__m512bh test_mm512_fnmsubne_pbh(__m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + return _mm512_fnmsubne_pbh(__A, __B, __C); +} + +__m512bh test_mm512_mask_fnmsubne_pbh(__m512bh __A, __mmask32 __U, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_mask_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask_fnmsubne_pbh(__A, __U, __B, __C); +} + +__m512bh test_mm512_mask3_fnmsubne_pbh(__m512bh __A, __m512bh __B, __m512bh __C, __mmask32 __U) { + // CHECK-LABEL: @test_mm512_mask3_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_mask3_fnmsubne_pbh(__A, __B, __C, __U); +} + +__m512bh test_mm512_maskz_fnmsubne_pbh(__mmask32 __U, __m512bh __A, __m512bh __B, __m512bh __C) { + // CHECK-LABEL: @test_mm512_maskz_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <32 x bfloat> @llvm.fma.v32bf16(<32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}}) + // CHECK: select <32 x i1> %{{.*}}, <32 x bfloat> %{{.*}}, <32 x bfloat> %{{.*}} + return _mm512_maskz_fnmsubne_pbh(__U, __A, __B, __C); +} diff --git a/clang/test/CodeGen/X86/avx10_2bf16-builtins.c b/clang/test/CodeGen/X86/avx10_2bf16-builtins.c new file mode 100644 index 0000000000000..cd94edcf58ea2 --- /dev/null +++ b/clang/test/CodeGen/X86/avx10_2bf16-builtins.c @@ -0,0 +1,2082 @@ +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64 -target-feature +avx10.2-256 -emit-llvm -o - -Wno-invalid-feature-combination -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=i386 -target-feature +avx10.2-256 -emit-llvm -o - -Wno-invalid-feature-combination -Wall -Werror | FileCheck %s + +#include + +__m256bh test_mm256_setzero_pbh() { + // CHECK-LABEL: @test_mm256_setzero_pbh + // CHECK: zeroinitializer + return _mm256_setzero_pbh(); +} + +__m128bh test_mm_setzero_pbh() { + // CHECK-LABEL: @test_mm_setzero_pbh + // CHECK: zeroinitializer + return _mm_setzero_pbh(); +} + +__m256bh test_mm256_undefined_pbh(void) { + // CHECK-LABEL: @test_mm256_undefined_pbh + // CHECK: ret <16 x bfloat> zeroinitializer + return _mm256_undefined_pbh(); +} + +__m128bh test_mm_undefined_pbh(void) { + // CHECK-LABEL: @test_mm_undefined_pbh + // CHECK: ret <8 x bfloat> zeroinitializer + return _mm_undefined_pbh(); +} + +__bf16 test_mm_cvtsbh_bf16(__m128bh __A) { + // CHECK-LABEL: @test_mm_cvtsbh_bf16 + // CHECK: extractelement <8 x bfloat> %{{.*}}, i32 0 + return _mm_cvtsbh_bf16(__A); +} + +__bf16 test_mm256_cvtsbh_bf16(__m256bh __A) { + // CHECK-LABEL: @test_mm256_cvtsbh_bf16 + // CHECK: extractelement <16 x bfloat> %{{.*}}, i32 0 + return _mm256_cvtsbh_bf16(__A); +} + +__m128bh test_mm_set_sbh(__bf16 h) { + // CHECK-LABEL: @test_mm_set_sbh + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 1 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 2 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 3 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 4 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 5 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 6 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 7 + return _mm_set_sbh(h); +} + +__m128bh test_mm_set1_pbh(__bf16 h) { + // CHECK-LABEL: @test_mm_set1_pbh + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 7 + return _mm_set1_pbh(h); +} + +__m256bh test_mm256_set1_pbh(__bf16 h) { + // CHECK-LABEL: @test_mm256_set1_pbh + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 7 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 8 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 9 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 10 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 11 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 12 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 13 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 14 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 15 + return _mm256_set1_pbh(h); +} + +__m128bh test_mm_set_pbh(__bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, + __bf16 bf5, __bf16 bf6, __bf16 bf7, __bf16 bf8) { + // CHECK-LABEL: @test_mm_set_pbh + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 7 + return _mm_set_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8); +} + +__m256bh test_mm256_set_pbh(__bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, + __bf16 bf5, __bf16 bf6, __bf16 bf7, __bf16 bf8, + __bf16 bf9, __bf16 bf10, __bf16 bf11, __bf16 bf12, + __bf16 bf13, __bf16 bf14, __bf16 bf15, __bf16 bf16) { + // CHECK-LABEL: @test_mm256_set_pbh + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 7 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 8 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 9 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 10 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 11 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 12 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 13 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 14 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 15 + return _mm256_set_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, + bf9, bf10, bf11, bf12, bf13, bf14, bf15, bf16); +} + +__m128bh test_mm_setr_pbh(__bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, + __bf16 bf5, __bf16 bf6, __bf16 bf7, __bf16 bf8) { + // CHECK-LABEL: @test_mm_setr_pbh + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <8 x bfloat> {{.*}}, i32 7 + return _mm_setr_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8); +} + +__m256bh test_mm256_setr_pbh(__bf16 bf1, __bf16 bf2, __bf16 bf3, __bf16 bf4, + __bf16 bf5, __bf16 bf6, __bf16 bf7, __bf16 bf8, + __bf16 bf9, __bf16 bf10, __bf16 bf11, __bf16 bf12, + __bf16 bf13, __bf16 bf14, __bf16 bf15, __bf16 bf16) { + // CHECK-LABEL: @test_mm256_setr_pbh + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 0 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 1 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 2 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 3 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 4 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 5 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 6 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 7 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 8 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 9 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 10 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 11 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 12 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 13 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 14 + // CHECK: insertelement <16 x bfloat> {{.*}}, i32 15 + return _mm256_setr_pbh(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, + bf9, bf10, bf11, bf12, bf13, bf14, bf15, bf16); +} + +__m128 test_mm_castpbf16_ps(__m128bh A) { + // CHECK-LABEL: test_mm_castpbf16_ps + // CHECK: bitcast <8 x bfloat> %{{.*}} to <4 x float> + return _mm_castpbf16_ps(A); +} + +__m256 test_mm256_castpbf16_ps(__m256bh A) { + // CHECK-LABEL: test_mm256_castpbf16_ps + // CHECK: bitcast <16 x bfloat> %{{.*}} to <8 x float> + return _mm256_castpbf16_ps(A); +} + +__m128i test_mm_castpbf16_si128(__m128bh A) { + // CHECK-LABEL: test_mm_castpbf16_si128 + // CHECK: bitcast <8 x bfloat> %{{.*}} to <2 x i64> + return _mm_castpbf16_si128(A); +} + +__m256i test_mm256_castpbf16_si256(__m256bh A) { + // CHECK-LABEL: test_mm256_castpbf16_si256 + // CHECK: bitcast <16 x bfloat> %{{.*}} to <4 x i64> + return _mm256_castpbf16_si256(A); +} + +__m128bh test_mm_castps_pbh(__m128 A) { + // CHECK-LABEL: test_mm_castps_pbh + // CHECK: bitcast <4 x float> %{{.*}} to <8 x bfloat> + return _mm_castps_pbh(A); +} + +__m256bh test_mm256_castps_pbh(__m256 A) { + // CHECK-LABEL: test_mm256_castps_pbh + // CHECK: bitcast <8 x float> %{{.*}} to <16 x bfloat> + return _mm256_castps_pbh(A); +} + +__m128bh test_mm_castpd_pbh(__m128d A) { + // CHECK-LABEL: test_mm_castpd_pbh + // CHECK: bitcast <2 x double> %{{.*}} to <8 x bfloat> + return _mm_castpd_pbh(A); +} + +__m256bh test_mm256_castpd_pbh(__m256d A) { + // CHECK-LABEL: test_mm256_castpd_pbh + // CHECK: bitcast <4 x double> %{{.*}} to <16 x bfloat> + return _mm256_castpd_pbh(A); +} + +__m128bh test_mm_castsi128_pbh(__m128i A) { + // CHECK-LABEL: test_mm_castsi128_pbh + // CHECK: bitcast <2 x i64> %{{.*}} to <8 x bfloat> + return _mm_castsi128_pbh(A); +} + +__m256bh test_mm256_castsi256_pbh(__m256i A) { + // CHECK-LABEL: test_mm256_castsi256_pbh + // CHECK: bitcast <4 x i64> %{{.*}} to <16 x bfloat> + return _mm256_castsi256_pbh(A); +} + +__m128d test_mm_castpbf16_pd(__m128bh A) { + // CHECK-LABEL: test_mm_castpbf16_pd + // CHECK: bitcast <8 x bfloat> %{{.*}} to <2 x double> + return _mm_castpbf16_pd(A); +} + +__m128bh test_mm256_castpbf16256_pbh128(__m256bh __a) { + // CHECK-LABEL: test_mm256_castpbf16256_pbh128 + // CHECK: shufflevector <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <8 x i32> + return _mm256_castpbf16256_pbh128(__a); +} + +__m256bh test_mm256_castpbf16128_pbh256(__m128bh __a) { + // CHECK-LABEL: test_mm256_castpbf16128_pbh256 + // CHECK: shufflevector <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <16 x i32> + return _mm256_castpbf16128_pbh256(__a); +} + +__m256d test_mm256_castpbf16_pd(__m256bh A) { + // CHECK-LABEL: test_mm256_castpbf16_pd + // CHECK: bitcast <16 x bfloat> %{{.*}} to <4 x double> + return _mm256_castpbf16_pd(A); +} + +__m256bh test_mm256_zextpbf16128_pbh256(__m128bh __a) { + // CHECK-LABEL: test_mm256_zextpbf16128_pbh256 + // CHECK: shufflevector <8 x bfloat> %{{.*}}, <8 x bfloat> {{.*}}, <16 x i32> + return _mm256_zextpbf16128_pbh256(__a); +} + +__m128bh test_mm_abs_pbh(__m128bh a) { + // CHECK-LABEL: @test_mm_abs_pbh + // CHECK: and <4 x i32> + return _mm_abs_pbh(a); +} + +__m256bh test_mm256_abs_pbh(__m256bh a) { + // CHECK-LABEL: @test_mm256_abs_pbh + // CHECK: and <8 x i32> + return _mm256_abs_pbh(a); +} + +__m256bh test_mm256_loadu_pbh(void *p) { + // CHECK-LABEL: @test_mm256_loadu_pbh + // CHECK: load <16 x bfloat>, ptr {{.*}}, align 1{{$}} + return _mm256_loadu_pbh(p); +} + +__m128bh test_mm_load_sbh(void const *A) { + // CHECK-LABEL: test_mm_load_sbh + // CHECK: %{{.*}} = call <8 x bfloat> @llvm.masked.load.v8bf16.p0(ptr %{{.*}}, i32 1, <8 x i1> bitcast (<1 x i8> to <8 x i1>), <8 x bfloat> %{{.*}}) + return _mm_load_sbh(A); +} + +__m256bh test_mm256_load_pbh(void *p) { + // CHECK-LABEL: @test_mm256_load_pbh + // CHECK: load <16 x bfloat>, ptr %{{.*}}, align 32 + return _mm256_load_pbh(p); +} + +__m128bh test_mm_load_pbh(void *p) { + // CHECK-LABEL: @test_mm_load_pbh + // CHECK: load <8 x bfloat>, ptr %{{.*}}, align 16 + return _mm_load_pbh(p); +} + +__m128bh test_mm_loadu_pbh(void *p) { + // CHECK-LABEL: @test_mm_loadu_pbh + // CHECK: load <8 x bfloat>, ptr {{.*}}, align 1{{$}} + return _mm_loadu_pbh(p); +} + +void test_mm_store_sbh(void *A, __m128bh B) { + // CHECK-LABEL: test_mm_store_sbh + // CHECK: extractelement <8 x bfloat> %{{.*}}, i32 0 + // CHECK: store bfloat %{{.*}}, ptr %{{.*}}, align 1{{$}} + _mm_store_sbh(A, B); +} + +void test_mm_mask_store_sbh(void *__P, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_store_sbh + // CHECK: call void @llvm.masked.store.v8bf16.p0(<8 x bfloat> %{{.*}}, ptr %{{.*}}, i32 1, <8 x i1> %{{.*}}) + _mm_mask_store_sbh(__P, __U, __A); +} + +void test_mm256_store_pbh(void *p, __m256bh a) { + // CHECK-LABEL: @test_mm256_store_pbh + // CHECK: store <16 x bfloat> %{{.*}}, ptr %{{.*}}, align 32 + _mm256_store_pbh(p, a); +} + +void test_mm_store_pbh(void *p, __m128bh a) { + // CHECK-LABEL: @test_mm_store_pbh + // CHECK: store <8 x bfloat> %{{.*}}, ptr %{{.*}}, align 16 + _mm_store_pbh(p, a); +} + +__m128bh test_mm_mask_load_sbh(__m128bh __A, __mmask8 __U, const void *__W) { + // CHECK-LABEL: @test_mm_mask_load_sbh + // CHECK: %{{.*}} = call <8 x bfloat> @llvm.masked.load.v8bf16.p0(ptr %{{.*}}, i32 1, <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}) + return _mm_mask_load_sbh(__A, __U, __W); +} + +__m128bh test_mm_maskz_load_sbh(__mmask8 __U, const void *__W) { + // CHECK-LABEL: @test_mm_maskz_load_sbh + // CHECK: %{{.*}} = call <8 x bfloat> @llvm.masked.load.v8bf16.p0(ptr %{{.*}}, i32 1, <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}) + return _mm_maskz_load_sbh(__U, __W); +} + +void test_mm256_storeu_pbh(void *p, __m256bh a) { + // CHECK-LABEL: @test_mm256_storeu_pbh + // CHECK: store <16 x bfloat> %{{.*}}, ptr %{{.*}}, align 1{{$}} + // CHECK-NEXT: ret void + _mm256_storeu_pbh(p, a); +} + +void test_mm_storeu_pbh(void *p, __m128bh a) { + // CHECK-LABEL: @test_mm_storeu_pbh + // CHECK: store <8 x bfloat> %{{.*}}, ptr %{{.*}}, align 1{{$}} + // CHECK-NEXT: ret void + _mm_storeu_pbh(p, a); +} + +__m128bh test_mm_move_sbh(__m128bh A, __m128bh B) { + // CHECK-LABEL: test_mm_move_sbh + // CHECK: extractelement <8 x bfloat> %{{.*}}, i32 0 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat %{{.*}}, i32 0 + return _mm_move_sbh(A, B); +} + +__m128bh test_mm_mask_move_sbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_mask_move_sbh + // CHECK: [[EXT:%.*]] = extractelement <8 x bfloat> %{{.*}}, i32 0 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat [[EXT]], i32 0 + // CHECK: [[A:%.*]] = extractelement <8 x bfloat> [[VEC:%.*]], i64 0 + // CHECK-NEXT: [[B:%.*]] = extractelement <8 x bfloat> %{{.*}}, i64 0 + // CHECK-NEXT: bitcast i8 %{{.*}} to <8 x i1> + // CHECK-NEXT: extractelement <8 x i1> %{{.*}}, i64 0 + // CHECK-NEXT: [[SEL:%.*]] = select i1 %{{.*}}, bfloat [[A]], bfloat [[B]] + // CHECK-NEXT: insertelement <8 x bfloat> [[VEC]], bfloat [[SEL]], i64 0 + return _mm_mask_move_sbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_move_sbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_maskz_move_sbh + // CHECK: [[EXT:%.*]] = extractelement <8 x bfloat> %{{.*}}, i32 0 + // CHECK: insertelement <8 x bfloat> %{{.*}}, bfloat [[EXT]], i32 0 + // CHECK: [[A:%.*]] = extractelement <8 x bfloat> [[VEC:%.*]], i64 0 + // CHECK-NEXT: [[B:%.*]] = extractelement <8 x bfloat> %{{.*}}, i64 0 + // CHECK-NEXT: bitcast i8 %{{.*}} to <8 x i1> + // CHECK-NEXT: extractelement <8 x i1> %{{.*}}, i64 0 + // CHECK-NEXT: [[SEL:%.*]] = select i1 %{{.*}}, bfloat [[A]], bfloat [[B]] + // CHECK-NEXT: insertelement <8 x bfloat> [[VEC]], bfloat [[SEL]], i64 0 + return _mm_maskz_move_sbh(__U, __A, __B); +} + +__m128bh test_mm_mask_blend_pbh(__mmask8 __U, __m128bh __A, __m128bh __W) { + // CHECK-LABEL: @test_mm_mask_blend_pbh + // CHECK: %{{.*}} = bitcast i8 %{{.*}} to <8 x i1> + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask_blend_pbh(__U, __A, __W); +} + +__m256bh test_mm256_mask_blend_pbh(__mmask16 __U, __m256bh __A, __m256bh __W) { + // CHECK-LABEL: @test_mm256_mask_blend_pbh + // CHECK: %{{.*}} = bitcast i16 %{{.*}} to <16 x i1> + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask_blend_pbh(__U, __A, __W); +} + +__m128bh test_mm_permutex2var_pbh(__m128bh __A, __m128i __I, __m128bh __B) { + // CHECK-LABEL: @test_mm_permutex2var_pbh + // CHECK: %{{.*}} = bitcast <8 x bfloat> %{{.*}} to <8 x i16> + // CHECK: %{{.*}} = bitcast <2 x i64> %{{.*}} to <8 x i16> + // CHECK: %{{.*}} = bitcast <8 x bfloat> %{{.*}} to <8 x i16> + // CHECK: %{{.*}} = call <8 x i16> @llvm.x86.avx512.vpermi2var.hi.128(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK: %{{.*}} = bitcast <8 x i16> %{{.*}} to <8 x bfloat> + return _mm_permutex2var_pbh(__A, __I, __B); +} + +__m256bh test_mm256_permutex2var_pbh(__m256bh __A, __m256i __I, __m256bh __B) { + // CHECK-LABEL: @test_mm256_permutex2var_pbh + // CHECK: %{{.*}} = bitcast <16 x bfloat> %{{.*}} to <16 x i16> + // CHECK: %{{.*}} = bitcast <4 x i64> %{{.*}} to <16 x i16> + // CHECK: %{{.*}} = bitcast <16 x bfloat> %{{.*}} to <16 x i16> + // CHECK: %{{.*}} = call <16 x i16> @llvm.x86.avx512.vpermi2var.hi.256(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: %{{.*}} = bitcast <16 x i16> %{{.*}} to <16 x bfloat> + return _mm256_permutex2var_pbh(__A, __I, __B); +} + +__m128bh test_mm_permutexvar_pbh(__m128i __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_permutexvar_pbh + // CHECK: %{{.*}} = bitcast <8 x bfloat> %{{.*}} to <8 x i16> + // CHECK: %{{.*}} = bitcast <2 x i64> %{{.*}} to <8 x i16> + // CHECK: %{{.*}} = call <8 x i16> @llvm.x86.avx512.permvar.hi.128(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK: %{{.*}} = bitcast <8 x i16> %{{.*}} to <8 x bfloat> + return _mm_permutexvar_pbh(__A, __B); +} + +__m256bh test_mm256_permutexvar_pbh(__m256i __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_permutexvar_pbh + // CHECK: %{{.*}} = bitcast <16 x bfloat> %{{.*}} to <16 x i16> + // CHECK: %{{.*}} = bitcast <4 x i64> %{{.*}} to <16 x i16> + // CHECK: %{{.*}} = call <16 x i16> @llvm.x86.avx512.permvar.hi.256(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: %{{.*}} = bitcast <16 x i16> %{{.*}} to <16 x bfloat> + return _mm256_permutexvar_pbh(__A, __B); +} + +__m256bh test_mm256_addne_pbh(__m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_addne_pbh + // CHECK: %{{.*}} = fadd <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_addne_pbh(__A, __B); +} + +__m256bh test_mm256_mask_addne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fadd <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return (__m256bh)_mm256_mask_addne_pbh(__W, __U, __A, __B); +} + +__m256bh test_mm256_maskz_addne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fadd <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_addne_pbh(__U, __A, __B); +} + +__m128bh test_mm_addne_pbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_addne_pbh + // CHECK: %{{.*}} = fadd <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_addne_pbh(__A, __B); +} + +__m128bh test_mm_mask_addne_pbh(__m128bh __W, __mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fadd <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return (__m128bh)_mm_mask_addne_pbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_addne_pbh(__mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fadd <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_addne_pbh(__U, __A, __B); +} + +__m256bh test_mm256_subne_pbh(__m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_subne_pbh + // CHECK: %{{.*}} = fsub <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_subne_pbh(__A, __B); +} + +__m256bh test_mm256_mask_subne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fsub <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return (__m256bh)_mm256_mask_subne_pbh(__W, __U, __A, __B); +} + +__m256bh test_mm256_maskz_subne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fsub <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_subne_pbh(__U, __A, __B); +} + +__m128bh test_mm_subne_pbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_subne_pbh + // CHECK: %{{.*}} = fsub <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_subne_pbh(__A, __B); +} + +__m128bh test_mm_mask_subne_pbh(__m128bh __W, __mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fsub <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return (__m128bh)_mm_mask_subne_pbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_subne_pbh(__mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fsub <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_subne_pbh(__U, __A, __B); +} + +__m256bh test_mm256_mulne_pbh(__m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_mulne_pbh + // CHECK: %{{.*}} = fmul <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_mulne_pbh(__A, __B); +} + +__m256bh test_mm256_mask_mulne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fmul <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return (__m256bh)_mm256_mask_mulne_pbh(__W, __U, __A, __B); +} + +__m256bh test_mm256_maskz_mulne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fmul <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_mulne_pbh(__U, __A, __B); +} + +__m128bh test_mm_mulne_pbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_mulne_pbh + // CHECK: %{{.*}} = fmul <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_mulne_pbh(__A, __B); +} + +__m128bh test_mm_mask_mulne_pbh(__m128bh __W, __mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fmul <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return (__m128bh)_mm_mask_mulne_pbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_mulne_pbh(__mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fmul <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_mulne_pbh(__U, __A, __B); +} + +__m256bh test_mm256_divne_pbh(__m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_divne_pbh + // CHECK: %{{.*}} = fdiv <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_divne_pbh(__A, __B); +} + +__m256bh test_mm256_mask_divne_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fdiv <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return (__m256bh)_mm256_mask_divne_pbh(__W, __U, __A, __B); +} + +__m256bh test_mm256_maskz_divne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: %{{.*}} = fdiv <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_divne_pbh(__U, __A, __B); +} + +__m128bh test_mm_divne_pbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_divne_pbh + // CHECK: %{{.*}} = fdiv <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_divne_pbh(__A, __B); +} + +__m128bh test_mm_mask_divne_pbh(__m128bh __W, __mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fdiv <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return (__m128bh)_mm_mask_divne_pbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_divne_pbh(__mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: %{{.*}} = fdiv <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_divne_pbh(__U, __A, __B); +} + +__m256bh test_mm256_max_pbh(__m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_max_pbh + // CHECK: @llvm.x86.avx10.vmaxpbf16256( + return _mm256_max_pbh(__A, __B); +} + +__m256bh test_mm256_mask_max_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: @llvm.x86.avx10.vmaxpbf16256 + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return (__m256bh)_mm256_mask_max_pbh(__W, __U, __A, __B); +} + +__m256bh test_mm256_maskz_max_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: @llvm.x86.avx10.vmaxpbf16256 + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_max_pbh(__U, __A, __B); +} + +__m128bh test_mm_max_pbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_max_pbh + // CHECK: @llvm.x86.avx10.vmaxpbf16128( + return _mm_max_pbh(__A, __B); +} + +__m128bh test_mm_mask_max_pbh(__m128bh __W, __mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: @llvm.x86.avx10.vmaxpbf16128 + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return (__m128bh)_mm_mask_max_pbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_max_pbh(__mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: @llvm.x86.avx10.vmaxpbf16128 + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_max_pbh(__U, __A, __B); +} + +__m256bh test_mm256_min_pbh(__m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_min_pbh + // CHECK: @llvm.x86.avx10.vminpbf16256( + return _mm256_min_pbh(__A, __B); +} + +__m256bh test_mm256_mask_min_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: @llvm.x86.avx10.vminpbf16256 + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return (__m256bh)_mm256_mask_min_pbh(__W, __U, __A, __B); +} + +__m256bh test_mm256_maskz_min_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK: @llvm.x86.avx10.vminpbf16256 + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_min_pbh(__U, __A, __B); +} + +__m128bh test_mm_min_pbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_min_pbh + // CHECK: @llvm.x86.avx10.vminpbf16128( + return _mm_min_pbh(__A, __B); +} + +__m128bh test_mm_mask_min_pbh(__m128bh __W, __mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: @llvm.x86.avx10.vminpbf16128 + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return (__m128bh)_mm_mask_min_pbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_min_pbh(__mmask16 __U, __m128bh __A, __m128bh __B) { + // CHECK: @llvm.x86.avx10.vminpbf16128 + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_min_pbh(__U, __A, __B); +} + +int test_mm_comeqsbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: test_mm_comeqsbh + // CHECK: %{{.}} = call i32 @llvm.x86.avx10.vcomsbf16eq(<8 x bfloat> %{{.}}, <8 x bfloat> %{{.}}) + return _mm_comeqsbh(__A, __B); +} + +int test_mm_comltsbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: test_mm_comltsbh + // CHECK: %{{.}} = call i32 @llvm.x86.avx10.vcomsbf16lt(<8 x bfloat> %{{.}}, <8 x bfloat> %{{.}}) + return _mm_comltsbh(__A, __B); +} + +int test_mm_comlesbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: test_mm_comlesbh + // CHECK: %{{.}} = call i32 @llvm.x86.avx10.vcomsbf16le(<8 x bfloat> %{{.}}, <8 x bfloat> %{{.}}) + return _mm_comlesbh(__A, __B); +} + +int test_mm_comgtsbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: test_mm_comgtsbh + // CHECK: %{{.}} = call i32 @llvm.x86.avx10.vcomsbf16gt(<8 x bfloat> %{{.}}, <8 x bfloat> %{{.}}) + return _mm_comgtsbh(__A, __B); +} + +int test_mm_comgesbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: test_mm_comgesbh + // CHECK: %{{.}} = call i32 @llvm.x86.avx10.vcomsbf16ge(<8 x bfloat> %{{.}}, <8 x bfloat> %{{.}}) + return _mm_comgesbh(__A, __B); +} + +int test_mm_comneqsbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: test_mm_comneqsbh + // CHECK: %{{.}} = call i32 @llvm.x86.avx10.vcomsbf16neq(<8 x bfloat> %{{.}}, <8 x bfloat> %{{.}}) + return _mm_comneqsbh(__A, __B); +} + +__mmask16 test_mm256_cmp_pbh_mask_eq_oq(__m256bh a, __m256bh b) { + // CHECK-LABEL: @test_mm256_cmp_pbh_mask_eq_oq + // CHECK: fcmp oeq <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_EQ_OQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_lt_os(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_lt_os + // CHECK: fcmp olt <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_LT_OS); +} + +__mmask16 test_mm256_cmp_pbh_mask_le_os(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_le_os + // CHECK: fcmp ole <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_LE_OS); +} + +__mmask16 test_mm256_cmp_pbh_mask_unord_q(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_unord_q + // CHECK: fcmp uno <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_UNORD_Q); +} + +__mmask16 test_mm256_cmp_pbh_mask_neq_uq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_neq_uq + // CHECK: fcmp une <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NEQ_UQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_nlt_us(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_nlt_us + // CHECK: fcmp uge <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NLT_US); +} + +__mmask16 test_mm256_cmp_pbh_mask_nle_us(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_nle_us + // CHECK: fcmp ugt <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NLE_US); +} + +__mmask16 test_mm256_cmp_pbh_mask_ord_q(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_ord_q + // CHECK: fcmp ord <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_ORD_Q); +} + +__mmask16 test_mm256_cmp_pbh_mask_eq_uq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_eq_uq + // CHECK: fcmp ueq <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_EQ_UQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_nge_us(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_nge_us + // CHECK: fcmp ult <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NGE_US); +} + +__mmask16 test_mm256_cmp_pbh_mask_ngt_us(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_ngt_us + // CHECK: fcmp ule <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NGT_US); +} + +__mmask16 test_mm256_cmp_pbh_mask_false_oq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_false_oq + // CHECK: fcmp false <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_FALSE_OQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_neq_oq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_neq_oq + // CHECK: fcmp one <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NEQ_OQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_ge_os(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_ge_os + // CHECK: fcmp oge <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_GE_OS); +} + +__mmask16 test_mm256_cmp_pbh_mask_gt_os(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_gt_os + // CHECK: fcmp ogt <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_GT_OS); +} + +__mmask16 test_mm256_cmp_pbh_mask_true_uq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_true_uq + // CHECK: fcmp true <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_TRUE_UQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_eq_os(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_eq_os + // CHECK: fcmp oeq <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_EQ_OS); +} + +__mmask16 test_mm256_cmp_pbh_mask_lt_oq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_lt_oq + // CHECK: fcmp olt <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_LT_OQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_le_oq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_le_oq + // CHECK: fcmp ole <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_LE_OQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_unord_s(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_unord_s + // CHECK: fcmp uno <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_UNORD_S); +} + +__mmask16 test_mm256_cmp_pbh_mask_neq_us(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_neq_us + // CHECK: fcmp une <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NEQ_US); +} + +__mmask16 test_mm256_cmp_pbh_mask_nlt_uq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_nlt_uq + // CHECK: fcmp uge <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NLT_UQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_nle_uq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_nle_uq + // CHECK: fcmp ugt <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NLE_UQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_ord_s(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_ord_s + // CHECK: fcmp ord <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_ORD_S); +} + +__mmask16 test_mm256_cmp_pbh_mask_eq_us(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_eq_us + // CHECK: fcmp ueq <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_EQ_US); +} + +__mmask16 test_mm256_cmp_pbh_mask_nge_uq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_nge_uq + // CHECK: fcmp ult <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NGE_UQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_ngt_uq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_ngt_uq + // CHECK: fcmp ule <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NGT_UQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_false_os(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_false_os + // CHECK: fcmp false <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_FALSE_OS); +} + +__mmask16 test_mm256_cmp_pbh_mask_neq_os(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_neq_os + // CHECK: fcmp one <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_NEQ_OS); +} + +__mmask16 test_mm256_cmp_pbh_mask_ge_oq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_ge_oq + // CHECK: fcmp oge <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_GE_OQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_gt_oq(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_gt_oq + // CHECK: fcmp ogt <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_GT_OQ); +} + +__mmask16 test_mm256_cmp_pbh_mask_true_us(__m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_cmp_pbh_mask_true_us + // CHECK: fcmp true <16 x bfloat> %{{.*}}, %{{.*}} + return _mm256_cmp_pbh_mask(a, b, _CMP_TRUE_US); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_eq_oq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: @test_mm256_mask_cmp_pbh_mask_eq_oq + // CHECK: fcmp oeq <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_OQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_lt_os(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_lt_os + // CHECK: fcmp olt <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_LT_OS); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_le_os(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_le_os + // CHECK: fcmp ole <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_LE_OS); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_unord_q(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_unord_q + // CHECK: fcmp uno <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_UNORD_Q); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_neq_uq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_neq_uq + // CHECK: fcmp une <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_UQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_nlt_us(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_nlt_us + // CHECK: fcmp uge <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NLT_US); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_nle_us(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_nle_us + // CHECK: fcmp ugt <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NLE_US); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_ord_q(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_ord_q + // CHECK: fcmp ord <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_ORD_Q); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_eq_uq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_eq_uq + // CHECK: fcmp ueq <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_UQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_nge_us(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_nge_us + // CHECK: fcmp ult <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NGE_US); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_ngt_us(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_ngt_us + // CHECK: fcmp ule <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NGT_US); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_false_oq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_false_oq + // CHECK: fcmp false <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_FALSE_OQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_neq_oq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_neq_oq + // CHECK: fcmp one <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_OQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_ge_os(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_ge_os + // CHECK: fcmp oge <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_GE_OS); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_gt_os(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_gt_os + // CHECK: fcmp ogt <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_GT_OS); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_true_uq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_true_uq + // CHECK: fcmp true <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_TRUE_UQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_eq_os(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_eq_os + // CHECK: fcmp oeq <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_OS); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_lt_oq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_lt_oq + // CHECK: fcmp olt <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_LT_OQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_le_oq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_le_oq + // CHECK: fcmp ole <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_LE_OQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_unord_s(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_unord_s + // CHECK: fcmp uno <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_UNORD_S); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_neq_us(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_neq_us + // CHECK: fcmp une <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_US); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_nlt_uq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_nlt_uq + // CHECK: fcmp uge <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NLT_UQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_nle_uq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_nle_uq + // CHECK: fcmp ugt <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NLE_UQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_ord_s(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_ord_s + // CHECK: fcmp ord <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_ORD_S); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_eq_us(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_eq_us + // CHECK: fcmp ueq <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_US); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_nge_uq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_nge_uq + // CHECK: fcmp ult <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NGE_UQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_ngt_uq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_ngt_uq + // CHECK: fcmp ule <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NGT_UQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_false_os(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_false_os + // CHECK: fcmp false <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_FALSE_OS); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_neq_os(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_neq_os + // CHECK: fcmp one <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_OS); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_ge_oq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_ge_oq + // CHECK: fcmp oge <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_GE_OQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_gt_oq(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_gt_oq + // CHECK: fcmp ogt <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_GT_OQ); +} + +__mmask16 test_mm256_mask_cmp_pbh_mask_true_us(__mmask16 m, __m256bh a, __m256bh b) { + // CHECK-LABEL: test_mm256_mask_cmp_pbh_mask_true_us + // CHECK: fcmp true <16 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <16 x i1> %{{.*}}, %{{.*}} + return _mm256_mask_cmp_pbh_mask(m, a, b, _CMP_TRUE_US); +} + +__mmask8 test_mm_cmp_pbh_mask_eq_oq(__m128bh a, __m128bh b) { + // CHECK-LABEL: @test_mm_cmp_pbh_mask_eq_oq + // CHECK: fcmp oeq <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_EQ_OQ); +} + +__mmask8 test_mm_cmp_pbh_mask_lt_os(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_lt_os + // CHECK: fcmp olt <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_LT_OS); +} + +__mmask8 test_mm_cmp_pbh_mask_le_os(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_le_os + // CHECK: fcmp ole <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_LE_OS); +} + +__mmask8 test_mm_cmp_pbh_mask_unord_q(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_unord_q + // CHECK: fcmp uno <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_UNORD_Q); +} + +__mmask8 test_mm_cmp_pbh_mask_neq_uq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_neq_uq + // CHECK: fcmp une <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NEQ_UQ); +} + +__mmask8 test_mm_cmp_pbh_mask_nlt_us(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_nlt_us + // CHECK: fcmp uge <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NLT_US); +} + +__mmask8 test_mm_cmp_pbh_mask_nle_us(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_nle_us + // CHECK: fcmp ugt <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NLE_US); +} + +__mmask8 test_mm_cmp_pbh_mask_ord_q(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_ord_q + // CHECK: fcmp ord <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_ORD_Q); +} + +__mmask8 test_mm_cmp_pbh_mask_eq_uq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_eq_uq + // CHECK: fcmp ueq <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_EQ_UQ); +} + +__mmask8 test_mm_cmp_pbh_mask_nge_us(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_nge_us + // CHECK: fcmp ult <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NGE_US); +} + +__mmask8 test_mm_cmp_pbh_mask_ngt_us(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_ngt_us + // CHECK: fcmp ule <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NGT_US); +} + +__mmask8 test_mm_cmp_pbh_mask_false_oq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_false_oq + // CHECK: fcmp false <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_FALSE_OQ); +} + +__mmask8 test_mm_cmp_pbh_mask_neq_oq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_neq_oq + // CHECK: fcmp one <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NEQ_OQ); +} + +__mmask8 test_mm_cmp_pbh_mask_ge_os(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_ge_os + // CHECK: fcmp oge <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_GE_OS); +} + +__mmask8 test_mm_cmp_pbh_mask_gt_os(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_gt_os + // CHECK: fcmp ogt <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_GT_OS); +} + +__mmask8 test_mm_cmp_pbh_mask_true_uq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_true_uq + // CHECK: fcmp true <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_TRUE_UQ); +} + +__mmask8 test_mm_cmp_pbh_mask_eq_os(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_eq_os + // CHECK: fcmp oeq <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_EQ_OS); +} + +__mmask8 test_mm_cmp_pbh_mask_lt_oq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_lt_oq + // CHECK: fcmp olt <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_LT_OQ); +} + +__mmask8 test_mm_cmp_pbh_mask_le_oq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_le_oq + // CHECK: fcmp ole <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_LE_OQ); +} + +__mmask8 test_mm_cmp_pbh_mask_unord_s(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_unord_s + // CHECK: fcmp uno <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_UNORD_S); +} + +__mmask8 test_mm_cmp_pbh_mask_neq_us(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_neq_us + // CHECK: fcmp une <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NEQ_US); +} + +__mmask8 test_mm_cmp_pbh_mask_nlt_uq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_nlt_uq + // CHECK: fcmp uge <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NLT_UQ); +} + +__mmask8 test_mm_cmp_pbh_mask_nle_uq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_nle_uq + // CHECK: fcmp ugt <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NLE_UQ); +} + +__mmask8 test_mm_cmp_pbh_mask_ord_s(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_ord_s + // CHECK: fcmp ord <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_ORD_S); +} + +__mmask8 test_mm_cmp_pbh_mask_eq_us(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_eq_us + // CHECK: fcmp ueq <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_EQ_US); +} + +__mmask8 test_mm_cmp_pbh_mask_nge_uq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_nge_uq + // CHECK: fcmp ult <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NGE_UQ); +} + +__mmask8 test_mm_cmp_pbh_mask_ngt_uq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_ngt_uq + // CHECK: fcmp ule <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NGT_UQ); +} + +__mmask8 test_mm_cmp_pbh_mask_false_os(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_false_os + // CHECK: fcmp false <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_FALSE_OS); +} + +__mmask8 test_mm_cmp_pbh_mask_neq_os(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_neq_os + // CHECK: fcmp one <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_NEQ_OS); +} + +__mmask8 test_mm_cmp_pbh_mask_ge_oq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_ge_oq + // CHECK: fcmp oge <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_GE_OQ); +} + +__mmask8 test_mm_cmp_pbh_mask_gt_oq(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_gt_oq + // CHECK: fcmp ogt <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_GT_OQ); +} + +__mmask8 test_mm_cmp_pbh_mask_true_us(__m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_cmp_pbh_mask_true_us + // CHECK: fcmp true <8 x bfloat> %{{.*}}, %{{.*}} + return _mm_cmp_pbh_mask(a, b, _CMP_TRUE_US); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_eq_oq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: @test_mm_mask_cmp_pbh_mask_eq_oq + // CHECK: fcmp oeq <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_OQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_lt_os(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_lt_os + // CHECK: fcmp olt <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_LT_OS); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_le_os(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_le_os + // CHECK: fcmp ole <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_LE_OS); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_unord_q(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_unord_q + // CHECK: fcmp uno <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_UNORD_Q); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_neq_uq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_neq_uq + // CHECK: fcmp une <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_UQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_nlt_us(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_nlt_us + // CHECK: fcmp uge <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NLT_US); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_nle_us(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_nle_us + // CHECK: fcmp ugt <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NLE_US); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_ord_q(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_ord_q + // CHECK: fcmp ord <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_ORD_Q); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_eq_uq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_eq_uq + // CHECK: fcmp ueq <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_UQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_nge_us(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_nge_us + // CHECK: fcmp ult <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NGE_US); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_ngt_us(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_ngt_us + // CHECK: fcmp ule <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NGT_US); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_false_oq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_false_oq + // CHECK: fcmp false <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_FALSE_OQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_neq_oq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_neq_oq + // CHECK: fcmp one <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_OQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_ge_os(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_ge_os + // CHECK: fcmp oge <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_GE_OS); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_gt_os(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_gt_os + // CHECK: fcmp ogt <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_GT_OS); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_true_uq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_true_uq + // CHECK: fcmp true <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_TRUE_UQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_eq_os(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_eq_os + // CHECK: fcmp oeq <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_OS); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_lt_oq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_lt_oq + // CHECK: fcmp olt <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_LT_OQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_le_oq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_le_oq + // CHECK: fcmp ole <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_LE_OQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_unord_s(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_unord_s + // CHECK: fcmp uno <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_UNORD_S); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_neq_us(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_neq_us + // CHECK: fcmp une <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_US); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_nlt_uq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_nlt_uq + // CHECK: fcmp uge <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NLT_UQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_nle_uq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_nle_uq + // CHECK: fcmp ugt <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NLE_UQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_ord_s(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_ord_s + // CHECK: fcmp ord <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_ORD_S); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_eq_us(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_eq_us + // CHECK: fcmp ueq <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_EQ_US); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_nge_uq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_nge_uq + // CHECK: fcmp ult <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NGE_UQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_ngt_uq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_ngt_uq + // CHECK: fcmp ule <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NGT_UQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_false_os(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_false_os + // CHECK: fcmp false <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_FALSE_OS); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_neq_os(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_neq_os + // CHECK: fcmp one <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_NEQ_OS); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_ge_oq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_ge_oq + // CHECK: fcmp oge <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_GE_OQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_gt_oq(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_gt_oq + // CHECK: fcmp ogt <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_GT_OQ); +} + +__mmask8 test_mm_mask_cmp_pbh_mask_true_us(__mmask8 m, __m128bh a, __m128bh b) { + // CHECK-LABEL: test_mm_mask_cmp_pbh_mask_true_us + // CHECK: fcmp true <8 x bfloat> %{{.*}}, %{{.*}} + // CHECK: and <8 x i1> %{{.*}}, %{{.*}} + return _mm_mask_cmp_pbh_mask(m, a, b, _CMP_TRUE_US); +} + + +__mmask16 test_mm256_mask_fpclass_pbh_mask(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_fpclass_pbh_mask + // CHECK: @llvm.x86.avx10.fpclass.nepbf16.256 + return _mm256_mask_fpclass_pbh_mask(__U, __A, 4); +} + +__mmask16 test_mm256_fpclass_pbh_mask(__m256bh __A) { + // CHECK-LABEL: @test_mm256_fpclass_pbh_mask + // CHECK: @llvm.x86.avx10.fpclass.nepbf16.256 + return _mm256_fpclass_pbh_mask(__A, 4); +} + +__mmask8 test_mm_mask_fpclass_pbh_mask(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_fpclass_pbh_mask + // CHECK: @llvm.x86.avx10.fpclass.nepbf16.128 + return _mm_mask_fpclass_pbh_mask(__U, __A, 4); +} + +__mmask8 test_mm_fpclass_pbh_mask(__m128bh __A) { + // CHECK-LABEL: @test_mm_fpclass_pbh_mask + // CHECK: @llvm.x86.avx10.fpclass.nepbf16.128 + return _mm_fpclass_pbh_mask(__A, 4); +} + +__m256bh test_mm256_scalef_pbh(__m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.256 + return _mm256_scalef_pbh(__A, __B); +} + +__m256bh test_mm256_mask_scalef_pbh(__m256bh __W, __mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_mask_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.256 + return _mm256_mask_scalef_pbh(__W, __U, __A, __B); +} + +__m256bh test_mm256_maskz_scalef_pbh(__mmask16 __U, __m256bh __A, __m256bh __B) { + // CHECK-LABEL: @test_mm256_maskz_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.256 + return _mm256_maskz_scalef_pbh(__U, __A, __B); +} + +__m256bh test_mm256_rcp_pbh(__m256bh __A) { + // CHECK-LABEL: @test_mm256_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.256 + return _mm256_rcp_pbh(__A); +} + +__m256bh test_mm256_mask_rcp_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.256 + return (__m256bh)_mm256_mask_rcp_pbh(__W, __U, __A); +} + +__m256bh test_mm256_maskz_rcp_pbh(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_maskz_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.256 + return _mm256_maskz_rcp_pbh(__U, __A); +} + +__m256bh test_mm256_getexp_pbh(__m256bh __A) { + // CHECK-LABEL: @test_mm256_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.256 + return _mm256_getexp_pbh(__A); +} + +__m256bh test_mm256_mask_getexp_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.256 + return _mm256_mask_getexp_pbh(__W, __U, __A); +} + +__m256bh test_mm256_maskz_getexp_pbh(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_maskz_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.256 + return _mm256_maskz_getexp_pbh(__U, __A); +} + +__m256bh test_mm256_rsqrt_pbh(__m256bh __A) { + // CHECK-LABEL: @test_mm256_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.256 + return _mm256_rsqrt_pbh(__A); +} + +__m256bh test_mm256_mask_rsqrt_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.256 + return (__m256bh)_mm256_mask_rsqrt_pbh(__W, __U, __A); +} + +__m256bh test_mm256_maskz_rsqrt_pbh(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_maskz_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.256 + return _mm256_maskz_rsqrt_pbh(__U, __A); +} + +__m256bh test_mm256_reducene_pbh(__m256bh __A) { + // CHECK-LABEL: @test_mm256_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.256 + return _mm256_reducene_pbh(__A, 3); +} + +__m256bh test_mm256_mask_reducene_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.256 + return _mm256_mask_reducene_pbh(__W, __U, __A, 1); +} + +__m256bh test_mm256_maskz_reducene_pbh(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_maskz_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.256 + return _mm256_maskz_reducene_pbh(__U, __A, 1); +} + +__m256bh test_mm256_roundscalene_pbh(__m256bh __A) { + // CHECK-LABEL: @test_mm256_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.256 + return _mm256_roundscalene_pbh(__A, 3); +} + +__m256bh test_mm256_mask_roundscalene_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.256 + return _mm256_mask_roundscalene_pbh(__W, __U, __A, 1); +} + +__m256bh test_mm256_maskz_roundscalene_pbh(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_maskz_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.256 + return _mm256_maskz_roundscalene_pbh(__U, __A, 1 ); +} + +__m256bh test_mm256_getmant_pbh(__m256bh __A) { + // CHECK-LABEL: @test_mm256_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.256 + return _mm256_getmant_pbh(__A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m256bh test_mm256_mask_getmant_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.256 + return _mm256_mask_getmant_pbh(__W, __U, __A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m256bh test_mm256_maskz_getmant_pbh(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_maskz_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.256 + return _mm256_maskz_getmant_pbh(__U, __A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m256bh test_mm256_sqrt_pbh(__m256bh __A) { + // CHECK-LABEL: @test_mm256_sqrt_pbh + // CHECK: call <16 x bfloat> @llvm.sqrt.v16bf16(<16 x bfloat> %{{.*}}) + return _mm256_sqrt_pbh(__A); +} + +__m256bh test_mm256_mask_sqrt_pbh(__m256bh __W, __mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_mask_sqrt_pbh + // CHECK: @llvm.sqrt.v16bf16 + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return (__m256bh)_mm256_mask_sqrt_pbh(__W, __U, __A); +} + +__m256bh test_mm256_maskz_sqrt_pbh(__mmask16 __U, __m256bh __A) { + // CHECK-LABEL: @test_mm256_maskz_sqrt_pbh + // CHECK: @llvm.sqrt.v16bf16 + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_sqrt_pbh(__U, __A); +} + +__m128bh test_mm_scalef_pbh(__m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.128 + return _mm_scalef_pbh(__A, __B); +} + +__m128bh test_mm_mask_scalef_pbh(__m128bh __W, __mmask8 __U, __m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_mask_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.128 + return _mm_mask_scalef_pbh(__W, __U, __A, __B); +} + +__m128bh test_mm_maskz_scalef_pbh(__mmask8 __U, __m128bh __A, __m128bh __B) { + // CHECK-LABEL: @test_mm_maskz_scalef_pbh + // CHECK: @llvm.x86.avx10.mask.scalef.nepbf16.128 + return _mm_maskz_scalef_pbh(__U, __A, __B); +} + +__m128bh test_mm_rcp_pbh(__m128bh __A) { + // CHECK-LABEL: @test_mm_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.128 + return _mm_rcp_pbh(__A); +} + +__m128bh test_mm_mask_rcp_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.128 + return (__m128bh)_mm_mask_rcp_pbh(__W, __U, __A); +} + +__m128bh test_mm_maskz_rcp_pbh(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_maskz_rcp_pbh + // CHECK: @llvm.x86.avx10.mask.rcp.nepbf16.128 + return _mm_maskz_rcp_pbh(__U, __A); +} + +__m128bh test_mm_getexp_pbh(__m128bh __A) { + // CHECK-LABEL: @test_mm_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.128 + return _mm_getexp_pbh(__A); +} + +__m128bh test_mm_mask_getexp_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.128 + return _mm_mask_getexp_pbh(__W, __U, __A); +} + +__m128bh test_mm_maskz_getexp_pbh(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_maskz_getexp_pbh + // CHECK: @llvm.x86.avx10.mask.getexp.nepbf16.128 + return _mm_maskz_getexp_pbh(__U, __A); +} + +__m128bh test_mm_rsqrt_pbh(__m128bh __A) { + // CHECK-LABEL: @test_mm_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.128 + return _mm_rsqrt_pbh(__A); +} + +__m128bh test_mm_mask_rsqrt_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.128 + return (__m128bh)_mm_mask_rsqrt_pbh(__W, __U, __A); +} + +__m128bh test_mm_maskz_rsqrt_pbh(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_maskz_rsqrt_pbh + // CHECK: @llvm.x86.avx10.mask.rsqrt.nepbf16.128 + return _mm_maskz_rsqrt_pbh(__U, __A); +} + +__m128bh test_mm_reducene_pbh(__m128bh __A) { + // CHECK-LABEL: @test_mm_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.128 + return _mm_reducene_pbh(__A, 3); +} + +__m128bh test_mm_mask_reducene_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.128 + return _mm_mask_reducene_pbh(__W, __U, __A, 1); +} + +__m128bh test_mm_maskz_reducene_pbh(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_maskz_reducene_pbh + // CHECK: @llvm.x86.avx10.mask.reduce.nepbf16.128 + return _mm_maskz_reducene_pbh(__U, __A, 1); +} + +__m128bh test_mm_roundscalene_pbh(__m128bh __A) { + // CHECK-LABEL: @test_mm_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.128 + return _mm_roundscalene_pbh(__A, 3); +} + +__m128bh test_mm_mask_roundscalene_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.128 + return _mm_mask_roundscalene_pbh(__W, __U, __A, 1); +} + +__m128bh test_mm_maskz_roundscalene_pbh(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_maskz_roundscalene_pbh + // CHECK: @llvm.x86.avx10.mask.rndscale.nepbf16.128 + return _mm_maskz_roundscalene_pbh(__U, __A, 1 ); +} + +__m128bh test_mm_getmant_pbh(__m128bh __A) { + // CHECK-LABEL: @test_mm_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.128 + return _mm_getmant_pbh(__A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m128bh test_mm_mask_getmant_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.128 + return _mm_mask_getmant_pbh(__W, __U, __A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m128bh test_mm_maskz_getmant_pbh(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_maskz_getmant_pbh + // CHECK: @llvm.x86.avx10.mask.getmant.nepbf16.128 + return _mm_maskz_getmant_pbh(__U, __A, _MM_MANT_NORM_p5_2, _MM_MANT_SIGN_nan); +} + +__m128bh test_mm_sqrt_pbh(__m128bh __A) { + // CHECK-LABEL: @test_mm_sqrt_pbh + // CHECK: call <8 x bfloat> @llvm.sqrt.v8bf16(<8 x bfloat> {{.*}}) + return _mm_sqrt_pbh(__A); +} + +__m128bh test_mm_mask_sqrt_pbh(__m128bh __W, __mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_mask_sqrt_pbh + // CHECK: call <8 x bfloat> @llvm.sqrt.v8bf16(<8 x bfloat> {{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return (__m128bh)_mm_mask_sqrt_pbh(__W, __U, __A); +} + +__m128bh test_mm_maskz_sqrt_pbh(__mmask8 __U, __m128bh __A) { + // CHECK-LABEL: @test_mm_maskz_sqrt_pbh + // CHECK: call <8 x bfloat> @llvm.sqrt.v8bf16(<8 x bfloat> {{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_sqrt_pbh(__U, __A); +} + +__m256bh test_mm256_fmaddne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_fmaddne_pbh + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + return _mm256_fmaddne_pbh(__A, __B, __C); +} + +__m256bh test_mm256_mask_fmaddne_pbh(__m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_mask_fmaddne_pbh + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask_fmaddne_pbh(__A, __U, __B, __C); +} + +__m256bh test_mm256_mask3_fmaddne_pbh(__m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + // CHECK-LABEL: @test_mm256_mask3_fmaddne_pbh + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask3_fmaddne_pbh(__A, __B, __C, __U); +} + +__m256bh test_mm256_maskz_fmaddne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_maskz_fmaddne_pbh + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_fmaddne_pbh(__U, __A, __B, __C); +} + +__m256bh test_mm256_fmsubne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_fmsubne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + return _mm256_fmsubne_pbh(__A, __B, __C); +} + +__m256bh test_mm256_mask_fmsubne_pbh(__m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_mask_fmsubne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask_fmsubne_pbh(__A, __U, __B, __C); +} + +__m256bh test_mm256_mask3_fmsubne_pbh(__m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + // CHECK-LABEL: @test_mm256_mask3_fmsubne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask3_fmsubne_pbh(__A, __B, __C, __U); +} + +__m256bh test_mm256_maskz_fmsubne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_maskz_fmsubne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_fmsubne_pbh(__U, __A, __B, __C); +} + +__m256bh test_mm256_fnmaddne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + return _mm256_fnmaddne_pbh(__A, __B, __C); +} + +__m256bh test_mm256_mask_fnmaddne_pbh(__m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_mask_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask_fnmaddne_pbh(__A, __U, __B, __C); +} + +__m256bh test_mm256_mask3_fnmaddne_pbh(__m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + // CHECK-LABEL: @test_mm256_mask3_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask3_fnmaddne_pbh(__A, __B, __C, __U); +} + +__m256bh test_mm256_maskz_fnmaddne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_maskz_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_fnmaddne_pbh(__U, __A, __B, __C); +} + +__m256bh test_mm256_fnmsubne_pbh(__m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + return _mm256_fnmsubne_pbh(__A, __B, __C); +} + +__m256bh test_mm256_mask_fnmsubne_pbh(__m256bh __A, __mmask16 __U, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_mask_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask_fnmsubne_pbh(__A, __U, __B, __C); +} + +__m256bh test_mm256_mask3_fnmsubne_pbh(__m256bh __A, __m256bh __B, __m256bh __C, __mmask16 __U) { + // CHECK-LABEL: @test_mm256_mask3_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_mask3_fnmsubne_pbh(__A, __B, __C, __U); +} + +__m256bh test_mm256_maskz_fnmsubne_pbh(__mmask16 __U, __m256bh __A, __m256bh __B, __m256bh __C) { + // CHECK-LABEL: @test_mm256_maskz_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <16 x bfloat> @llvm.fma.v16bf16(<16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}}) + // CHECK: select <16 x i1> %{{.*}}, <16 x bfloat> %{{.*}}, <16 x bfloat> %{{.*}} + return _mm256_maskz_fnmsubne_pbh(__U, __A, __B, __C); +} + +__m128bh test_mm_fmaddne_pbh(__m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_fmaddne_pbh + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + return _mm_fmaddne_pbh(__A, __B, __C); +} + +__m128bh test_mm_mask_fmaddne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_mask_fmaddne_pbh + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask_fmaddne_pbh(__A, __U, __B, __C); +} + +__m128bh test_mm_mask3_fmaddne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + // CHECK-LABEL: @test_mm_mask3_fmaddne_pbh + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask3_fmaddne_pbh(__A, __B, __C, __U); +} + +__m128bh test_mm_maskz_fmaddne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_maskz_fmaddne_pbh + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_fmaddne_pbh(__U, __A, __B, __C); +} + +__m128bh test_mm_fmsubne_pbh(__m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_fmsubne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + return _mm_fmsubne_pbh(__A, __B, __C); +} + +__m128bh test_mm_mask_fmsubne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_mask_fmsubne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask_fmsubne_pbh(__A, __U, __B, __C); +} + +__m128bh test_mm_mask3_fmsubne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + // CHECK-LABEL: @test_mm_mask3_fmsubne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask3_fmsubne_pbh(__A, __B, __C, __U); +} + +__m128bh test_mm_maskz_fmsubne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_maskz_fmsubne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_fmsubne_pbh(__U, __A, __B, __C); +} + +__m128bh test_mm_fnmaddne_pbh(__m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + return _mm_fnmaddne_pbh(__A, __B, __C); +} + +__m128bh test_mm_mask_fnmaddne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_mask_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask_fnmaddne_pbh(__A, __U, __B, __C); +} + +__m128bh test_mm_mask3_fnmaddne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + // CHECK-LABEL: @test_mm_mask3_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask3_fnmaddne_pbh(__A, __B, __C, __U); +} + +__m128bh test_mm_maskz_fnmaddne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_maskz_fnmaddne_pbh + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_fnmaddne_pbh(__U, __A, __B, __C); +} + +__m128bh test_mm_fnmsubne_pbh(__m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + return _mm_fnmsubne_pbh(__A, __B, __C); +} + +__m128bh test_mm_mask_fnmsubne_pbh(__m128bh __A, __mmask8 __U, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_mask_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask_fnmsubne_pbh(__A, __U, __B, __C); +} + +__m128bh test_mm_mask3_fnmsubne_pbh(__m128bh __A, __m128bh __B, __m128bh __C, __mmask8 __U) { + // CHECK-LABEL: @test_mm_mask3_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_mask3_fnmsubne_pbh(__A, __B, __C, __U); +} + +__m128bh test_mm_maskz_fnmsubne_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) { + // CHECK-LABEL: @test_mm_maskz_fnmsubne_pbh + // CHECK: fneg + // CHECK: fneg + // CHECK: call <8 x bfloat> @llvm.fma.v8bf16(<8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}}) + // CHECK: select <8 x i1> %{{.*}}, <8 x bfloat> %{{.*}}, <8 x bfloat> %{{.*}} + return _mm_maskz_fnmsubne_pbh(__U, __A, __B, __C); +} diff --git a/clang/test/CodeGen/X86/x86-atomic-double.c b/clang/test/CodeGen/X86/x86-atomic-double.c index 2354c89cc2b17..09c8f70c3db85 100644 --- a/clang/test/CodeGen/X86/x86-atomic-double.c +++ b/clang/test/CodeGen/X86/x86-atomic-double.c @@ -6,20 +6,14 @@ // X64-LABEL: define dso_local double @test_double_post_inc( // X64-SAME: ) #[[ATTR0:[0-9]+]] { // X64-NEXT: entry: -// X64-NEXT: [[RETVAL:%.*]] = alloca double, align 8 -// X64-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_post_inc.n, float 1.000000e+00 seq_cst, align 8 -// X64-NEXT: store float [[TMP0]], ptr [[RETVAL]], align 8 -// X64-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL]], align 8 -// X64-NEXT: ret double [[TMP1]] +// X64-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_post_inc.n, double 1.000000e+00 seq_cst, align 8 +// X64-NEXT: ret double [[TMP0]] // // X86-LABEL: define dso_local double @test_double_post_inc( // X86-SAME: ) #[[ATTR0:[0-9]+]] { // X86-NEXT: entry: -// X86-NEXT: [[RETVAL:%.*]] = alloca double, align 4 -// X86-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_post_inc.n, float 1.000000e+00 seq_cst, align 8 -// X86-NEXT: store float [[TMP0]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL]], align 4 -// X86-NEXT: ret double [[TMP1]] +// X86-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_post_inc.n, double 1.000000e+00 seq_cst, align 8 +// X86-NEXT: ret double [[TMP0]] // double test_double_post_inc() { @@ -30,20 +24,14 @@ double test_double_post_inc() // X64-LABEL: define dso_local double @test_double_post_dc( // X64-SAME: ) #[[ATTR0]] { // X64-NEXT: entry: -// X64-NEXT: [[RETVAL:%.*]] = alloca double, align 8 -// X64-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_post_dc.n, float 1.000000e+00 seq_cst, align 8 -// X64-NEXT: store float [[TMP0]], ptr [[RETVAL]], align 8 -// X64-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL]], align 8 -// X64-NEXT: ret double [[TMP1]] +// X64-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_post_dc.n, double 1.000000e+00 seq_cst, align 8 +// X64-NEXT: ret double [[TMP0]] // // X86-LABEL: define dso_local double @test_double_post_dc( // X86-SAME: ) #[[ATTR0]] { // X86-NEXT: entry: -// X86-NEXT: [[RETVAL:%.*]] = alloca double, align 4 -// X86-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_post_dc.n, float 1.000000e+00 seq_cst, align 8 -// X86-NEXT: store float [[TMP0]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL]], align 4 -// X86-NEXT: ret double [[TMP1]] +// X86-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_post_dc.n, double 1.000000e+00 seq_cst, align 8 +// X86-NEXT: ret double [[TMP0]] // double test_double_post_dc() { @@ -54,22 +42,16 @@ double test_double_post_dc() // X64-LABEL: define dso_local double @test_double_pre_dc( // X64-SAME: ) #[[ATTR0]] { // X64-NEXT: entry: -// X64-NEXT: [[RETVAL:%.*]] = alloca double, align 8 -// X64-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_pre_dc.n, float 1.000000e+00 seq_cst, align 8 -// X64-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 -// X64-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 8 -// X64-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL]], align 8 -// X64-NEXT: ret double [[TMP2]] +// X64-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_pre_dc.n, double 1.000000e+00 seq_cst, align 8 +// X64-NEXT: [[TMP1:%.*]] = fsub double [[TMP0]], 1.000000e+00 +// X64-NEXT: ret double [[TMP1]] // // X86-LABEL: define dso_local double @test_double_pre_dc( // X86-SAME: ) #[[ATTR0]] { // X86-NEXT: entry: -// X86-NEXT: [[RETVAL:%.*]] = alloca double, align 4 -// X86-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_pre_dc.n, float 1.000000e+00 seq_cst, align 8 -// X86-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 -// X86-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL]], align 4 -// X86-NEXT: ret double [[TMP2]] +// X86-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr @test_double_pre_dc.n, double 1.000000e+00 seq_cst, align 8 +// X86-NEXT: [[TMP1:%.*]] = fsub double [[TMP0]], 1.000000e+00 +// X86-NEXT: ret double [[TMP1]] // double test_double_pre_dc() { @@ -80,25 +62,43 @@ double test_double_pre_dc() // X64-LABEL: define dso_local double @test_double_pre_inc( // X64-SAME: ) #[[ATTR0]] { // X64-NEXT: entry: -// X64-NEXT: [[RETVAL:%.*]] = alloca double, align 8 -// X64-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_pre_inc.n, float 1.000000e+00 seq_cst, align 8 -// X64-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 -// X64-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 8 -// X64-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL]], align 8 -// X64-NEXT: ret double [[TMP2]] +// X64-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_pre_inc.n, double 1.000000e+00 seq_cst, align 8 +// X64-NEXT: [[TMP1:%.*]] = fadd double [[TMP0]], 1.000000e+00 +// X64-NEXT: ret double [[TMP1]] // // X86-LABEL: define dso_local double @test_double_pre_inc( // X86-SAME: ) #[[ATTR0]] { // X86-NEXT: entry: -// X86-NEXT: [[RETVAL:%.*]] = alloca double, align 4 -// X86-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_pre_inc.n, float 1.000000e+00 seq_cst, align 8 -// X86-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 -// X86-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL]], align 4 -// X86-NEXT: ret double [[TMP2]] +// X86-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @test_double_pre_inc.n, double 1.000000e+00 seq_cst, align 8 +// X86-NEXT: [[TMP1:%.*]] = fadd double [[TMP0]], 1.000000e+00 +// X86-NEXT: ret double [[TMP1]] // double test_double_pre_inc() { static _Atomic double n; return ++n; } + +// X64-LABEL: define dso_local i32 @pr107054( +// X64-SAME: ) #[[ATTR0]] { +// X64-NEXT: entry: +// X64-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @pr107054.n, double 1.000000e+00 seq_cst, align 8 +// X64-NEXT: [[TMP1:%.*]] = fadd double [[TMP0]], 1.000000e+00 +// X64-NEXT: [[CMP:%.*]] = fcmp oeq double [[TMP1]], 1.000000e+00 +// X64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 +// X64-NEXT: ret i32 [[CONV]] +// +// X86-LABEL: define dso_local i32 @pr107054( +// X86-SAME: ) #[[ATTR0]] { +// X86-NEXT: entry: +// X86-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @pr107054.n, double 1.000000e+00 seq_cst, align 8 +// X86-NEXT: [[TMP1:%.*]] = fadd double [[TMP0]], 1.000000e+00 +// X86-NEXT: [[CMP:%.*]] = fcmp oeq double [[TMP1]], 1.000000e+00 +// X86-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 +// X86-NEXT: ret i32 [[CONV]] +// +int pr107054() +{ + static _Atomic double n; + return (++n) == 1; +} diff --git a/clang/test/CodeGen/X86/x86-atomic-long_double.c b/clang/test/CodeGen/X86/x86-atomic-long_double.c index 2c3f381f13511..9c82784807dac 100644 --- a/clang/test/CodeGen/X86/x86-atomic-long_double.c +++ b/clang/test/CodeGen/X86/x86-atomic-long_double.c @@ -4,29 +4,60 @@ // X64-LABEL: define dso_local x86_fp80 @testinc( // X64-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0:[0-9]+]] { -// X64-NEXT: [[ENTRY:.*:]] -// X64-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ENTRY:.*]]: // X64-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 8 +// X64-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP3:%.*]] = alloca x86_fp80, align 16 // X64-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 8 // X64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 8 -// X64-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr [[TMP0]], float 1.000000e+00 seq_cst, align 16 -// X64-NEXT: [[TMP2:%.*]] = fadd float [[TMP1]], 1.000000e+00 -// X64-NEXT: store float [[TMP2]], ptr [[RETVAL]], align 16 -// X64-NEXT: [[TMP3:%.*]] = load x86_fp80, ptr [[RETVAL]], align 16 -// X64-NEXT: ret x86_fp80 [[TMP3]] +// X64-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic i128, ptr [[TMP0]] seq_cst, align 16 +// X64-NEXT: store i128 [[ATOMIC_LOAD]], ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: br label %[[ATOMIC_OP:.*]] +// X64: [[ATOMIC_OP]]: +// X64-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP8:%.*]], %[[ATOMIC_OP]] ] +// X64-NEXT: [[INC:%.*]] = fadd x86_fp80 [[TMP2]], 0xK3FFF8000000000000000 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP1]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: [[TMP3:%.*]] = load i128, ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP2]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[INC]], ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP4:%.*]] = load i128, ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[TMP0]], i128 [[TMP3]], i128 [[TMP4]] seq_cst seq_cst, align 16 +// X64-NEXT: [[TMP6:%.*]] = extractvalue { i128, i1 } [[TMP5]], 0 +// X64-NEXT: [[TMP7:%.*]] = extractvalue { i128, i1 } [[TMP5]], 1 +// X64-NEXT: store i128 [[TMP6]], ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: [[TMP8]] = load x86_fp80, ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: br i1 [[TMP7]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X64: [[ATOMIC_CONT]]: +// X64-NEXT: ret x86_fp80 [[INC]] // // X86-LABEL: define dso_local x86_fp80 @testinc( // X86-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0:[0-9]+]] { -// X86-NEXT: [[ENTRY:.*:]] -// X86-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ENTRY:.*]]: // X86-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 4 +// X86-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 4 // X86-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 4 // X86-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 4 -// X86-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr [[TMP0]], float 1.000000e+00 seq_cst, align 4 -// X86-NEXT: [[TMP2:%.*]] = fadd float [[TMP1]], 1.000000e+00 -// X86-NEXT: store float [[TMP2]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP3:%.*]] = load x86_fp80, ptr [[RETVAL]], align 4 -// X86-NEXT: ret x86_fp80 [[TMP3]] +// X86-NEXT: call void @__atomic_load(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP]], i32 noundef 5) +// X86-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 4 +// X86-NEXT: br label %[[ATOMIC_OP:.*]] +// X86: [[ATOMIC_OP]]: +// X86-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP3:%.*]], %[[ATOMIC_OP]] ] +// X86-NEXT: [[INC:%.*]] = fadd x86_fp80 [[TMP2]], 0xK3FFF8000000000000000 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP1]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP2]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[INC]], ptr [[ATOMIC_TEMP2]], align 4 +// X86-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP1]], ptr noundef [[ATOMIC_TEMP2]], i32 noundef 5, i32 noundef 5) +// X86-NEXT: [[TMP3]] = load x86_fp80, ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: br i1 [[CALL]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X86: [[ATOMIC_CONT]]: +// X86-NEXT: ret x86_fp80 [[INC]] // long double testinc(_Atomic long double *addr) { @@ -35,27 +66,60 @@ long double testinc(_Atomic long double *addr) { // X64-LABEL: define dso_local x86_fp80 @testdec( // X64-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0]] { -// X64-NEXT: [[ENTRY:.*:]] -// X64-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ENTRY:.*]]: // X64-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 8 +// X64-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP3:%.*]] = alloca x86_fp80, align 16 // X64-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 8 // X64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 8 -// X64-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr [[TMP0]], float 1.000000e+00 seq_cst, align 16 -// X64-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 16 -// X64-NEXT: [[TMP2:%.*]] = load x86_fp80, ptr [[RETVAL]], align 16 -// X64-NEXT: ret x86_fp80 [[TMP2]] +// X64-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic i128, ptr [[TMP0]] seq_cst, align 16 +// X64-NEXT: store i128 [[ATOMIC_LOAD]], ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: br label %[[ATOMIC_OP:.*]] +// X64: [[ATOMIC_OP]]: +// X64-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP8:%.*]], %[[ATOMIC_OP]] ] +// X64-NEXT: [[DEC:%.*]] = fadd x86_fp80 [[TMP2]], 0xKBFFF8000000000000000 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP1]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: [[TMP3:%.*]] = load i128, ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP2]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[DEC]], ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP4:%.*]] = load i128, ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[TMP0]], i128 [[TMP3]], i128 [[TMP4]] seq_cst seq_cst, align 16 +// X64-NEXT: [[TMP6:%.*]] = extractvalue { i128, i1 } [[TMP5]], 0 +// X64-NEXT: [[TMP7:%.*]] = extractvalue { i128, i1 } [[TMP5]], 1 +// X64-NEXT: store i128 [[TMP6]], ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: [[TMP8]] = load x86_fp80, ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: br i1 [[TMP7]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X64: [[ATOMIC_CONT]]: +// X64-NEXT: ret x86_fp80 [[TMP1]] // // X86-LABEL: define dso_local x86_fp80 @testdec( // X86-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0]] { -// X86-NEXT: [[ENTRY:.*:]] -// X86-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ENTRY:.*]]: // X86-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 4 +// X86-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 4 // X86-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 4 // X86-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 4 -// X86-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr [[TMP0]], float 1.000000e+00 seq_cst, align 4 -// X86-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP2:%.*]] = load x86_fp80, ptr [[RETVAL]], align 4 -// X86-NEXT: ret x86_fp80 [[TMP2]] +// X86-NEXT: call void @__atomic_load(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP]], i32 noundef 5) +// X86-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 4 +// X86-NEXT: br label %[[ATOMIC_OP:.*]] +// X86: [[ATOMIC_OP]]: +// X86-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP3:%.*]], %[[ATOMIC_OP]] ] +// X86-NEXT: [[DEC:%.*]] = fadd x86_fp80 [[TMP2]], 0xKBFFF8000000000000000 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP1]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP2]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[DEC]], ptr [[ATOMIC_TEMP2]], align 4 +// X86-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP1]], ptr noundef [[ATOMIC_TEMP2]], i32 noundef 5, i32 noundef 5) +// X86-NEXT: [[TMP3]] = load x86_fp80, ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: br i1 [[CALL]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X86: [[ATOMIC_CONT]]: +// X86-NEXT: ret x86_fp80 [[TMP1]] // long double testdec(_Atomic long double *addr) { @@ -175,29 +239,60 @@ long double testassign(_Atomic long double *addr) { // X64-LABEL: define dso_local x86_fp80 @test_volatile_inc( // X64-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0]] { -// X64-NEXT: [[ENTRY:.*:]] -// X64-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ENTRY:.*]]: // X64-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 8 +// X64-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP3:%.*]] = alloca x86_fp80, align 16 // X64-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 8 // X64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 8 -// X64-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr [[TMP0]], float 1.000000e+00 seq_cst, align 16 -// X64-NEXT: [[TMP2:%.*]] = fadd float [[TMP1]], 1.000000e+00 -// X64-NEXT: store float [[TMP2]], ptr [[RETVAL]], align 16 -// X64-NEXT: [[TMP3:%.*]] = load x86_fp80, ptr [[RETVAL]], align 16 -// X64-NEXT: ret x86_fp80 [[TMP3]] +// X64-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic volatile i128, ptr [[TMP0]] seq_cst, align 16 +// X64-NEXT: store i128 [[ATOMIC_LOAD]], ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: br label %[[ATOMIC_OP:.*]] +// X64: [[ATOMIC_OP]]: +// X64-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP8:%.*]], %[[ATOMIC_OP]] ] +// X64-NEXT: [[INC:%.*]] = fadd x86_fp80 [[TMP2]], 0xK3FFF8000000000000000 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP1]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: [[TMP3:%.*]] = load i128, ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP2]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[INC]], ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP4:%.*]] = load i128, ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP5:%.*]] = cmpxchg volatile ptr [[TMP0]], i128 [[TMP3]], i128 [[TMP4]] seq_cst seq_cst, align 16 +// X64-NEXT: [[TMP6:%.*]] = extractvalue { i128, i1 } [[TMP5]], 0 +// X64-NEXT: [[TMP7:%.*]] = extractvalue { i128, i1 } [[TMP5]], 1 +// X64-NEXT: store i128 [[TMP6]], ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: [[TMP8]] = load x86_fp80, ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: br i1 [[TMP7]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X64: [[ATOMIC_CONT]]: +// X64-NEXT: ret x86_fp80 [[INC]] // // X86-LABEL: define dso_local x86_fp80 @test_volatile_inc( // X86-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0]] { -// X86-NEXT: [[ENTRY:.*:]] -// X86-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ENTRY:.*]]: // X86-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 4 +// X86-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 4 // X86-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 4 // X86-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 4 -// X86-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr [[TMP0]], float 1.000000e+00 seq_cst, align 4 -// X86-NEXT: [[TMP2:%.*]] = fadd float [[TMP1]], 1.000000e+00 -// X86-NEXT: store float [[TMP2]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP3:%.*]] = load x86_fp80, ptr [[RETVAL]], align 4 -// X86-NEXT: ret x86_fp80 [[TMP3]] +// X86-NEXT: call void @__atomic_load(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP]], i32 noundef 5) +// X86-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 4 +// X86-NEXT: br label %[[ATOMIC_OP:.*]] +// X86: [[ATOMIC_OP]]: +// X86-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP3:%.*]], %[[ATOMIC_OP]] ] +// X86-NEXT: [[INC:%.*]] = fadd x86_fp80 [[TMP2]], 0xK3FFF8000000000000000 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP1]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP2]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[INC]], ptr [[ATOMIC_TEMP2]], align 4 +// X86-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP1]], ptr noundef [[ATOMIC_TEMP2]], i32 noundef 5, i32 noundef 5) +// X86-NEXT: [[TMP3]] = load x86_fp80, ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: br i1 [[CALL]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X86: [[ATOMIC_CONT]]: +// X86-NEXT: ret x86_fp80 [[INC]] // long double test_volatile_inc(volatile _Atomic long double *addr) { return ++*addr; @@ -205,27 +300,60 @@ long double test_volatile_inc(volatile _Atomic long double *addr) { // X64-LABEL: define dso_local x86_fp80 @test_volatile_dec( // X64-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0]] { -// X64-NEXT: [[ENTRY:.*:]] -// X64-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ENTRY:.*]]: // X64-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 8 +// X64-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP3:%.*]] = alloca x86_fp80, align 16 // X64-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 8 // X64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 8 -// X64-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr [[TMP0]], float 1.000000e+00 seq_cst, align 16 -// X64-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 16 -// X64-NEXT: [[TMP2:%.*]] = load x86_fp80, ptr [[RETVAL]], align 16 -// X64-NEXT: ret x86_fp80 [[TMP2]] +// X64-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic volatile i128, ptr [[TMP0]] seq_cst, align 16 +// X64-NEXT: store i128 [[ATOMIC_LOAD]], ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: br label %[[ATOMIC_OP:.*]] +// X64: [[ATOMIC_OP]]: +// X64-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP8:%.*]], %[[ATOMIC_OP]] ] +// X64-NEXT: [[DEC:%.*]] = fadd x86_fp80 [[TMP2]], 0xKBFFF8000000000000000 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP1]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: [[TMP3:%.*]] = load i128, ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP2]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[DEC]], ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP4:%.*]] = load i128, ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP5:%.*]] = cmpxchg volatile ptr [[TMP0]], i128 [[TMP3]], i128 [[TMP4]] seq_cst seq_cst, align 16 +// X64-NEXT: [[TMP6:%.*]] = extractvalue { i128, i1 } [[TMP5]], 0 +// X64-NEXT: [[TMP7:%.*]] = extractvalue { i128, i1 } [[TMP5]], 1 +// X64-NEXT: store i128 [[TMP6]], ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: [[TMP8]] = load x86_fp80, ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: br i1 [[TMP7]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X64: [[ATOMIC_CONT]]: +// X64-NEXT: ret x86_fp80 [[TMP1]] // // X86-LABEL: define dso_local x86_fp80 @test_volatile_dec( // X86-SAME: ptr noundef [[ADDR:%.*]]) #[[ATTR0]] { -// X86-NEXT: [[ENTRY:.*:]] -// X86-NEXT: [[RETVAL:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ENTRY:.*]]: // X86-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr, align 4 +// X86-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 4 // X86-NEXT: store ptr [[ADDR]], ptr [[ADDR_ADDR]], align 4 // X86-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ADDR_ADDR]], align 4 -// X86-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr [[TMP0]], float 1.000000e+00 seq_cst, align 4 -// X86-NEXT: store float [[TMP1]], ptr [[RETVAL]], align 4 -// X86-NEXT: [[TMP2:%.*]] = load x86_fp80, ptr [[RETVAL]], align 4 -// X86-NEXT: ret x86_fp80 [[TMP2]] +// X86-NEXT: call void @__atomic_load(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP]], i32 noundef 5) +// X86-NEXT: [[TMP1:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 4 +// X86-NEXT: br label %[[ATOMIC_OP:.*]] +// X86: [[ATOMIC_OP]]: +// X86-NEXT: [[TMP2:%.*]] = phi x86_fp80 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP3:%.*]], %[[ATOMIC_OP]] ] +// X86-NEXT: [[DEC:%.*]] = fadd x86_fp80 [[TMP2]], 0xKBFFF8000000000000000 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP1]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[TMP2]], ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP2]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[DEC]], ptr [[ATOMIC_TEMP2]], align 4 +// X86-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i32 noundef 12, ptr noundef [[TMP0]], ptr noundef [[ATOMIC_TEMP1]], ptr noundef [[ATOMIC_TEMP2]], i32 noundef 5, i32 noundef 5) +// X86-NEXT: [[TMP3]] = load x86_fp80, ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: br i1 [[CALL]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X86: [[ATOMIC_CONT]]: +// X86-NEXT: ret x86_fp80 [[TMP1]] // long double test_volatile_dec(volatile _Atomic long double *addr) { return (*addr)--; @@ -341,3 +469,64 @@ long double test_volatile_assign(volatile _Atomic long double *addr) { return *addr; } + +// X64-LABEL: define dso_local i32 @pr107054( +// X64-SAME: ) #[[ATTR0]] { +// X64-NEXT: [[ENTRY:.*]]: +// X64-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_TEMP3:%.*]] = alloca x86_fp80, align 16 +// X64-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic i128, ptr @pr107054.n seq_cst, align 16 +// X64-NEXT: store i128 [[ATOMIC_LOAD]], ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 16 +// X64-NEXT: br label %[[ATOMIC_OP:.*]] +// X64: [[ATOMIC_OP]]: +// X64-NEXT: [[TMP1:%.*]] = phi x86_fp80 [ [[TMP0]], %[[ENTRY]] ], [ [[TMP7:%.*]], %[[ATOMIC_OP]] ] +// X64-NEXT: [[INC:%.*]] = fadd x86_fp80 [[TMP1]], 0xK3FFF8000000000000000 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP1]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[TMP1]], ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: [[TMP2:%.*]] = load i128, ptr [[ATOMIC_TEMP1]], align 16 +// X64-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ATOMIC_TEMP2]], i8 0, i64 16, i1 false) +// X64-NEXT: store x86_fp80 [[INC]], ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP3:%.*]] = load i128, ptr [[ATOMIC_TEMP2]], align 16 +// X64-NEXT: [[TMP4:%.*]] = cmpxchg ptr @pr107054.n, i128 [[TMP2]], i128 [[TMP3]] seq_cst seq_cst, align 16 +// X64-NEXT: [[TMP5:%.*]] = extractvalue { i128, i1 } [[TMP4]], 0 +// X64-NEXT: [[TMP6:%.*]] = extractvalue { i128, i1 } [[TMP4]], 1 +// X64-NEXT: store i128 [[TMP5]], ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: [[TMP7]] = load x86_fp80, ptr [[ATOMIC_TEMP3]], align 16 +// X64-NEXT: br i1 [[TMP6]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X64: [[ATOMIC_CONT]]: +// X64-NEXT: [[CMP:%.*]] = fcmp oeq x86_fp80 [[INC]], 0xK3FFF8000000000000000 +// X64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 +// X64-NEXT: ret i32 [[CONV]] +// +// X86-LABEL: define dso_local i32 @pr107054( +// X86-SAME: ) #[[ATTR0]] { +// X86-NEXT: [[ENTRY:.*]]: +// X86-NEXT: [[ATOMIC_TEMP:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: [[ATOMIC_TEMP2:%.*]] = alloca x86_fp80, align 4 +// X86-NEXT: call void @__atomic_load(i32 noundef 12, ptr noundef @pr107054.n, ptr noundef [[ATOMIC_TEMP]], i32 noundef 5) +// X86-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[ATOMIC_TEMP]], align 4 +// X86-NEXT: br label %[[ATOMIC_OP:.*]] +// X86: [[ATOMIC_OP]]: +// X86-NEXT: [[TMP1:%.*]] = phi x86_fp80 [ [[TMP0]], %[[ENTRY]] ], [ [[TMP2:%.*]], %[[ATOMIC_OP]] ] +// X86-NEXT: [[INC:%.*]] = fadd x86_fp80 [[TMP1]], 0xK3FFF8000000000000000 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP1]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[TMP1]], ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ATOMIC_TEMP2]], i8 0, i64 12, i1 false) +// X86-NEXT: store x86_fp80 [[INC]], ptr [[ATOMIC_TEMP2]], align 4 +// X86-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i32 noundef 12, ptr noundef @pr107054.n, ptr noundef [[ATOMIC_TEMP1]], ptr noundef [[ATOMIC_TEMP2]], i32 noundef 5, i32 noundef 5) +// X86-NEXT: [[TMP2]] = load x86_fp80, ptr [[ATOMIC_TEMP1]], align 4 +// X86-NEXT: br i1 [[CALL]], label %[[ATOMIC_CONT:.*]], label %[[ATOMIC_OP]] +// X86: [[ATOMIC_CONT]]: +// X86-NEXT: [[CMP:%.*]] = fcmp oeq x86_fp80 [[INC]], 0xK3FFF8000000000000000 +// X86-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 +// X86-NEXT: ret i32 [[CONV]] +// +int pr107054() +{ + static _Atomic long double n; + return (++n) == 1; +} diff --git a/clang/test/CodeGen/aarch64-neon-luti.c b/clang/test/CodeGen/aarch64-neon-luti.c new file mode 100644 index 0000000000000..4b485636d45b1 --- /dev/null +++ b/clang/test/CodeGen/aarch64-neon-luti.c @@ -0,0 +1,507 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// REQUIRES: aarch64-registered-target +#include +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +lut -target-feature +bf16 -O3 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +lut -target-feature +bf16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2_lane_u8( +// CHECK-SAME: <8 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.lane.v16i8.v8i8(<8 x i8> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANE]] +// +uint8x16_t test_vluti2_lane_u8(uint8x8_t vn, uint8x8_t vm) { + return vluti2_lane_u8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2_laneq_u8( +// CHECK-SAME: <8 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.laneq.v16i8.v8i8(<8 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANEQ]] +// +uint8x16_t test_vluti2_laneq_u8(uint8x8_t vn, uint8x16_t vm) { + return vluti2_laneq_u8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2q_lane_u8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.lane.v16i8.v16i8(<16 x i8> [[VN]], <8 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANE]] +// +uint8x16_t test_vluti2q_lane_u8(uint8x16_t vn, uint8x8_t vm) { + return vluti2q_lane_u8(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2q_laneq_u8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.laneq.v16i8.v16i8(<16 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANEQ]] +// +uint8x16_t test_vluti2q_laneq_u8(uint8x16_t vn, uint8x16_t vm) { + return vluti2q_laneq_u8(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2_lane_s8( +// CHECK-SAME: <8 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.lane.v16i8.v8i8(<8 x i8> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANE]] +// +int8x16_t test_vluti2_lane_s8(int8x8_t vn, uint8x8_t vm) { + return vluti2_lane_s8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2_laneq_s8( +// CHECK-SAME: <8 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.laneq.v16i8.v8i8(<8 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANEQ]] +// +int8x16_t test_vluti2_laneq_s8(int8x8_t vn, uint8x16_t vm) { + return vluti2_laneq_s8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2q_lane_s8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.lane.v16i8.v16i8(<16 x i8> [[VN]], <8 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANE]] +// +int8x16_t test_vluti2q_lane_s8(int8x16_t vn, uint8x8_t vm) { + return vluti2q_lane_s8(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2q_laneq_s8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.laneq.v16i8.v16i8(<16 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANEQ]] +// +int8x16_t test_vluti2q_laneq_s8(int8x16_t vn, uint8x16_t vm) { + return vluti2q_laneq_s8(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2_lane_p8( +// CHECK-SAME: <8 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.lane.v16i8.v8i8(<8 x i8> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANE]] +// +poly8x16_t test_vluti2_lane_p8(poly8x8_t vn, uint8x8_t vm) { + return vluti2_lane_p8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2_laneq_p8( +// CHECK-SAME: <8 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.laneq.v16i8.v8i8(<8 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANEQ]] +// +poly8x16_t test_vluti2_laneq_p8(poly8x8_t vn, uint8x16_t vm) { + return vluti2_laneq_p8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2q_lane_p8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.lane.v16i8.v16i8(<16 x i8> [[VN]], <8 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANE]] +// +poly8x16_t test_vluti2q_lane_p8(poly8x16_t vn, uint8x8_t vm) { + return vluti2q_lane_p8(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti2q_laneq_p8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti2.laneq.v16i8.v16i8(<16 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <16 x i8> [[VLUTI2_LANEQ]] +// +poly8x16_t test_vluti2q_laneq_p8(poly8x16_t vn, uint8x16_t vm) { + return vluti2q_laneq_p8(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2_lane_u16( +// CHECK-SAME: <4 x i16> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.lane.v8i16.v4i16(<4 x i16> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANE1]] +// +uint16x8_t test_vluti2_lane_u16(uint16x4_t vn, uint8x8_t vm) { + return vluti2_lane_u16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2_laneq_u16( +// CHECK-SAME: <4 x i16> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.laneq.v8i16.v4i16(<4 x i16> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANEQ1]] +// +uint16x8_t test_vluti2_laneq_u16(uint16x4_t vn, uint8x16_t vm) { + return vluti2_laneq_u16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2q_lane_u16( +// CHECK-SAME: <8 x i16> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.lane.v8i16.v8i16(<8 x i16> [[VN]], <8 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANE1]] +// +uint16x8_t test_vluti2q_lane_u16(uint16x8_t vn, uint8x8_t vm) { + return vluti2q_lane_u16(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2q_laneq_u16( +// CHECK-SAME: <8 x i16> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.laneq.v8i16.v8i16(<8 x i16> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANEQ1]] +// +uint16x8_t test_vluti2q_laneq_u16(uint16x8_t vn, uint8x16_t vm) { + return vluti2q_laneq_u16(vn, vm, 7); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2_lane_s16( +// CHECK-SAME: <4 x i16> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.lane.v8i16.v4i16(<4 x i16> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANE1]] +// +int16x8_t test_vluti2_lane_s16(int16x4_t vn, uint8x8_t vm) { + return vluti2_lane_s16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2_laneq_s16( +// CHECK-SAME: <4 x i16> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.laneq.v8i16.v4i16(<4 x i16> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANEQ1]] +// +int16x8_t test_vluti2_laneq_s16(int16x4_t vn, uint8x16_t vm) { + return vluti2_laneq_s16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2q_lane_s16( +// CHECK-SAME: <8 x i16> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.lane.v8i16.v8i16(<8 x i16> [[VN]], <8 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANE1]] +// +int16x8_t test_vluti2q_lane_s16(int16x8_t vn, uint8x8_t vm) { + return vluti2q_lane_s16(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2q_laneq_s16( +// CHECK-SAME: <8 x i16> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.laneq.v8i16.v8i16(<8 x i16> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANEQ1]] +// +int16x8_t test_vluti2q_laneq_s16(int16x8_t vn, uint8x16_t vm) { + return vluti2q_laneq_s16(vn, vm, 7); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vluti2_lane_f16( +// CHECK-SAME: <4 x half> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vluti2.lane.v8f16.v4f16(<4 x half> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x half> [[VLUTI2_LANE1]] +// +float16x8_t test_vluti2_lane_f16(float16x4_t vn, uint8x8_t vm) { + return vluti2_lane_f16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vluti2_laneq_f16( +// CHECK-SAME: <4 x half> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vluti2.laneq.v8f16.v4f16(<4 x half> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x half> [[VLUTI2_LANEQ1]] +// +float16x8_t test_vluti2_laneq_f16(float16x4_t vn, uint8x16_t vm) { + return vluti2_laneq_f16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vluti2q_lane_f16( +// CHECK-SAME: <8 x half> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vluti2.lane.v8f16.v8f16(<8 x half> [[VN]], <8 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <8 x half> [[VLUTI2_LANE1]] +// +float16x8_t test_vluti2q_lane_f16(float16x8_t vn, uint8x8_t vm) { + return vluti2q_lane_f16(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vluti2q_laneq_f16( +// CHECK-SAME: <8 x half> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vluti2.laneq.v8f16.v8f16(<8 x half> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <8 x half> [[VLUTI2_LANEQ1]] +// +float16x8_t test_vluti2q_laneq_f16(float16x8_t vn, uint8x16_t vm) { + return vluti2q_laneq_f16(vn, vm, 7); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vluti2_lane_bf16( +// CHECK-SAME: <4 x bfloat> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x bfloat> @llvm.aarch64.neon.vluti2.lane.v8bf16.v4bf16(<4 x bfloat> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x bfloat> [[VLUTI2_LANE1]] +// +bfloat16x8_t test_vluti2_lane_bf16(bfloat16x4_t vn, uint8x8_t vm) { + return vluti2_lane_bf16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vluti2_laneq_bf16( +// CHECK-SAME: <4 x bfloat> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x bfloat> @llvm.aarch64.neon.vluti2.laneq.v8bf16.v4bf16(<4 x bfloat> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x bfloat> [[VLUTI2_LANEQ1]] +// +bfloat16x8_t test_vluti2_laneq_bf16(bfloat16x4_t vn, uint8x16_t vm) { + return vluti2_laneq_bf16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vluti2q_lane_bf16( +// CHECK-SAME: <8 x bfloat> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x bfloat> @llvm.aarch64.neon.vluti2.lane.v8bf16.v8bf16(<8 x bfloat> [[VN]], <8 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <8 x bfloat> [[VLUTI2_LANE1]] +// +bfloat16x8_t test_vluti2q_lane_bf16(bfloat16x8_t vn, uint8x8_t vm) { + return vluti2q_lane_bf16(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vluti2q_laneq_bf16( +// CHECK-SAME: <8 x bfloat> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x bfloat> @llvm.aarch64.neon.vluti2.laneq.v8bf16.v8bf16(<8 x bfloat> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <8 x bfloat> [[VLUTI2_LANEQ1]] +// +bfloat16x8_t test_vluti2q_laneq_bf16(bfloat16x8_t vn, uint8x16_t vm) { + return vluti2q_laneq_bf16(vn, vm, 7); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2_lane_p16( +// CHECK-SAME: <4 x i16> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.lane.v8i16.v4i16(<4 x i16> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANE1]] +// +poly16x8_t test_vluti2_lane_p16(poly16x4_t vn, uint8x8_t vm) { + return vluti2_lane_p16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2_laneq_p16( +// CHECK-SAME: <4 x i16> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.laneq.v8i16.v4i16(<4 x i16> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANEQ1]] +// +poly16x8_t test_vluti2_laneq_p16(poly16x4_t vn, uint8x16_t vm) { + return vluti2_laneq_p16(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2q_lane_p16( +// CHECK-SAME: <8 x i16> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANE1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.lane.v8i16.v8i16(<8 x i16> [[VN]], <8 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANE1]] +// +poly16x8_t test_vluti2q_lane_p16(poly16x8_t vn, uint8x8_t vm) { + return vluti2q_lane_p16(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti2q_laneq_p16( +// CHECK-SAME: <8 x i16> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI2_LANEQ1:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti2.laneq.v8i16.v8i16(<8 x i16> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <8 x i16> [[VLUTI2_LANEQ1]] +// +poly16x8_t test_vluti2q_laneq_p16(poly16x8_t vn, uint8x16_t vm) { + return vluti2q_laneq_p16(vn, vm, 7); +} + +// + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti4q_lane_u8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI4Q_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti4q.lane.v16i8(<16 x i8> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI4Q_LANE]] +// +uint8x16_t test_vluti4q_lane_u8(uint8x16_t vn, uint8x8_t vm) { + return vluti4q_lane_u8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti4q_laneq_u8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI4Q_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti4q.laneq.v16i8(<16 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI4Q_LANEQ]] +// +uint8x16_t test_vluti4q_laneq_u8(uint8x16_t vn, uint8x16_t vm) { + return vluti4q_laneq_u8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti4q_lane_s8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI4Q_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti4q.lane.v16i8(<16 x i8> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI4Q_LANE]] +// +int8x16_t test_vluti4q_lane_s8(int8x16_t vn, uint8x8_t vm) { + return vluti4q_lane_s8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti4q_laneq_s8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI4Q_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti4q.laneq.v16i8(<16 x i8> [[VN]], <16 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <16 x i8> [[VLUTI4Q_LANEQ]] +// +int8x16_t test_vluti4q_laneq_s8(int8x16_t vn, uint8x16_t vm) { + return vluti4q_laneq_s8(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti4q_lane_p8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI4Q_LANE:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti4q.lane.v16i8(<16 x i8> [[VN]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <16 x i8> [[VLUTI4Q_LANE]] +// +poly8x16_t test_vluti4q_lane_p8(poly8x16_t vn, uint8x8_t vm) { + return vluti4q_lane_p8(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vluti4q_laneq_p8( +// CHECK-SAME: <16 x i8> noundef [[VN:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VLUTI4Q_LANEQ:%.*]] = tail call <16 x i8> @llvm.aarch64.neon.vluti4q.laneq.v16i8(<16 x i8> [[VN]], <16 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <16 x i8> [[VLUTI4Q_LANEQ]] +// +poly8x16_t test_vluti4q_laneq_p8(poly8x16_t vn, uint8x16_t vm) { + return vluti4q_laneq_p8(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti4q_lane_u16_x2( +// CHECK-SAME: [2 x <8 x i16>] alignstack(16) [[VN_COERCE:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANE_X24:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti4q.lane.x2.v8i16(<8 x i16> [[VN_COERCE_FCA_0_EXTRACT]], <8 x i16> [[VN_COERCE_FCA_1_EXTRACT]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI4Q_LANE_X24]] +// +uint16x8_t test_vluti4q_lane_u16_x2(uint16x8x2_t vn, uint8x8_t vm) { + return vluti4q_lane_u16_x2(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti4q_laneq_u16_x2( +// CHECK-SAME: [2 x <8 x i16>] alignstack(16) [[VN_COERCE:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANEQ_X24:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti4q.laneq.x2.v8i16(<8 x i16> [[VN_COERCE_FCA_0_EXTRACT]], <8 x i16> [[VN_COERCE_FCA_1_EXTRACT]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI4Q_LANEQ_X24]] +// +uint16x8_t test_vluti4q_laneq_u16_x2(uint16x8x2_t vn, uint8x16_t vm) { + return vluti4q_laneq_u16_x2(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti4q_lane_s16_x2( +// CHECK-SAME: [2 x <8 x i16>] alignstack(16) [[VN_COERCE:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANE_X24:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti4q.lane.x2.v8i16(<8 x i16> [[VN_COERCE_FCA_0_EXTRACT]], <8 x i16> [[VN_COERCE_FCA_1_EXTRACT]], <8 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <8 x i16> [[VLUTI4Q_LANE_X24]] +// +int16x8_t test_vluti4q_lane_s16_x2(int16x8x2_t vn, uint8x8_t vm) { + return vluti4q_lane_s16_x2(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti4q_laneq_s16_x2( +// CHECK-SAME: [2 x <8 x i16>] alignstack(16) [[VN_COERCE:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANEQ_X24:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti4q.laneq.x2.v8i16(<8 x i16> [[VN_COERCE_FCA_0_EXTRACT]], <8 x i16> [[VN_COERCE_FCA_1_EXTRACT]], <16 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <8 x i16> [[VLUTI4Q_LANEQ_X24]] +// +int16x8_t test_vluti4q_laneq_s16_x2(int16x8x2_t vn, uint8x16_t vm) { + return vluti4q_laneq_s16_x2(vn, vm, 3); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vluti4q_lane_f16_x2( +// CHECK-SAME: [2 x <8 x half>] alignstack(16) [[VN_COERCE:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x half>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x half>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANE_X24:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vluti4q.lane.x2.v8f16(<8 x half> [[VN_COERCE_FCA_0_EXTRACT]], <8 x half> [[VN_COERCE_FCA_1_EXTRACT]], <8 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <8 x half> [[VLUTI4Q_LANE_X24]] +// +float16x8_t test_vluti4q_lane_f16_x2(float16x8x2_t vn, uint8x8_t vm) { + return vluti4q_lane_f16_x2(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vluti4q_laneq_f16_x2( +// CHECK-SAME: [2 x <8 x half>] alignstack(16) [[VN_COERCE:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x half>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x half>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANEQ_X24:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vluti4q.laneq.x2.v8f16(<8 x half> [[VN_COERCE_FCA_0_EXTRACT]], <8 x half> [[VN_COERCE_FCA_1_EXTRACT]], <16 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <8 x half> [[VLUTI4Q_LANEQ_X24]] +// +float16x8_t test_vluti4q_laneq_f16_x2(float16x8x2_t vn, uint8x16_t vm) { + return vluti4q_laneq_f16_x2(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vluti4q_lane_bf16_x2( +// CHECK-SAME: [2 x <8 x bfloat>] alignstack(16) [[VN_COERCE:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x bfloat>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x bfloat>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANE_X24:%.*]] = tail call <8 x bfloat> @llvm.aarch64.neon.vluti4q.lane.x2.v8bf16(<8 x bfloat> [[VN_COERCE_FCA_0_EXTRACT]], <8 x bfloat> [[VN_COERCE_FCA_1_EXTRACT]], <8 x i8> [[VM]], i32 1) +// CHECK-NEXT: ret <8 x bfloat> [[VLUTI4Q_LANE_X24]] +// +bfloat16x8_t test_vluti4q_lane_bf16_x2(bfloat16x8x2_t vn, uint8x8_t vm) { + return vluti4q_lane_bf16_x2(vn, vm, 1); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vluti4q_laneq_bf16_x2( +// CHECK-SAME: [2 x <8 x bfloat>] alignstack(16) [[VN_COERCE:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x bfloat>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x bfloat>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANEQ_X24:%.*]] = tail call <8 x bfloat> @llvm.aarch64.neon.vluti4q.laneq.x2.v8bf16(<8 x bfloat> [[VN_COERCE_FCA_0_EXTRACT]], <8 x bfloat> [[VN_COERCE_FCA_1_EXTRACT]], <16 x i8> [[VM]], i32 2) +// CHECK-NEXT: ret <8 x bfloat> [[VLUTI4Q_LANEQ_X24]] +// +bfloat16x8_t test_vluti4q_laneq_bf16_x2(bfloat16x8x2_t vn, uint8x16_t vm) { + return vluti4q_laneq_bf16_x2(vn, vm, 2); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti4q_lane_p16_x2( +// CHECK-SAME: [2 x <8 x i16>] alignstack(16) [[VN_COERCE:%.*]], <8 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANE_X24:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti4q.lane.x2.v8i16(<8 x i16> [[VN_COERCE_FCA_0_EXTRACT]], <8 x i16> [[VN_COERCE_FCA_1_EXTRACT]], <8 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI4Q_LANE_X24]] +// +poly16x8_t test_vluti4q_lane_p16_x2(poly16x8x2_t vn, uint8x8_t vm) { + return vluti4q_lane_p16_x2(vn, vm, 0); +} + +// CHECK-LABEL: define dso_local <8 x i16> @test_vluti4q_laneq_p16_x2( +// CHECK-SAME: [2 x <8 x i16>] alignstack(16) [[VN_COERCE:%.*]], <16 x i8> noundef [[VM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VN_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 0 +// CHECK-NEXT: [[VN_COERCE_FCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x i16>] [[VN_COERCE]], 1 +// CHECK-NEXT: [[VLUTI4Q_LANEQ_X24:%.*]] = tail call <8 x i16> @llvm.aarch64.neon.vluti4q.laneq.x2.v8i16(<8 x i16> [[VN_COERCE_FCA_0_EXTRACT]], <8 x i16> [[VN_COERCE_FCA_1_EXTRACT]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x i16> [[VLUTI4Q_LANEQ_X24]] +// +poly16x8_t test_vluti4q_laneq_p16_x2(poly16x8x2_t vn, uint8x16_t vm) { + return vluti4q_laneq_p16_x2(vn, vm, 0); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_faminmax.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_faminmax.c new file mode 100644 index 0000000000000..5d026f8cde5e0 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_faminmax.c @@ -0,0 +1,476 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED) A1 +#else +#define SVE_ACLE_FUNC(A1,A2) A1##A2 +#endif + + +// Multi, x2 + +// CHECK-LABEL: @test_svamax_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famax.x2.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z18test_svamax_f16_x213svfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famax.x2.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat16x2_t test_svamax_f16_x2(svfloat16x2_t zdn, svfloat16x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamax,_f16_x2)(zdn, zm); +} + +// CHECK-LABEL: @test_svamax_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famax.x2.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z18test_svamax_f32_x213svfloat32x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famax.x2.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat32x2_t test_svamax_f32_x2(svfloat32x2_t zdn, svfloat32x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamax,_f32_x2)(zdn, zm); +} + +// CHECK-LABEL: @test_svamax_f64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM]], i64 2) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famax.x2.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z18test_svamax_f64_x213svfloat64x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM]], i64 2) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famax.x2.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat64x2_t test_svamax_f64_x2(svfloat64x2_t zdn, svfloat64x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamax,_f64_x2)(zdn, zm); +} + +// CHECK-LABEL: @test_svamin_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famin.x2.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z18test_svamin_f16_x213svfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famin.x2.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat16x2_t test_svamin_f16_x2(svfloat16x2_t zdn, svfloat16x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamin,_f16_x2)(zdn, zm); +} + +// CHECK-LABEL: @test_svamin_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famin.x2.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z18test_svamin_f32_x213svfloat32x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famin.x2.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat32x2_t test_svamin_f32_x2(svfloat32x2_t zdn, svfloat32x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamin,_f32_x2)(zdn, zm); +} + +// CHECK-LABEL: @test_svamin_f64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM]], i64 2) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famin.x2.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z18test_svamin_f64_x213svfloat64x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZM]], i64 2) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sme.famin.x2.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat64x2_t test_svamin_f64_x2(svfloat64x2_t zdn, svfloat64x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamin,_f64_x2)(zdn, zm); +} + +// Multi, x4 + +// CHECK-LABEL: @test_svamax_f16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 24) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famax.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 8) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP12]], [[TMP13]], i64 16) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP14]], [[TMP15]], i64 24) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z18test_svamax_f16_x413svfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famax.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 8) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP12]], [[TMP13]], i64 16) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP14]], [[TMP15]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svfloat16x4_t test_svamax_f16_x4(svfloat16x4_t zdn, svfloat16x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamax,_f16_x4)(zdn, zm); +} + +// CHECK-LABEL: @test_svamax_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 12) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famax.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 4) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP12]], [[TMP13]], i64 8) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP14]], [[TMP15]], i64 12) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z18test_svamax_f32_x413svfloat32x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 12) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famax.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 4) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP12]], [[TMP13]], i64 8) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP14]], [[TMP15]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svfloat32x4_t test_svamax_f32_x4(svfloat32x4_t zdn, svfloat32x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamax,_f32_x4)(zdn, zm); +} + +// CHECK-LABEL: @test_svamax_f64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 2) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 6) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famax.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 2) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP12]], [[TMP13]], i64 4) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP14]], [[TMP15]], i64 6) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z18test_svamax_f64_x413svfloat64x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 2) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 6) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famax.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 2) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP12]], [[TMP13]], i64 4) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP14]], [[TMP15]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svfloat64x4_t test_svamax_f64_x4(svfloat64x4_t zdn, svfloat64x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamax,_f64_x4)(zdn, zm); +} + +// CHECK-LABEL: @test_svamin_f16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 24) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famin.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 8) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP12]], [[TMP13]], i64 16) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP14]], [[TMP15]], i64 24) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z18test_svamin_f16_x413svfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZDN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famin.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 8) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP12]], [[TMP13]], i64 16) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP14]], [[TMP15]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svfloat16x4_t test_svamin_f16_x4(svfloat16x4_t zdn, svfloat16x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamin,_f16_x4)(zdn, zm); +} + +// CHECK-LABEL: @test_svamin_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 12) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famin.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 4) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP12]], [[TMP13]], i64 8) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP14]], [[TMP15]], i64 12) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z18test_svamin_f32_x413svfloat32x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZDN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZM]], i64 12) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famin.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 4) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP12]], [[TMP13]], i64 8) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP14]], [[TMP15]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svfloat32x4_t test_svamin_f32_x4(svfloat32x4_t zdn, svfloat32x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamin,_f32_x4)(zdn, zm); +} + +// CHECK-LABEL: @test_svamin_f64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 2) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 6) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famin.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 2) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP12]], [[TMP13]], i64 4) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP14]], [[TMP15]], i64 6) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z18test_svamin_f64_x413svfloat64x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZDN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 2) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZM]], i64 6) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sme.famin.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 2) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP12]], [[TMP13]], i64 4) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP14]], [[TMP15]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svfloat64x4_t test_svamin_f64_x4(svfloat64x4_t zdn, svfloat64x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svamin,_f64_x4)(zdn, zm); +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_faminmax.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_faminmax.c new file mode 100644 index 0000000000000..3cf7d99d606f3 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_faminmax.c @@ -0,0 +1,775 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-CPP +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-CPP +// RUN: %clang_cc1 -x c++ -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-CPP + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#ifdef __ARM_FEATURE_SME +#include "arm_sme.h" +#else +#include "arm_sve.h" +#endif + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +#ifdef __ARM_FEATURE_SME +#define STREAMING __arm_streaming +#else +#define STREAMING +#endif + +// CHECK-LABEL: define dso_local @test_famin_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f16_mu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_f16_m(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f16_xu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_f16_x(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f16_zu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famin_f16_z(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f16_mu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_n_f16_m(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f16_xu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_n_f16_x(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f16_zu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famin_n_f16_z(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f32_mu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_f32_m(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f32_xu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_f32_x(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f32_zu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famin_f32_z(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f32_mu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_n_f32_m(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f32_xu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_n_f32_x(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f32_zu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famin_n_f32_z(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f64_mu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_f64_m(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f64_xu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_f64_x(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f64_zu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famin_f64_z(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f64, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f64_mu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_n_f64_m(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f64_xu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_n_f64_x(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f64_zu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famin_n_f64_z(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f64, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f16_mu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_f16_m(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f16_xu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_f16_x(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f16_zu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famax_f16_z(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f16_mu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_n_f16_m(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f16_xu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_n_f16_x(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f16_zu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famax_n_f16_z(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f32_mu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_f32_m(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f32_xu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_f32_x(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f32_zu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famax_f32_z(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f32_mu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_n_f32_m(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f32_xu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_n_f32_x(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f32_zu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famax_n_f32_z(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f64_mu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_f64_m(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f64_xu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_f64_x(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f64_zu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famax_f64_z(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f64, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f64_mu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_n_f64_m(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f64_xu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_n_f64_x(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f64_zu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famax_n_f64_z(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f64, _z)(pg, a, b); +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_luti.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_luti.c new file mode 100644 index 0000000000000..60c4828c407e8 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_luti.c @@ -0,0 +1,337 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu \ +// RUN: -target-feature +sme -target-feature +sme2 -target-feature +lut -target-feature +bf16 -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu \ +// RUN: -target-feature +sve -target-feature +sve2 -target-feature +lut -target-feature +bf16 -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu \ +// RUN: -target-feature +sve -target-feature +sve2 -target-feature +lut -target-feature +bf16 -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu \ +// RUN: -target-feature +sve -target-feature +sve2 -target-feature +lut -target-feature +bf16 -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +lut -target-feature +bf16 -O1 -Werror -Wall -o /dev/null %s +#include + +#if defined __ARM_FEATURE_SME +#define MODE_ATTR __arm_streaming +#else +#define MODE_ATTR +#endif + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +// SME-CHECK-LABEL: @test_svluti2_lane_s8( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti2_lane_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z20test_svluti2_lane_s8u10__SVInt8_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svint8_t test_svluti2_lane_s8(svint8_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti2_lane,_s8,)(table, indices, 0); +} + +// SME-CHECK-LABEL: @test_svluti2_lane_u8( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 3) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti2_lane_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 3) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z20test_svluti2_lane_u8u11__SVUint8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 3) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svuint8_t test_svluti2_lane_u8(svuint8_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti2_lane,_u8,)(table, indices, 3); +} + +// SME-CHECK-LABEL: @test_svluti2_lane_s16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti2_lane_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z21test_svluti2_lane_s16u11__SVInt16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svint16_t test_svluti2_lane_s16(svint16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti2_lane,_s16,)(table, indices, 0); +} + +// SME-CHECK-LABEL: @test_svluti2_lane_u16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 7) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti2_lane_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z21test_svluti2_lane_u16u12__SVUint16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 7) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svuint16_t test_svluti2_lane_u16(svuint16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti2_lane,_u16,)(table, indices, 7); +} + +// SME-CHECK-LABEL: @test_svluti2_lane_f16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.nxv8f16( [[TABLE:%.*]], [[INDICES:%.*]], i32 5) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti2_lane_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8f16( [[TABLE:%.*]], [[INDICES:%.*]], i32 5) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z21test_svluti2_lane_f16u13__SVFloat16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8f16( [[TABLE:%.*]], [[INDICES:%.*]], i32 5) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svfloat16_t test_svluti2_lane_f16(svfloat16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti2_lane,_f16,)(table, indices, 5); +} + +// SME-CHECK-LABEL: @test_svluti2_lane_bf16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.nxv8bf16( [[TABLE:%.*]], [[INDICES:%.*]], i32 2) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti2_lane_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8bf16( [[TABLE:%.*]], [[INDICES:%.*]], i32 2) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z22test_svluti2_lane_bf16u14__SVBfloat16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti2.lane.nxv8bf16( [[TABLE:%.*]], [[INDICES:%.*]], i32 2) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svbfloat16_t test_svluti2_lane_bf16(svbfloat16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti2_lane,_bf16,)(table, indices, 2); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_s8( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti4_lane_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z20test_svluti4_lane_s8u10__SVInt8_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svint8_t test_svluti4_lane_s8(svint8_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_s8,)(table, indices, 0); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_u8( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 1) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti4_lane_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 1) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z20test_svluti4_lane_u8u11__SVUint8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv16i8( [[TABLE:%.*]], [[INDICES:%.*]], i32 1) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svuint8_t test_svluti4_lane_u8(svuint8_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_u8,)(table, indices, 1); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_s16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti4_lane_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z21test_svluti4_lane_s16u11__SVInt16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 0) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svint16_t test_svluti4_lane_s16(svint16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_s16,)(table, indices, 0); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_u16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 7) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti4_lane_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 3) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z21test_svluti4_lane_u16u12__SVUint16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8i16( [[TABLE:%.*]], [[INDICES:%.*]], i32 3) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svuint16_t test_svluti4_lane_u16(svuint16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_u16,)(table, indices, 3); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_f16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.nxv8f16( [[TABLE:%.*]], [[INDICES:%.*]], i32 5) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti4_lane_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8f16( [[TABLE:%.*]], [[INDICES:%.*]], i32 2) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z21test_svluti4_lane_f16u13__SVFloat16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8f16( [[TABLE:%.*]], [[INDICES:%.*]], i32 2) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svfloat16_t test_svluti4_lane_f16(svfloat16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_f16,)(table, indices, 2); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_bf16( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.nxv8bf16( [[TABLE:%.*]], [[INDICES:%.*]], i32 2) +// SME-CHECK-NEXT: ret [[TMP0]] +// CHECK-LABEL: @test_svluti4_lane_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8bf16( [[TABLE:%.*]], [[INDICES:%.*]], i32 1) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z22test_svluti4_lane_bf16u14__SVBfloat16_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.nxv8bf16( [[TABLE:%.*]], [[INDICES:%.*]], i32 1) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svbfloat16_t test_svluti4_lane_bf16(svbfloat16_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_bf16,)(table, indices, 1); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_s16_x2( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE:%.*]], i64 0) +// SME-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE]], i64 8) +// SME-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.x2.nxv8i16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 0) +// SME-CHECK-NEXT: ret [[TMP2]] +// CHECK-LABEL: @test_svluti4_lane_s16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8i16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 0) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti4_lane_s16_x211svint16x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8i16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 0) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svint16_t test_svluti4_lane_s16_x2(svint16x2_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_s16,_x2)(table, indices, 0); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_u16_x2( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE:%.*]], i64 0) +// SME-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE]], i64 8) +// SME-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.x2.nxv8i16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 7) +// SME-CHECK-NEXT: ret [[TMP2]] +// CHECK-LABEL: @test_svluti4_lane_u16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8i16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 3) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti4_lane_u16_x212svuint16x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[TABLE]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8i16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 3) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svuint16_t test_svluti4_lane_u16_x2(svuint16x2_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_u16,_x2)(table, indices, 3); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_f16_x2( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[TABLE:%.*]], i64 0) +// SME-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[TABLE]], i64 8) +// SME-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.x2.nxv8f16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 5) +// SME-CHECK-NEXT: ret [[TMP2]] +// CHECK-LABEL: @test_svluti4_lane_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[TABLE:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[TABLE]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8f16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 2) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti4_lane_f16_x213svfloat16x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[TABLE:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[TABLE]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8f16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 2) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svfloat16_t test_svluti4_lane_f16_x2(svfloat16x2_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_f16,_x2)(table, indices, 2); +} + +// SME-CHECK-LABEL: @test_svluti4_lane_bf16_x2( +// SME-CHECK-NEXT: entry: +// SME-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[TABLE:%.*]], i64 0) +// SME-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[TABLE]], i64 8) +// SME-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.x2.nxv8bf16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 2) +// SME-CHECK-NEXT: ret [[TMP2]] +// CHECK-LABEL: @test_svluti4_lane_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[TABLE:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[TABLE]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8bf16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 1) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z25test_svluti4_lane_bf16_x214svbfloat16x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[TABLE:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[TABLE]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.luti4.lane.x2.nxv8bf16( [[TMP0]], [[TMP1]], [[INDICES:%.*]], i32 1) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svbfloat16_t test_svluti4_lane_bf16_x2(svbfloat16x2_t table, svuint8_t indices) MODE_ATTR{ + return SVE_ACLE_FUNC(svluti4_lane,_bf16,_x2)(table, indices, 1); +} diff --git a/clang/test/CodeGen/arm-neon-range-checks.c b/clang/test/CodeGen/arm-neon-range-checks.c deleted file mode 100644 index 360ff6be16654..0000000000000 --- a/clang/test/CodeGen/arm-neon-range-checks.c +++ /dev/null @@ -1,426 +0,0 @@ -// RUN: %clang_cc1 -triple arm64-none-eabi -target-feature +neon -target-feature +dotprod -target-feature +v8.1a -verify %s -// RUN: %clang_cc1 -triple armv8.1a-none-eabi -target-feature +neon -target-feature +dotprod -target-feature +v8.1a -verify %s - -// REQUIRES: aarch64-registered-target || arm-registered-target - -#include - -void test_vdot_lane(int32x2_t r, int8x8_t a, int8x8_t b) { - vdot_lane_s32(r, a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vdot_lane_s32(r, a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vdot_lane_s32(r, a, b, 0); - vdot_lane_s32(r, a, b, 1); -} - -void test_vdotq_lane(int32x4_t r, int8x16_t a, int8x8_t b) { - vdotq_lane_s32(r, a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vdotq_lane_s32(r, a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vdotq_lane_s32(r, a, b, 0); - vdotq_lane_s32(r, a, b, 1); -} - -#if defined(__aarch64__) -void test_vdot_laneq(int32x2_t r, int8x8_t a, int8x16_t b) { - vdot_laneq_s32(r, a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vdot_laneq_s32(r, a, b, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vdot_laneq_s32(r, a, b, 0); - vdot_laneq_s32(r, a, b, 3); -} - -void test_vdotq_laneq(int32x4_t r, int8x16_t a, int8x16_t b) { - vdotq_laneq_s32(r, a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vdotq_laneq_s32(r, a, b, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vdotq_laneq_s32(r, a, b, 0); - vdotq_laneq_s32(r, a, b, 3); -} -#endif - -void test_vdup_lane(int32x2_t v) { - vdup_lane_s32(v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vdup_lane_s32(v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vdup_lane_s32(v, 0); - vdup_lane_s32(v, 1); -} - -void test_vdupq_lane(int32x2_t v) { - vdupq_lane_s32(v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vdupq_lane_s32(v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vdupq_lane_s32(v, 0); - vdupq_lane_s32(v, 1); -} - -#if defined(__aarch64__) -void test_vdup_laneq(int32x4_t v) { - vdup_laneq_s32(v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vdup_laneq_s32(v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vdup_laneq_s32(v, 0); - vdup_laneq_s32(v, 3); -} - -void test_vdupq_laneq(int32x4_t v) { - vdupq_laneq_s32(v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vdupq_laneq_s32(v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vdupq_laneq_s32(v, 0); - vdupq_laneq_s32(v, 3); -} -#endif - -void test_vmla_lane(int32x2_t a, int32x2_t b, int32x2_t v) { - vmla_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmla_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmla_lane_s32(a, b, v, 0); - vmla_lane_s32(a, b, v, 1); -} - -void test_vmlaq_lane(int32x4_t a, int32x4_t b, int32x2_t v) { - vmlaq_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmlaq_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmlaq_lane_s32(a, b, v, 0); - vmlaq_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vmla_laneq(int32x2_t a, int32x2_t b, int32x4_t v) { - vmla_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmla_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmla_laneq_s32(a, b, v, 0); - vmla_laneq_s32(a, b, v, 3); -} - -void test_vmlaq_laneq(int32x4_t a, int32x4_t b, int32x4_t v) { - vmlaq_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmlaq_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmlaq_laneq_s32(a, b, v, 0); - vmlaq_laneq_s32(a, b, v, 3); -} - -void test_vmlal_high_lane(int64x2_t a, int32x4_t b, int32x2_t v) { - vmlal_high_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmlal_high_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmlal_high_lane_s32(a, b, v, 0); - vmlal_high_lane_s32(a, b, v, 1); -} - -void test_vmlal_high_laneq(int64x2_t a, int32x4_t b, int32x4_t v) { - vmlal_high_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmlal_high_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmlal_high_laneq_s32(a, b, v, 0); - vmlal_high_laneq_s32(a, b, v, 3); -} -#endif - -void test_vmlal_lane(int64x2_t a, int32x2_t b, int32x2_t v) { - vmlal_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmlal_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmlal_lane_s32(a, b, v, 0); - vmlal_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vmlal_laneq(int64x2_t a, int32x2_t b, int32x4_t v) { - vmlal_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmlal_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmlal_laneq_s32(a, b, v, 0); - vmlal_laneq_s32(a, b, v, 3); -} -#endif - -void test_vmls_lane(int32x2_t a, int32x2_t b, int32x2_t v) { - vmls_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmls_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmls_lane_s32(a, b, v, 0); - vmls_lane_s32(a, b, v, 1); -} - -void test_vmlsq_lane(int32x4_t a, int32x4_t b, int32x2_t v) { - vmlsq_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmlsq_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmlsq_lane_s32(a, b, v, 0); - vmlsq_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vmls_laneq(int32x2_t a, int32x2_t b, int32x4_t v) { - vmls_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmls_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmls_laneq_s32(a, b, v, 0); - vmls_laneq_s32(a, b, v, 3); -} - -void test_vmlsq_laneq(int32x4_t a, int32x4_t b, int32x4_t v) { - vmlsq_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmlsq_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmlsq_laneq_s32(a, b, v, 0); - vmlsq_laneq_s32(a, b, v, 3); -} - -void test_vmlsl_high_lane(int64x2_t a, int32x4_t b, int32x2_t v) { - vmlsl_high_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmlsl_high_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmlsl_high_lane_s32(a, b, v, 0); - vmlsl_high_lane_s32(a, b, v, 1); -} - -void test_vmlsl_high_laneq(int64x2_t a, int32x4_t b, int32x4_t v) { - vmlsl_high_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmlsl_high_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmlsl_high_laneq_s32(a, b, v, 0); - vmlsl_high_laneq_s32(a, b, v, 3); -} -#endif - -void test_vmlsl_lane(int64x2_t a, int32x2_t b, int32x2_t v) { - vmlsl_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmlsl_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmlsl_lane_s32(a, b, v, 0); - vmlsl_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vmlsl_laneq(int64x2_t a, int32x2_t b, int32x4_t v) { - vmlsl_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmlsl_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmlsl_laneq_s32(a, b, v, 0); - vmlsl_laneq_s32(a, b, v, 3); -} -#endif - -void test_vmull_lane(int32x2_t a, int32x2_t b) { - vmull_lane_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmull_lane_s32(a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmull_lane_s32(a, b, 0); - vmull_lane_s32(a, b, 1); -} - -#if defined(__aarch64__) -void test_vmull_laneq(int32x2_t a, int32x4_t b) { - vmull_laneq_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmull_laneq_s32(a, b, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmull_laneq_s32(a, b, 0); - vmull_laneq_s32(a, b, 3); -} - -void test_vmull_high_lane(int32x4_t a, int32x2_t b) { - vmull_high_lane_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vmull_high_lane_s32(a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vmull_high_lane_s32(a, b, 0); - vmull_high_lane_s32(a, b, 1); -} - -void test_vmull_high_laneq(int32x4_t a, int32x4_t b) { - vmull_high_laneq_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vmull_high_laneq_s32(a, b, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vmull_high_laneq_s32(a, b, 0); - vmull_high_laneq_s32(a, b, 3); -} - -void test_vqdmlal_high_lane(int64x2_t a, int32x4_t b, int32x2_t v) { - vqdmlal_high_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmlal_high_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmlal_high_lane_s32(a, b, v, 0); - vqdmlal_high_lane_s32(a, b, v, 1); -} - -void test_vqdmlal_high_laneq(int64x2_t a, int32x4_t b, int32x4_t v) { - vqdmlal_high_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmlal_high_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmlal_high_laneq_s32(a, b, v, 0); - vqdmlal_high_laneq_s32(a, b, v, 3); -} -#endif - -void test_vqdmlal_lane(int64x2_t a, int32x2_t b, int32x2_t v) { - vqdmlal_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmlal_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmlal_lane_s32(a, b, v, 0); - vqdmlal_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vqdmlal_laneq(int64x2_t a, int32x2_t b, int32x4_t v) { - vqdmlal_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmlal_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmlal_laneq_s32(a, b, v, 0); - vqdmlal_laneq_s32(a, b, v, 3); -} - -void test_vqdmlsl_high_lane(int64x2_t a, int32x4_t b, int32x2_t v) { - vqdmlsl_high_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmlsl_high_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmlsl_high_lane_s32(a, b, v, 0); - vqdmlsl_high_lane_s32(a, b, v, 1); -} - -void test_vqdmlsl_high_laneq(int64x2_t a, int32x4_t b, int32x4_t v) { - vqdmlsl_high_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmlsl_high_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmlsl_high_laneq_s32(a, b, v, 0); - vqdmlsl_high_laneq_s32(a, b, v, 3); -} -#endif - -void test_vqdmlsl_lane(int64x2_t a, int32x2_t b, int32x2_t v) { - vqdmlsl_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmlsl_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmlsl_lane_s32(a, b, v, 0); - vqdmlsl_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vqdmlsl_laneq(int64x2_t a, int32x2_t b, int32x4_t v) { - vqdmlsl_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmlsl_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmlsl_laneq_s32(a, b, v, 0); - vqdmlsl_laneq_s32(a, b, v, 3); -} -#endif - -void test_vqdmulh_lane(int32x2_t a, int32x2_t b) { - vqdmulh_lane_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmulh_lane_s32(a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmulh_lane_s32(a, b, 0); - vqdmulh_lane_s32(a, b, 1); -} - -void test_vqdmulhq_lane(int32x4_t a, int32x2_t b) { - vqdmulhq_lane_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmulhq_lane_s32(a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmulhq_lane_s32(a, b, 0); - vqdmulhq_lane_s32(a, b, 1); -} - -#if defined(__aarch64__) -void test_vqdmulh_laneq(int32x2_t a, int32x4_t b) { - vqdmulh_laneq_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmulh_laneq_s32(a, b, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmulh_laneq_s32(a, b, 0); - vqdmulh_laneq_s32(a, b, 3); -} - -void test_vqdmulhq_laneq(int32x4_t a, int32x4_t b) { - vqdmulhq_laneq_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmulhq_laneq_s32(a, b, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmulhq_laneq_s32(a, b, 0); - vqdmulhq_laneq_s32(a, b, 3); -} - -void test_vqdmull_high_lane(int32x4_t a, int32x2_t b) { - vqdmull_high_lane_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmull_high_lane_s32(a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmull_high_lane_s32(a, b, 0); - vqdmull_high_lane_s32(a, b, 1); -} - -void test_vqdmull_high_laneq(int32x4_t a, int32x4_t b) { - vqdmull_high_laneq_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmull_high_laneq_s32(a, b, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmull_high_laneq_s32(a, b, 0); - vqdmull_high_laneq_s32(a, b, 3); -} -#endif - -void test_vqdmull_lane(int32x2_t a, int32x2_t v) { - vqdmull_lane_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqdmull_lane_s32(a, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqdmull_lane_s32(a, v, 0); - vqdmull_lane_s32(a, v, 1); -} - -#if defined(__aarch64__) -void test_vqdmull_laneq(int32x2_t a, int32x4_t v) { - vqdmull_laneq_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqdmull_laneq_s32(a, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqdmull_laneq_s32(a, v, 0); - vqdmull_laneq_s32(a, v, 3); -} -#endif - -void test_vqrdmlah_lane(int32x2_t a, int32x2_t b, int32x2_t v) { - vqrdmlah_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqrdmlah_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqrdmlah_lane_s32(a, b, v, 0); - vqrdmlah_lane_s32(a, b, v, 1); -} - -void test_vqrdmlahq_lane(int32x4_t a, int32x4_t b, int32x2_t v) { - vqrdmlahq_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqrdmlahq_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqrdmlahq_lane_s32(a, b, v, 0); - vqrdmlahq_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vqrdmlah_laneq(int32x2_t a, int32x2_t b, int32x4_t v) { - vqrdmlah_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqrdmlah_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqrdmlah_laneq_s32(a, b, v, 0); - vqrdmlah_laneq_s32(a, b, v, 3); -} - -void test_vqrdmlahq_laneq(int32x4_t a, int32x4_t b, int32x4_t v) { - vqrdmlahq_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqrdmlahq_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqrdmlahq_laneq_s32(a, b, v, 0); - vqrdmlahq_laneq_s32(a, b, v, 3); -} -#endif - -void test_vqrdmlsh_lane(int32x2_t a, int32x2_t b, int32x2_t v) { - vqrdmlsh_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqrdmlsh_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqrdmlsh_lane_s32(a, b, v, 0); - vqrdmlsh_lane_s32(a, b, v, 1); -} - -void test_vqrdmlshq_lane(int32x4_t a, int32x4_t b, int32x2_t v) { - vqrdmlshq_lane_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqrdmlshq_lane_s32(a, b, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqrdmlshq_lane_s32(a, b, v, 0); - vqrdmlshq_lane_s32(a, b, v, 1); -} - -#if defined(__aarch64__) -void test_vqrdmlsh_laneq(int32x2_t a, int32x2_t b, int32x4_t v) { - vqrdmlsh_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqrdmlsh_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqrdmlsh_laneq_s32(a, b, v, 0); - vqrdmlsh_laneq_s32(a, b, v, 3); -} - -void test_vqrdmlshq_laneq(int32x4_t a, int32x4_t b, int32x4_t v) { - vqrdmlshq_laneq_s32(a, b, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqrdmlshq_laneq_s32(a, b, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqrdmlshq_laneq_s32(a, b, v, 0); - vqrdmlshq_laneq_s32(a, b, v, 3); -} -#endif - -void test_vqrdmulh_lane(int32x2_t a, int32x2_t v) { - vqrdmulh_lane_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqrdmulh_lane_s32(a, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqrdmulh_lane_s32(a, v, 0); - vqrdmulh_lane_s32(a, v, 1); -} - -void test_vqrdmulhq_lane(int32x4_t a, int32x2_t v) { - vqrdmulhq_lane_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - vqrdmulhq_lane_s32(a, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} - vqrdmulhq_lane_s32(a, v, 0); - vqrdmulhq_lane_s32(a, v, 1); -} - -#if defined(__aarch64__) -void test_vqrdmulh_laneq(int32x2_t a, int32x4_t v) { - vqrdmulh_laneq_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqrdmulh_laneq_s32(a, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqrdmulh_laneq_s32(a, v, 0); - vqrdmulh_laneq_s32(a, v, 3); -} - -void test_vqrdmulhq_laneq(int32x4_t a, int32x4_t v) { - vqrdmulhq_laneq_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - vqrdmulhq_laneq_s32(a, v, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - vqrdmulhq_laneq_s32(a, v, 0); - vqrdmulhq_laneq_s32(a, v, 3); -} -#endif diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index ab36b6e7720ba..a06e815737f4e 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -118,7 +118,7 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 // SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP2]] @@ -134,7 +134,7 @@ void test1(struct annotated *p, int index, int val) { // NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP0]] // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void // @@ -142,7 +142,7 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: ret void // @@ -150,7 +150,7 @@ void test1(struct annotated *p, int index, int val) { // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // @@ -207,7 +207,7 @@ size_t test2_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[TMP2]], 2 // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP3]], i64 4) @@ -231,7 +231,7 @@ size_t test2_bdos(struct annotated *p) { // NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP4]] // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void // @@ -239,7 +239,7 @@ size_t test2_bdos(struct annotated *p) { // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: ret void // @@ -247,7 +247,7 @@ size_t test2_bdos(struct annotated *p) { // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c index 39ede01d6e3b8..8a560a47ad1e1 100644 --- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c +++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c @@ -33,7 +33,7 @@ char *add_unsigned(char *base, unsigned long offset) { // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c index e93dbcb9f647b..d884993ffb2b3 100644 --- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c +++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c @@ -50,7 +50,7 @@ char *var_var(char *base, unsigned long offset) { // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize @@ -83,7 +83,7 @@ char *var_zero(char *base) { // CHECK-NEXT: %[[BASE_ADDR:.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr %[[BASE]], ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 0 + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 0 // CHECK-SANITIZE-C-NEXT: %[[BASE_RELOADED_INT:.*]] = ptrtoint ptr %[[BASE_RELOADED]] to i64, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COMPUTED_GEP:.*]] = add i64 %[[BASE_RELOADED_INT]], 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[BASE_IS_NOT_NULLPTR:.*]] = icmp ne ptr %[[BASE_RELOADED]], null, !nosanitize @@ -111,7 +111,7 @@ char *var_one(char *base) { // CHECK-NEXT: %[[BASE_ADDR:.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr %[[BASE]], ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 1 + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 1 // CHECK-SANITIZE-NEXT: %[[BASE_RELOADED_INT:.*]] = ptrtoint ptr %[[BASE_RELOADED]] to i64, !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 %[[BASE_RELOADED_INT]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[BASE_IS_NOT_NULLPTR:.*]] = icmp ne ptr %[[BASE_RELOADED]], null, !nosanitize @@ -140,7 +140,7 @@ char *var_allones(char *base) { // CHECK-NEXT: %[[BASE_ADDR:.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr %[[BASE]], ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 -1 + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 -1 // CHECK-SANITIZE-NEXT: %[[BASE_RELOADED_INT:.*]] = ptrtoint ptr %[[BASE_RELOADED]] to i64, !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 %[[BASE_RELOADED_INT]], -1, !nosanitize // CHECK-SANITIZE-NEXT: %[[BASE_IS_NOT_NULLPTR:.*]] = icmp ne ptr %[[BASE_RELOADED]], null, !nosanitize @@ -171,7 +171,7 @@ char *nullptr_var(unsigned long offset) { // CHECK-NEXT: %[[OFFSET_ADDR:.*]] = alloca i64, align 8 // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr null, i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr null, i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize @@ -217,17 +217,17 @@ char *nullptr_zero(void) { char *nullptr_one_BAD(void) { // CHECK: define{{.*}} ptr @nullptr_one_BAD() // CHECK-NEXT: [[ENTRY:.*]]: - // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64), 0, !nosanitize + // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr null, i64 1) to i64), 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 false, %[[CMP]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 false, %[[CMP]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64)) - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64)) + // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr null, i64 1) to i64)) + // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr null, i64 1) to i64)) // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize // CHECK-SANITIZE: [[CONT]]: - // CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr null, i64 1) + // CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr null, i64 1) static char *const base = (char *)0; static const unsigned long offset = 1; #line 700 @@ -237,17 +237,17 @@ char *nullptr_one_BAD(void) { char *nullptr_allones_BAD(void) { // CHECK: define{{.*}} ptr @nullptr_allones_BAD() // CHECK-NEXT: [[ENTRY:.*]]: - // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64), 0, !nosanitize + // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr null, i64 -1) to i64), 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 false, %[[CMP]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 false, %[[CMP]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64)) - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64)) + // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr null, i64 -1) to i64)) + // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr null, i64 -1) to i64)) // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize // CHECK-SANITIZE: [[CONT]]: - // CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr null, i64 -1) + // CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr null, i64 -1) static char *const base = (char *)0; static const unsigned long offset = -1; #line 800 @@ -262,7 +262,7 @@ char *one_var(unsigned long offset) { // CHECK-NEXT: %[[OFFSET_ADDR:.*]] = alloca i64, align 8 // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr inttoptr (i64 1 to ptr), i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr inttoptr (i64 1 to ptr), i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize @@ -312,17 +312,17 @@ char *one_one_OK(void) { // CHECK: define{{.*}} ptr @one_one_OK() // CHECK-NEXT: [[ENTRY:.*]]: // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null, !nosanitize - // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), 0, !nosanitize + // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1)) - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1)) + // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1)) + // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1)) // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize // CHECK-SANITIZE: [[CONT]]: - // CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) + // CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 1) static char *const base = (char *)1; static const unsigned long offset = 1; #line 1100 @@ -333,17 +333,17 @@ char *one_allones_BAD(void) { // CHECK: define{{.*}} ptr @one_allones_BAD() // CHECK-NEXT: [[ENTRY:.*]]: // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null, !nosanitize - // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), 0, !nosanitize + // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1)) - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1)) + // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1)) + // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1)) // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize // CHECK-SANITIZE: [[CONT]]: - // CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) + // CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 1 to ptr), i64 -1) static char *const base = (char *)1; static const unsigned long offset = -1; #line 1200 @@ -358,7 +358,7 @@ char *allones_var(unsigned long offset) { // CHECK-NEXT: %[[OFFSET_ADDR:.*]] = alloca i64, align 8 // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr inttoptr (i64 -1 to ptr), i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr inttoptr (i64 -1 to ptr), i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize @@ -408,17 +408,17 @@ char *allones_one_BAD(void) { // CHECK: define{{.*}} ptr @allones_one_BAD() // CHECK-NEXT: [[ENTRY:.*]]: // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize - // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), 0, !nosanitize + // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1)) - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1)) + // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1)) + // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1)) // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize // CHECK-SANITIZE: [[CONT]]: - // CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) + // CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 1) static char *const base = (char *)-1; static const unsigned long offset = 1; #line 1500 @@ -429,17 +429,17 @@ char *allones_allones_OK(void) { // CHECK: define{{.*}} ptr @allones_allones_OK() // CHECK-NEXT: [[ENTRY:.*]]: // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize - // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), 0, !nosanitize + // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1600]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1)) - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1600]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1)) + // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1600]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1)) + // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1600]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1)) // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize // CHECK-SANITIZE: [[CONT]]: - // CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) + // CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) static char *const base = (char *)-1; static const unsigned long offset = -1; #line 1600 @@ -461,7 +461,7 @@ char *void_ptr(void *base, unsigned long offset) { // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize diff --git a/clang/test/CodeGen/catch-pointer-overflow-volatile.c b/clang/test/CodeGen/catch-pointer-overflow-volatile.c index 4b0653a0ae59e..626bbc0db7afb 100644 --- a/clang/test/CodeGen/catch-pointer-overflow-volatile.c +++ b/clang/test/CodeGen/catch-pointer-overflow-volatile.c @@ -23,7 +23,7 @@ char *volatile_ptr(char *volatile base, unsigned long offset) { // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load volatile ptr, ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize diff --git a/clang/test/CodeGen/catch-pointer-overflow.c b/clang/test/CodeGen/catch-pointer-overflow.c index 899af73bd81e0..1f7f1729098c7 100644 --- a/clang/test/CodeGen/catch-pointer-overflow.c +++ b/clang/test/CodeGen/catch-pointer-overflow.c @@ -30,7 +30,7 @@ char *add_unsigned(char *base, unsigned long offset) { // CHECK-NEXT: store i64 %[[OFFSET]], ptr %[[OFFSET_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, ptr %[[OFFSET_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i64 %[[OFFSET_RELOADED]] // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_AGGREGATE:.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %[[OFFSET_RELOADED]]), !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_OVERFLOWED:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize @@ -179,7 +179,7 @@ char *postinc(char *base) { // CHECK-NEXT: %[[BASE_ADDR:.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr %[[BASE]], ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i32 1 + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i32 1 // CHECK-SANITIZE-NEXT: %[[BASE_RELOADED_INT:.*]] = ptrtoint ptr %[[BASE_RELOADED]] to i64, !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 %[[BASE_RELOADED_INT]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[BASE_IS_NOT_NULLPTR:.*]] = icmp ne ptr %[[BASE_RELOADED]], null, !nosanitize @@ -241,7 +241,7 @@ char *preinc(char *base) { // CHECK-NEXT: %[[BASE_ADDR:.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr %[[BASE]], ptr %[[BASE_ADDR]], align 8 // CHECK-NEXT: %[[BASE_RELOADED:.*]] = load ptr, ptr %[[BASE_ADDR]], align 8 - // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[BASE_RELOADED]], i32 1 + // CHECK-NEXT: %[[ADD_PTR:.*]] = getelementptr inbounds nuw i8, ptr %[[BASE_RELOADED]], i32 1 // CHECK-SANITIZE-NEXT: %[[BASE_RELOADED_INT:.*]] = ptrtoint ptr %[[BASE_RELOADED]] to i64, !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 %[[BASE_RELOADED_INT]], 1, !nosanitize // CHECK-SANITIZE-NEXT: %[[BASE_IS_NOT_NULLPTR:.*]] = icmp ne ptr %[[BASE_RELOADED]], null, !nosanitize diff --git a/clang/test/CodeGen/ext-int.c b/clang/test/CodeGen/ext-int.c index 714b7e122a706..e3d609a4ba4a2 100644 --- a/clang/test/CodeGen/ext-int.c +++ b/clang/test/CodeGen/ext-int.c @@ -154,7 +154,7 @@ _BitInt(129) *f1(_BitInt(129) *p) { } char *f2(char *p) { - // CHECK64: getelementptr inbounds i8, {{.*}} i64 24 + // CHECK64: getelementptr inbounds nuw i8, {{.*}} i64 24 return p + sizeof(_BitInt(129)); } diff --git a/clang/test/CodeGen/hexagon-brev-ld-ptr-incdec.c b/clang/test/CodeGen/hexagon-brev-ld-ptr-incdec.c index 7802168de4d75..d25d1e04f15fa 100644 --- a/clang/test/CodeGen/hexagon-brev-ld-ptr-incdec.c +++ b/clang/test/CodeGen/hexagon-brev-ld-ptr-incdec.c @@ -6,9 +6,9 @@ // the return value will be the value in A[2] // CHECK: @brev_ptr_inc // CHECK-DAG: llvm.hexagon.L2.loadri.pbr -// CHECK-DAG: getelementptr inbounds i8, {{.*}}i32 4 -// CHECK-NOT: getelementptr inbounds i8, {{.*}}i32 8 -// CHECK-NOT: getelementptr inbounds i8, {{.*}}i32 4 +// CHECK-DAG: getelementptr inbounds nuw i8, {{.*}}i32 4 +// CHECK-NOT: getelementptr inbounds nuw i8, {{.*}}i32 8 +// CHECK-NOT: getelementptr inbounds nuw i8, {{.*}}i32 4 int brev_ptr_inc(int A[], int B[]) { int *p0 = &B[0]; int *p1 = &A[0]; diff --git a/clang/test/CodeGen/integer-overflow.c b/clang/test/CodeGen/integer-overflow.c index 461b026d39615..9e8cde8b33b16 100644 --- a/clang/test/CodeGen/integer-overflow.c +++ b/clang/test/CodeGen/integer-overflow.c @@ -60,10 +60,10 @@ void test1(void) { // -fwrapv should turn off inbounds for GEP's, PR9256 extern int* P; ++P; - // DEFAULT: getelementptr inbounds i32, ptr + // DEFAULT: getelementptr inbounds nuw i32, ptr // WRAPV: getelementptr i32, ptr - // TRAPV: getelementptr inbounds i32, ptr - // CATCH_UB_POINTER: getelementptr inbounds i32, ptr + // TRAPV: getelementptr inbounds nuw i32, ptr + // CATCH_UB_POINTER: getelementptr inbounds nuw i32, ptr // NOCATCH_UB_POINTER: getelementptr i32, ptr // PR9350: char pre-increment never overflows. diff --git a/clang/test/CodeGen/ms-intrinsics.c b/clang/test/CodeGen/ms-intrinsics.c index c3d64fda0b901..459a708d9b2e0 100644 --- a/clang/test/CodeGen/ms-intrinsics.c +++ b/clang/test/CodeGen/ms-intrinsics.c @@ -156,7 +156,7 @@ unsigned char test_BitScanForward(unsigned long *Index, unsigned long Mask) { // CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK: ret i8 [[RESULT]] // CHECK: [[ISNOTZERO_LABEL]]: -// CHECK: [[IDXGEP:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr %Index, {{i64|i32}} 4 +// CHECK: [[IDXGEP:%[a-z0-9._]+]] = getelementptr inbounds nuw i8, ptr %Index, {{i64|i32}} 4 // CHECK: [[INDEX:%[0-9]+]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 %Mask, i1 true) // CHECK: store i32 [[INDEX]], ptr [[IDXGEP]], align 4 // CHECK: br label %[[END_LABEL]] @@ -171,7 +171,7 @@ unsigned char test_BitScanReverse(unsigned long *Index, unsigned long Mask) { // CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK: ret i8 [[RESULT]] // CHECK: [[ISNOTZERO_LABEL]]: -// CHECK: [[IDXGEP:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr %Index, {{i64|i32}} 4 +// CHECK: [[IDXGEP:%[a-z0-9._]+]] = getelementptr inbounds nuw i8, ptr %Index, {{i64|i32}} 4 // CHECK: [[REVINDEX:%[0-9]+]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 %Mask, i1 true) // CHECK: [[INDEX:%[0-9]+]] = xor i32 [[REVINDEX]], 31 // CHECK: store i32 [[INDEX]], ptr [[IDXGEP]], align 4 @@ -437,10 +437,10 @@ unsigned char test_InterlockedCompareExchange128( ++ExchangeLow, ++ComparandResult); } // CHECK-64: define{{.*}}i8 @test_InterlockedCompareExchange128(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%ExchangeHigh, i64{{[a-z_ ]*}}%ExchangeLow, ptr{{[a-z_ ]*}}%ComparandResult){{.*}}{ -// CHECK-64: %incdec.ptr = getelementptr inbounds i8, ptr %Destination, i64 8 +// CHECK-64: %incdec.ptr = getelementptr inbounds nuw i8, ptr %Destination, i64 8 // CHECK-64: %inc = add nsw i64 %ExchangeHigh, 1 // CHECK-64: %inc1 = add nsw i64 %ExchangeLow, 1 -// CHECK-64: %incdec.ptr2 = getelementptr inbounds i8, ptr %ComparandResult, i64 8 +// CHECK-64: %incdec.ptr2 = getelementptr inbounds nuw i8, ptr %ComparandResult, i64 8 // CHECK-64: [[EH:%[0-9]+]] = zext i64 %inc to i128 // CHECK-64: [[EL:%[0-9]+]] = zext i64 %inc1 to i128 // CHECK-64: [[EHS:%[0-9]+]] = shl nuw i128 [[EH]], 64 @@ -486,7 +486,7 @@ short test_InterlockedIncrement16(short volatile *Addend) { return _InterlockedIncrement16(++Addend); } // CHECK: define{{.*}}i16 @test_InterlockedIncrement16(ptr{{[a-z_ ]*}}%Addend){{.*}}{ -// CHECK: %incdec.ptr = getelementptr inbounds i8, ptr %Addend, {{i64|i32}} 2 +// CHECK: %incdec.ptr = getelementptr inbounds nuw i8, ptr %Addend, {{i64|i32}} 2 // CHECK: [[TMP:%[0-9]+]] = atomicrmw add ptr %incdec.ptr, i16 1 seq_cst, align 2 // CHECK: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1 // CHECK: ret i16 [[RESULT]] @@ -496,7 +496,7 @@ long test_InterlockedIncrement(long volatile *Addend) { return _InterlockedIncrement(++Addend); } // CHECK: define{{.*}}i32 @test_InterlockedIncrement(ptr{{[a-z_ ]*}}%Addend){{.*}}{ -// CHECK: %incdec.ptr = getelementptr inbounds i8, ptr %Addend, {{i64|i32}} 4 +// CHECK: %incdec.ptr = getelementptr inbounds nuw i8, ptr %Addend, {{i64|i32}} 4 // CHECK: [[TMP:%[0-9]+]] = atomicrmw add ptr %incdec.ptr, i32 1 seq_cst, align 4 // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK: ret i32 [[RESULT]] diff --git a/clang/test/CodeGen/ubsan-pointer-overflow.m b/clang/test/CodeGen/ubsan-pointer-overflow.m index 9192598da92fc..4ecdac655669f 100644 --- a/clang/test/CodeGen/ubsan-pointer-overflow.m +++ b/clang/test/CodeGen/ubsan-pointer-overflow.m @@ -5,7 +5,7 @@ void variable_len_array_arith(int n, int k) { int vla[n]; int (*p)[n] = &vla; - // CHECK: getelementptr inbounds i32, ptr {{.*}}, i64 [[INC:%.*]] + // CHECK: getelementptr inbounds nuw i32, ptr {{.*}}, i64 [[INC:%.*]] // CHECK: @llvm.smul.with.overflow.i64(i64 4, i64 [[INC]]), !nosanitize // CHECK-NOT: select // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} diff --git a/clang/test/CodeGen/vla.c b/clang/test/CodeGen/vla.c index 33621c5dd7a29..a22ba727df2fe 100644 --- a/clang/test/CodeGen/vla.c +++ b/clang/test/CodeGen/vla.c @@ -120,7 +120,7 @@ int test4(unsigned n, char (*p)[n][n+1][6]) { // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2 // CHECK-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] // CHECK-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]] - // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8], ptr [[T0]], i32 [[T4]] + // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds nuw [6 x i8], ptr [[T0]], i32 [[T4]] // CHECK-NEXT: [[T6:%.*]] = load i32, ptr [[N]], align 4 // CHECK-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4 // CHECK-NEXT: [[T8:%.*]] = sub i32 0, [[T7]] diff --git a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp index e842de6335046..fd9786de3a949 100644 --- a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp +++ b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp @@ -152,16 +152,16 @@ void f_branch_elided() // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]] // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP1]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16:![0-9]+]] +// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR3]] // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP2]], i64 0, i64 0 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY1]], i64 4 -// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: br label [[FOR_COND:%.*]] // CHECK: for.cond: -// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] -// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP3]], [[TMP4]] // 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:%.*]] @@ -172,16 +172,16 @@ void f_branch_elided() // CHECK-NEXT: br label [[FOR_END:%.*]] // CHECK: for.body: // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]] -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: store i32 [[TMP6]], ptr [[I]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: -// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 1 -// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] -// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP18:![0-9]+]] +// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i32 1 +// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK: for.end: // CHECK-NEXT: ret void // @@ -204,16 +204,16 @@ void frl(int (&&e) [4]) // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]] // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP1]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR3]] // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP2]], i64 0, i64 0 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY1]], i64 4 -// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: br label [[FOR_COND:%.*]] // CHECK: for.cond: -// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] -// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP3]], [[TMP4]] // 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:%.*]] @@ -224,16 +224,16 @@ void frl(int (&&e) [4]) // CHECK-NEXT: br label [[FOR_END:%.*]] // CHECK: for.body: // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]] -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] // CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: store i32 [[TMP6]], ptr [[I]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: -// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 1 -// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] -// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP19:![0-9]+]] +// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i32 1 +// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]] // CHECK: for.end: // CHECK-NEXT: ret void // diff --git a/clang/test/CodeGenCXX/debug-info-lambda-this.cpp b/clang/test/CodeGenCXX/debug-info-lambda-this.cpp index 0a2f08ea4aa6d..e5acab126d72c 100644 --- a/clang/test/CodeGenCXX/debug-info-lambda-this.cpp +++ b/clang/test/CodeGenCXX/debug-info-lambda-this.cpp @@ -21,7 +21,8 @@ int main() { return 0; } -// CHECK: !{![[FOO_THIS:[0-9]+]], ![[FOO_AA:[0-9]+]], ![[FOO_OPERATOR:[0-9]+]]} +// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, name: "", {{.*}}, elements: ![[ELEMENT_TAG:[0-9]+]] +// CHECK: ![[ELEMENT_TAG]] = !{![[FOO_THIS:[0-9]+]], ![[FOO_AA:[0-9]+]], ![[FOO_OPERATOR:[0-9]+]]} // CHECK-NEXT: ![[FOO_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "__this", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[#]], size: [[#]]) // CHECK-NEXT: ![[FOO_AA]] = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[#]], size: [[#]], offset: [[#]]) // CHECK-NEXT: ![[FOO_OPERATOR]] = !DISubprogram(name: "operator()", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], scopeLine: [[#]], flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0) diff --git a/clang/test/CodeGenCXX/for-range.cpp b/clang/test/CodeGenCXX/for-range.cpp index 10d27206d12e4..088a34647c374 100644 --- a/clang/test/CodeGenCXX/for-range.cpp +++ b/clang/test/CodeGenCXX/for-range.cpp @@ -33,7 +33,7 @@ B *end(C&); extern B array[5]; -// CHECK-LABEL: define {{[^@]+}}@_Z9for_arrayv( +// CHECK-LABEL: @_Z9for_arrayv( // CHECK-NEXT: entry: // CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 1 // CHECK-NEXT: [[__RANGE1:%.*]] = alloca ptr, align 8 @@ -57,7 +57,7 @@ extern B array[5]; // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds [[STRUCT_B]], ptr [[TMP3]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[TMP3]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8 // CHECK-NEXT: br label [[FOR_COND]] // CHECK: for.end: @@ -70,7 +70,7 @@ void for_array() { } } -// CHECK-LABEL: define {{[^@]+}}@_Z9for_rangev( +// CHECK-LABEL: @_Z9for_rangev( // CHECK-NEXT: entry: // CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 1 // CHECK-NEXT: [[__RANGE1:%.*]] = alloca ptr, align 8 @@ -103,7 +103,7 @@ void for_array() { // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: // CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds [[STRUCT_B]], ptr [[TMP5]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[TMP5]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8 // CHECK-NEXT: br label [[FOR_COND]] // CHECK: for.end: @@ -116,7 +116,7 @@ void for_range() { } } -// CHECK-LABEL: define {{[^@]+}}@_Z16for_member_rangev( +// CHECK-LABEL: @_Z16for_member_rangev( // CHECK-NEXT: entry: // CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 1 // CHECK-NEXT: [[__RANGE1:%.*]] = alloca ptr, align 8 @@ -149,7 +149,7 @@ void for_range() { // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: // CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds [[STRUCT_B]], ptr [[TMP5]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[TMP5]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8 // CHECK-NEXT: br label [[FOR_COND]] // CHECK: for.end: diff --git a/clang/test/CodeGenCXX/microsoft-abi-template-static-init.cpp b/clang/test/CodeGenCXX/microsoft-abi-template-static-init.cpp index 60b48abca2f89..871551240debf 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-template-static-init.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-template-static-init.cpp @@ -49,8 +49,6 @@ struct X { static T ioo; static T init(); }; -// template specialized static data don't need in llvm.used, -// the static init routine get call from _GLOBAL__sub_I_ routines. template <> int X::ioo = X::init(); template struct X; class a { @@ -87,5 +85,6 @@ struct S1 int foo(); inline int zoo = foo(); inline static int boo = foo(); +inline __declspec(dllexport) A exported_inline{}; -// CHECK: @llvm.used = appending global [8 x ptr] [ptr @"?x@selectany_init@@3HA", ptr @"?x1@selectany_init@@3HA", ptr @"?x@?$A@H@explicit_template_instantiation@@2HA", ptr @"?ioo@?$X_@H@@2HA", ptr @"?aoo@S1@@2UA@@A", ptr @"?zoo@@3HA", ptr @"?s@?$ExportedTemplate@H@@2US@@A", ptr @"?x@?$A@H@implicit_template_instantiation@@2HA"], section "llvm.metadata" +// CHECK: @llvm.used = appending global [10 x ptr] [ptr @"?x@selectany_init@@3HA", ptr @"?x1@selectany_init@@3HA", ptr @"?x@?$A@H@explicit_template_instantiation@@2HA", ptr @"?ioo@?$X_@H@@2HA", ptr @"?ioo@?$X@H@@2HA", ptr @"?aoo@S1@@2UA@@A", ptr @"?zoo@@3HA", ptr @"?exported_inline@@3UA@@A", ptr @"?s@?$ExportedTemplate@H@@2US@@A", ptr @"?x@?$A@H@implicit_template_instantiation@@2HA"], section "llvm.metadata" diff --git a/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp b/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp index f7df110ec0129..bcb2d875dce66 100644 --- a/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp +++ b/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp @@ -16,7 +16,7 @@ void (*d)(){test_transform<0>}; // CHECK-NEXT: [[BODY]]: // CHECK-NEXT: [[CUR:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[NEXT:%.*]], %[[BODY]] ] // CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i32, ptr [[BEGIN]], i64 [[CUR]] -// CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds [1 x i32], ptr @a, i64 0, i64 [[CUR]] +// CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds nuw [1 x i32], ptr @a, i64 0, i64 [[CUR]] // CHECK-NEXT: [[X:%.*]] = load i32, ptr [[SRC]] // CHECK-NEXT: store i32 [[X]], ptr [[DEST]] // CHECK-NEXT: [[NEXT]] = add nuw i64 [[CUR]], 1 diff --git a/clang/test/CodeGenCXX/vla.cpp b/clang/test/CodeGenCXX/vla.cpp index 4cf2b3b445b40..aadf51fce3a44 100644 --- a/clang/test/CodeGenCXX/vla.cpp +++ b/clang/test/CodeGenCXX/vla.cpp @@ -83,7 +83,7 @@ void test2(int b) { //CHECK: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_NUM_ELEMENTS_PRE]] //CHECK-NEXT: [[VLA_NUM_ELEMENTS_POST:%.*]] = udiv i64 [[VLA_SIZEOF]], 4 - //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 [[VLA_NUM_ELEMENTS_POST]] + //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds nuw i32, ptr {{%.*}}, i64 [[VLA_NUM_ELEMENTS_POST]] //X64-NEXT: store ptr [[VLA_END_PTR]], ptr %__end1 //AMDGCN-NEXT: store ptr [[VLA_END_PTR]], ptr [[END]] for (int d : varr) 0; @@ -116,7 +116,7 @@ void test3(int b, int c) { //CHECK-NEXT: [[VLA_SIZEOF_DIM2:%.*]] = mul nuw i64 4, [[VLA_DIM2_PRE]] //CHECK-NEXT: [[VLA_NUM_ELEMENTS:%.*]] = udiv i64 [[VLA_SIZEOF]], [[VLA_SIZEOF_DIM2]] //CHECK-NEXT: [[VLA_END_INDEX:%.*]] = mul nsw i64 [[VLA_NUM_ELEMENTS]], [[VLA_DIM2_PRE]] - //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 [[VLA_END_INDEX]] + //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds nuw i32, ptr {{%.*}}, i64 [[VLA_END_INDEX]] //X64-NEXT: store ptr [[VLA_END_PTR]], ptr %__end //AMDGCN-NEXT: store ptr [[VLA_END_PTR]], ptr [[END]] diff --git a/clang/test/CodeGenCXX/vtable-available-externally.cpp b/clang/test/CodeGenCXX/vtable-available-externally.cpp index a57eb39edfe10..ab105260bc75a 100644 --- a/clang/test/CodeGenCXX/vtable-available-externally.cpp +++ b/clang/test/CodeGenCXX/vtable-available-externally.cpp @@ -250,28 +250,39 @@ struct C : A { virtual void car(); }; +// Inline definition outside body, so we can't emit vtable available_externally +// (see previous). +// CHECK-TEST10-DAG: @_ZTVN6Test101FE = external unnamed_addr constant +struct F : A { + void foo(); + virtual void cat(); // inline outside body +}; +inline void F::cat() {} + // no key function, vtable will be generated everywhere it will be used // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant struct E : A {}; -void g(A& a) { +void h(A& a) { a.foo(); a.bar(); } -void f() { +void g() { A a; - g(a); + h(a); B b; - g(b); + h(b); C c; - g(c); + h(c); D d; - g(d); + h(d); E e; - g(e); + h(e); + F f; + h(f); } } // Test10 diff --git a/clang/test/CodeGenHLSL/buffer-array-operator.hlsl b/clang/test/CodeGenHLSL/buffer-array-operator.hlsl index f5556df30871c..02e570ebdcb4f 100644 --- a/clang/test/CodeGenHLSL/buffer-array-operator.hlsl +++ b/clang/test/CodeGenHLSL/buffer-array-operator.hlsl @@ -17,7 +17,7 @@ void fn(int Idx) { // CHECK-NEXT: %h = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %this1, i32 0, i32 0 // CHECK-NEXT: %0 = load ptr, ptr %h, align 4 // CHECK-NEXT: %1 = load i32, ptr %Idx.addr, align 4 -// CHECK-NEXT: %arrayidx = getelementptr inbounds float, ptr %0, i32 %1 +// CHECK-NEXT: %arrayidx = getelementptr inbounds nuw float, ptr %0, i32 %1 // CHECK-NEXT: ret ptr %arrayidx // Const comes next, and returns the pointer instead of the value. @@ -26,5 +26,5 @@ void fn(int Idx) { // CHECK-NEXT: %h = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %this1, i32 0, i32 0 // CHECK-NEXT: %0 = load ptr, ptr %h, align 4 // CHECK-NEXT: %1 = load i32, ptr %Idx.addr, align 4 -// CHECK-NEXT: %arrayidx = getelementptr inbounds float, ptr %0, i32 %1 +// CHECK-NEXT: %arrayidx = getelementptr inbounds nuw float, ptr %0, i32 %1 // CHECK-NEXT: ret ptr %arrayidx diff --git a/clang/test/CodeGenHLSL/builtins/wave_is_first_lane.hlsl b/clang/test/CodeGenHLSL/builtins/wave_is_first_lane.hlsl new file mode 100644 index 0000000000000..18860c321eb91 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/wave_is_first_lane.hlsl @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL + +[numthreads(1, 1, 1)] +void main() { +// CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + +// CHECK-SPIRV: %[[#loop_tok:]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %[[#entry_tok]]) ] + while (true) { + +// CHECK-DXIL: %[[#]] = call i1 @llvm.dx.wave.is.first.lane() +// CHECK-SPIRV: %[[#]] = call i1 @llvm.spv.wave.is.first.lane() +// CHECK-SPIRV-SAME: [ "convergencectrl"(token %[[#loop_tok]]) ] + if (WaveIsFirstLane()) { + break; + } + } + +// CHECK-DXIL: %[[#]] = call i1 @llvm.dx.wave.is.first.lane() +// CHECK-SPIRV: %[[#]] = call i1 @llvm.spv.wave.is.first.lane() +// CHECK-SPIRV-SAME: [ "convergencectrl"(token %[[#entry_tok]]) ] + if (WaveIsFirstLane()) { + return; + } +} + +// CHECK-DXIL: i1 @llvm.dx.wave.is.first.lane() #[[#attr:]] +// CHECK-SPIRV: i1 @llvm.spv.wave.is.first.lane() #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/CodeGenOpenCL/atomics-cas-remarks-gfx90a.cl b/clang/test/CodeGenOpenCL/atomics-cas-remarks-gfx90a.cl index d23005e018f35..72027eda4571d 100644 --- a/clang/test/CodeGenOpenCL/atomics-cas-remarks-gfx90a.cl +++ b/clang/test/CodeGenOpenCL/atomics-cas-remarks-gfx90a.cl @@ -26,10 +26,11 @@ typedef enum memory_scope { #endif } memory_scope; -// REMARK: remark: A compare and swap loop was generated for an atomic fadd operation at workgroup-one-as memory scope [-Rpass=atomic-expand] -// REMARK: remark: A compare and swap loop was generated for an atomic fadd operation at agent-one-as memory scope [-Rpass=atomic-expand] -// REMARK: remark: A compare and swap loop was generated for an atomic fadd operation at one-as memory scope [-Rpass=atomic-expand] // REMARK: remark: A compare and swap loop was generated for an atomic fadd operation at wavefront-one-as memory scope [-Rpass=atomic-expand] +// REMARK: remark: A compare and swap loop was generated for an atomic fadd operation at one-as memory scope [-Rpass=atomic-expand] +// REMARK: remark: A compare and swap loop was generated for an atomic fadd operation at agent-one-as memory scope [-Rpass=atomic-expand] +// REMARK: remark: A compare and swap loop was generated for an atomic fadd operation at workgroup-one-as memory scope [-Rpass=atomic-expand] + // GFX90A-CAS-LABEL: @atomic_cas // GFX90A-CAS: atomicrmw fadd ptr addrspace(1) {{.*}} syncscope("workgroup-one-as") monotonic // GFX90A-CAS: atomicrmw fadd ptr addrspace(1) {{.*}} syncscope("agent-one-as") monotonic diff --git a/clang/test/CodeGenOpenCL/atomics-unsafe-hw-remarks-gfx90a.cl b/clang/test/CodeGenOpenCL/atomics-unsafe-hw-remarks-gfx90a.cl index 80ad9b4df8f64..7d684bc185a58 100644 --- a/clang/test/CodeGenOpenCL/atomics-unsafe-hw-remarks-gfx90a.cl +++ b/clang/test/CodeGenOpenCL/atomics-unsafe-hw-remarks-gfx90a.cl @@ -27,9 +27,10 @@ typedef enum memory_scope { #endif } memory_scope; -// GFX90A-HW-REMARK: Hardware instruction generated for atomic fadd operation at memory scope workgroup-one-as due to an unsafe request. [-Rpass=si-lower] -// GFX90A-HW-REMARK: Hardware instruction generated for atomic fadd operation at memory scope agent-one-as due to an unsafe request. [-Rpass=si-lower] // GFX90A-HW-REMARK: Hardware instruction generated for atomic fadd operation at memory scope wavefront-one-as due to an unsafe request. [-Rpass=si-lower] +// GFX90A-HW-REMARK: Hardware instruction generated for atomic fadd operation at memory scope agent-one-as due to an unsafe request. [-Rpass=si-lower] +// GFX90A-HW-REMARK: Hardware instruction generated for atomic fadd operation at memory scope workgroup-one-as due to an unsafe request. [-Rpass=si-lower] + // GFX90A-HW-REMARK: global_atomic_add_f32 v0, v[0:1], v2, off glc // GFX90A-HW-REMARK: global_atomic_add_f32 v0, v[0:1], v2, off glc // GFX90A-HW-REMARK: global_atomic_add_f32 v0, v[0:1], v2, off glc diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl index d9ec258e644c9..34ee44afe0f10 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl @@ -256,4 +256,28 @@ void test_s_ttracedata_imm() __builtin_amdgcn_s_ttracedata_imm(1); } - +// CHECK-LABEL: @test_s_prefetch_data( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[FP_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[GP_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) +// CHECK-NEXT: [[CP_ADDR:%.*]] = alloca ptr addrspace(4), align 8, addrspace(5) +// CHECK-NEXT: [[LEN_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: store ptr [[FP:%.*]], ptr addrspace(5) [[FP_ADDR]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[GP:%.*]], ptr addrspace(5) [[GP_ADDR]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[CP_ADDR]], align 8 +// CHECK-NEXT: store i32 [[LEN:%.*]], ptr addrspace(5) [[LEN_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr addrspace(5) [[FP_ADDR]], align 8 +// CHECK-NEXT: call void @llvm.amdgcn.s.prefetch.data.p0(ptr [[TMP0]], i32 0) +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(1), ptr addrspace(5) [[GP_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(5) [[LEN_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.amdgcn.s.prefetch.data.p1(ptr addrspace(1) [[TMP1]], i32 [[TMP2]]) +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(5) [[CP_ADDR]], align 8 +// CHECK-NEXT: call void @llvm.amdgcn.s.prefetch.data.p4(ptr addrspace(4) [[TMP3]], i32 31) +// CHECK-NEXT: ret void +// +void test_s_prefetch_data(int *fp, global float *gp, constant char *cp, unsigned int len) +{ + __builtin_amdgcn_s_prefetch_data(fp, 0); + __builtin_amdgcn_s_prefetch_data(gp, len); + __builtin_amdgcn_s_prefetch_data(cp, 31); +} diff --git a/clang/test/CodeGenSYCL/address-space-deduction.cpp b/clang/test/CodeGenSYCL/address-space-deduction.cpp index 96075a47343fe..5910ec3bfc305 100644 --- a/clang/test/CodeGenSYCL/address-space-deduction.cpp +++ b/clang/test/CodeGenSYCL/address-space-deduction.cpp @@ -33,55 +33,55 @@ // CHECK-NEXT: store ptr addrspace(4) [[I_ASCAST]], ptr addrspace(4) [[PPTR_ASCAST]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[PPTR_ASCAST]], align 8 // CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(4) [[TMP0]], [[I_ASCAST]] -// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[CMP]] to i8 -// CHECK-NEXT: store i8 [[FROMBOOL]], ptr addrspace(4) [[IS_I_PTR_ASCAST]], align 1 +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[CMP]] to i8 +// CHECK-NEXT: store i8 [[STOREDV]], ptr addrspace(4) [[IS_I_PTR_ASCAST]], align 1 // CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[PPTR_ASCAST]], align 8 // CHECK-NEXT: store i32 66, ptr addrspace(4) [[TMP1]], align 4 // CHECK-NEXT: store i32 23, ptr addrspace(4) [[VAR23_ASCAST]], align 4 // CHECK-NEXT: store ptr addrspace(4) [[VAR23_ASCAST]], ptr addrspace(4) [[CP_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[CP_ASCAST]], align 8 -// CHECK-NEXT: store i8 41, ptr addrspace(4) [[TMP3]], align 1 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[CP_ASCAST]], align 8 +// CHECK-NEXT: store i8 41, ptr addrspace(4) [[TMP2]], align 1 // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [42 x i32], ptr addrspace(4) [[ARR_ASCAST]], i64 0, i64 0 // CHECK-NEXT: store ptr addrspace(4) [[ARRAYDECAY]], ptr addrspace(4) [[CPP_ASCAST]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[CPP_ASCAST]], align 8 -// CHECK-NEXT: store i8 43, ptr addrspace(4) [[TMP5]], align 1 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[CPP_ASCAST]], align 8 +// CHECK-NEXT: store i8 43, ptr addrspace(4) [[TMP3]], align 1 // CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [42 x i32], ptr addrspace(4) [[ARR_ASCAST]], i64 0, i64 0 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr addrspace(4) [[ARRAYDECAY1]], i64 10 // CHECK-NEXT: store ptr addrspace(4) [[ADD_PTR]], ptr addrspace(4) [[APTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[APTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[APTR_ASCAST]], align 8 // CHECK-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [42 x i32], ptr addrspace(4) [[ARR_ASCAST]], i64 0, i64 0 -// CHECK-NEXT: [[ADD_PTR3:%.*]] = getelementptr inbounds i32, ptr addrspace(4) [[ARRAYDECAY2]], i64 168 -// CHECK-NEXT: [[CMP4:%.*]] = icmp ult ptr addrspace(4) [[TMP6]], [[ADD_PTR3]] +// CHECK-NEXT: [[ADD_PTR3:%.*]] = getelementptr inbounds nuw i32, ptr addrspace(4) [[ARRAYDECAY2]], i64 168 +// CHECK-NEXT: [[CMP4:%.*]] = icmp ult ptr addrspace(4) [[TMP4]], [[ADD_PTR3]] // CHECK-NEXT: br i1 [[CMP4]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] // CHECK: if.then: -// CHECK-NEXT: [[TMP7:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[APTR_ASCAST]], align 8 -// CHECK-NEXT: store i32 44, ptr addrspace(4) [[TMP7]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[APTR_ASCAST]], align 8 +// CHECK-NEXT: store i32 44, ptr addrspace(4) [[TMP5]], align 4 // CHECK-NEXT: br label [[IF_END]] // CHECK: if.end: // CHECK-NEXT: store ptr addrspace(4) addrspacecast (ptr addrspace(1) @.str to ptr addrspace(4)), ptr addrspace(4) [[STR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP8:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[STR_ASCAST]], align 8 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[TMP8]], i64 0 -// CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr addrspace(4) [[ARRAYIDX]], align 1 -// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP9]] to i32 +// CHECK-NEXT: [[TMP6:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[STR_ASCAST]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[TMP6]], i64 0 +// CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr addrspace(4) [[ARRAYIDX]], align 1 +// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP7]] to i32 // CHECK-NEXT: store i32 [[CONV]], ptr addrspace(4) [[I_ASCAST]], align 4 -// CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr addrspace(4) [[I_ASCAST]], align 4 -// CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP10]], 2 +// CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr addrspace(4) [[I_ASCAST]], align 4 +// CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP8]], 2 // CHECK-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK: cond.true: -// CHECK-NEXT: [[TMP11:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[STR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP9:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[STR_ASCAST]], align 8 // CHECK-NEXT: br label [[COND_END:%.*]] // CHECK: cond.false: // CHECK-NEXT: br label [[COND_END]] // CHECK: cond.end: -// CHECK-NEXT: [[COND:%.*]] = phi ptr addrspace(4) [ [[TMP11]], [[COND_TRUE]] ], [ addrspacecast (ptr addrspace(1) @.str.1 to ptr addrspace(4)), [[COND_FALSE]] ] +// CHECK-NEXT: [[COND:%.*]] = phi ptr addrspace(4) [ [[TMP9]], [[COND_TRUE]] ], [ addrspacecast (ptr addrspace(1) @.str.1 to ptr addrspace(4)), [[COND_FALSE]] ] // CHECK-NEXT: store ptr addrspace(4) [[COND]], ptr addrspace(4) [[PHI_STR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr addrspace(4) [[I_ASCAST]], align 4 -// CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP12]], 2 -// CHECK-NEXT: [[TMP13:%.*]] = zext i1 [[CMP6]] to i64 +// CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr addrspace(4) [[I_ASCAST]], align 4 +// CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP10]], 2 +// CHECK-NEXT: [[TMP11:%.*]] = zext i1 [[CMP6]] to i64 // CHECK-NEXT: [[COND7:%.*]] = select i1 [[CMP6]], ptr addrspace(4) addrspacecast (ptr addrspace(1) @.str.2 to ptr addrspace(4)), ptr addrspace(4) null // CHECK-NEXT: store ptr addrspace(4) [[COND7]], ptr addrspace(4) [[SELECT_NULL_ASCAST]], align 8 -// CHECK-NEXT: [[TMP14:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[STR_ASCAST]], align 8 -// CHECK-NEXT: store ptr addrspace(4) [[TMP14]], ptr addrspace(4) [[SELECT_STR_TRIVIAL1_ASCAST]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[STR_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[TMP12]], ptr addrspace(4) [[SELECT_STR_TRIVIAL1_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) addrspacecast (ptr addrspace(1) @.str.1 to ptr addrspace(4)), ptr addrspace(4) [[SELECT_STR_TRIVIAL2_ASCAST]], align 8 // CHECK-NEXT: ret void // diff --git a/clang/test/Driver/Ofast.c b/clang/test/Driver/Ofast.c index 91de296a4c3ff..b5189e951cc68 100644 --- a/clang/test/Driver/Ofast.c +++ b/clang/test/Driver/Ofast.c @@ -1,14 +1,14 @@ -// RUN: %clang -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s -// RUN: %clang -O2 -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s -// RUN: %clang -fno-fast-math -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s -// RUN: %clang -fno-strict-aliasing -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s -// RUN: %clang -fno-vectorize -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s -// RUN: %clang -Ofast -O2 -### -Werror %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 \ +// RUN: %clang -c -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -c -O2 -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -c -fno-fast-math -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -c -fno-strict-aliasing -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -c -fno-vectorize -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -c -Ofast -O2 -### -Werror %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 \ // RUN: %if target={{.*-windows-msvc.*}} %{ --check-prefix=CHECK-OFAST-O2-ALIASING-MSVC %} \ // RUN: %else %{ --check-prefix=CHECK-OFAST-O2-ALIASING %} %s -// RUN: %clang -Ofast -fno-fast-math -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-FAST-MATH %s -// RUN: %clang -Ofast -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-STRICT-ALIASING %s -// RUN: %clang -Ofast -fno-vectorize -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-VECTORIZE %s +// RUN: %clang -c -Ofast -fno-fast-math -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-FAST-MATH %s +// RUN: %clang -c -Ofast -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-STRICT-ALIASING %s +// RUN: %clang -c -Ofast -fno-vectorize -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-VECTORIZE %s // CHECK-OFAST: use '-O3 -ffast-math' for the same behavior, or '-O3' to enable only conforming optimizations // CHECK-OFAST: -cc1 diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index d69cd199ac61d..335fa546a1388 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -600,10 +600,12 @@ // CHECK_NO_DISABLE_DIRECT-NOT: -fobjc-disable-direct-methods-for-testing // RUN: %clang -### -S -fjmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s -// RUN: %clang -### -S -fjmc -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN_NOT_ELF,CHECK_NOJMC %s +// RUN: %clang -### -S -fjmc -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s +// RUN: %clang -### -S -fjmc -g -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK_JMC %s +// RUN: %clang -### -S -fjmc -g -fno-jmc -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC %s // RUN: %clang -### -S -fjmc -g -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_JMC %s // RUN: %clang -### -S -fjmc -g -fno-jmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC %s -// RUN: %clang -### -fjmc -g -flto -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN_NOT_ELF,CHECK_NOJMC_LTO %s +// RUN: %clang -### -fjmc -g -flto -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC_LTO %s // RUN: %clang -### -fjmc -g -flto -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_JMC_LTO %s // RUN: %clang -### -fjmc -g -flto -fno-jmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC_LTO %s // CHECK_JMC_WARN: -fjmc requires debug info. Use -g or debug options that enable debugger's stepping function; option ignored diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index f86c978f221cd..6ecf0b57bee5c 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -197,6 +197,8 @@ // CHECK-SANMT-MT: "-target-feature" "+mte" // CHECK-SANMT-MT-SAME: "-fsanitize=memtag-stack,memtag-heap,memtag-globals" +// RUN: not %clang --target=aarch64-linux -fsanitize=memtag -Xclang -target-feature -Xclang +mte %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-MT + // RUN: not %clang --target=aarch64-linux -fsanitize=memtag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-NOMT-0 // CHECK-SANMT-NOMT-0: '-fsanitize=memtag-stack' requires hardware support (+memtag) @@ -726,8 +728,8 @@ // NO-SP-NOT: stack-protector // NO-SP: "-fsanitize=safe-stack" // SP-ASAN: error: invalid argument '-fsanitize=safe-stack' not allowed with '-fsanitize=address' -// SP: "-fsanitize=safe-stack" // SP: -stack-protector +// SP: "-fsanitize=safe-stack" // NO-SP-NOT: stack-protector // RUN: %clang --target=powerpc64-unknown-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-SANM diff --git a/clang/test/Driver/fuchsia.c b/clang/test/Driver/fuchsia.c index c67f7f8c005b3..83dee16981690 100644 --- a/clang/test/Driver/fuchsia.c +++ b/clang/test/Driver/fuchsia.c @@ -30,10 +30,10 @@ // CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" +// CHECK: "-stack-protector" "2" // CHECK-AARCH64: "-fsanitize=shadow-call-stack" // CHECK-RISCV64: "-fsanitize=shadow-call-stack" // CHECK-X86_64: "-fsanitize=safe-stack" -// CHECK: "-stack-protector" "2" // CHECK-AARCH64: "-target-feature" "+outline-atomics" // CHECK-NOT: "-fcommon" // CHECK: {{.*}}ld.lld{{.*}}" "-z" "max-page-size=4096" "-z" "now" "-z" "start-stop-visibility=hidden" "-z" "rodynamic" "-z" "separate-loadable-segments" "-z" "rel" "--pack-dyn-relocs=relr" diff --git a/clang/test/Driver/ps4-ps5-toolchain.c b/clang/test/Driver/ps4-ps5-toolchain.c index 444e9df24714b..c9987c2b5758b 100644 --- a/clang/test/Driver/ps4-ps5-toolchain.c +++ b/clang/test/Driver/ps4-ps5-toolchain.c @@ -11,3 +11,8 @@ // RUN: %clang %s -### -target x86_64-sie-ps5 -flto 2>&1 | FileCheck %s --check-prefix=LTO // LTO-NOT: error: // LTO-NOT: unable to pass LLVM bit-code + +// Verify that the jump table sizes section is enabled. +// RUN: %clang %s -target x86_64-sie-ps5 -### 2>&1 | FileCheck -check-prefix=JUMPTABLESIZES %s +// JUMPTABLESIZES: "-mllvm" "-emit-jump-table-sizes-section" +// JUMPTABLESIZES: "-plugin-opt=-emit-jump-table-sizes-section" diff --git a/clang/test/Driver/ps4-sdk-root.c b/clang/test/Driver/ps4-sdk-root.c index e1a04522030c1..3e02fa9fc3bc2 100644 --- a/clang/test/Driver/ps4-sdk-root.c +++ b/clang/test/Driver/ps4-sdk-root.c @@ -6,9 +6,8 @@ // Check that PS4 clang doesn't report a warning message when locating // system libraries (either by looking at the value of SCE_ORBIS_SDK_DIR -// or relative to the location of the compiler driver), if "-c", "-S", "-E", -// "--sysroot", "-nostdlib" or "-nodefaultlibs" option is specified on -// the command line. +// or relative to the location of the compiler driver), if "-c", "-S", "-E" +// or "--sysroot" option is specified on the command line. // Otherwise, check that PS4 clang reports a warning. // Setting up SCE_ORBIS_SDK_DIR to existing location, which is not a PS4 SDK. @@ -36,9 +35,6 @@ // RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s // RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### --sysroot=foo/ -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s -// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -nostdlib -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s -// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -nodefaultlibs -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s - // NO-WARN-NOT: {{warning:|error:}} // WARN-SYS-HEADERS: warning: unable to find PS4 system headers directory // WARN-ISYSROOT: warning: no such sysroot directory: 'foo' diff --git a/clang/test/Driver/ps5-sdk-root.c b/clang/test/Driver/ps5-sdk-root.c index c3672aef9dc0c..2a82d8e72283b 100644 --- a/clang/test/Driver/ps5-sdk-root.c +++ b/clang/test/Driver/ps5-sdk-root.c @@ -8,12 +8,11 @@ // Check that PS5 clang doesn't report a warning message when locating // system libraries (either by looking at the value of SCE_PROSPERO_SDK_DIR -// or relative to the location of the compiler driver), if "-c", "-S", "-E", -// "--sysroot", "-nostdlib" or "-nodefaultlibs" option is specified on -// the command line. +// or relative to the location of the compiler driver), if "-c", "-S", "-E" +// or "--sysroot" option is specified on the command line. // Otherwise, check that PS5 clang reports a warning. -// Setting up SCE_PROSPERO_SDK_DIR to existing location, which is not a PS4 SDK. +// Setting up SCE_PROSPERO_SDK_DIR to existing location, which is not a PS5 SDK. // RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s // RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s @@ -38,9 +37,6 @@ // RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s // RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### --sysroot=foo/ -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s -// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -nostdlib -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s -// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -nodefaultlibs -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s - // NO-WARN-NOT: {{warning:|error:}} // WARN-SYS-HEADERS: warning: unable to find PS5 system headers directory // WARN-ISYSROOT: warning: no such sysroot directory: 'foo' diff --git a/clang/test/ExtractAPI/attributed-typedef.m b/clang/test/ExtractAPI/attributed-typedef.m new file mode 100644 index 0000000000000..c948c873ab759 --- /dev/null +++ b/clang/test/ExtractAPI/attributed-typedef.m @@ -0,0 +1,24 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \ +// RUN: -triple arm64-apple-macosx -x objective-c-header %s -o %t/output.symbols.json + +_Pragma("clang assume_nonnull begin") + +struct Foo { int a; }; +typedef struct Foo *Bar; +// RUN: FileCheck %s -input-file %t/output.symbols.json --check-prefix FUNC +void func(Bar b); +// FUNC-LABEL: "!testLabel": "c:@F@func", +// CHECK-NOT: Foo +// CHECK: "pathComponents" + +// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix THING +#define SWIFT_NAME(_name) __attribute__((swift_name(#_name))) +extern Bar const thing SWIFT_NAME(swiftThing); +// THING-LABEL: "!testLabel": "c:@thing" +// THING-NOT: Foo +// THING: "pathComponents" + +_Pragma("clang assume_nonnull end") + +// expected-no-diagnostics diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index 9d202e0d04682..e4254d1e64bec 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -47,7 +47,7 @@ typedef unsigned long long uint64_t; // CHECK-NEXT: [[CONV5_I:%.*]] = zext nneg i8 [[TMP0]] to i64 // CHECK-NEXT: [[ADD_I:%.*]] = add i64 [[MUL_I]], -48 // CHECK-NEXT: [[SUB_I:%.*]] = add i64 [[ADD_I]], [[CONV5_I]] -// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I]], i64 1 +// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I]], i64 1 // CHECK-NEXT: br label [[CLEANUP_I]] // CHECK: cleanup.i: // CHECK-NEXT: [[__TAGP_ADDR_1_I]] = phi ptr [ [[INCDEC_PTR_I]], [[IF_THEN_I]] ], [ [[__TAGP_ADDR_0_I]], [[WHILE_BODY_I]] ] @@ -79,7 +79,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base8(const char *p) { // CHECK-NEXT: [[CONV5_I:%.*]] = zext nneg i8 [[TMP0]] to i64 // CHECK-NEXT: [[ADD_I:%.*]] = add i64 [[MUL_I]], -48 // CHECK-NEXT: [[SUB_I:%.*]] = add i64 [[ADD_I]], [[CONV5_I]] -// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I]], i64 1 +// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I]], i64 1 // CHECK-NEXT: br label [[CLEANUP_I]] // CHECK: cleanup.i: // CHECK-NEXT: [[__TAGP_ADDR_1_I]] = phi ptr [ [[INCDEC_PTR_I]], [[IF_THEN_I]] ], [ [[__TAGP_ADDR_0_I]], [[WHILE_BODY_I]] ] @@ -120,7 +120,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base10(const char *p) { // CHECK-NEXT: [[CONV25_I:%.*]] = zext nneg i8 [[TMP0]] to i64 // CHECK-NEXT: [[ADD26_I:%.*]] = add i64 [[MUL24_I]], [[DOTSINK]] // CHECK-NEXT: [[ADD28_I:%.*]] = add i64 [[ADD26_I]], [[CONV25_I]] -// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I]], i64 1 +// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I]], i64 1 // CHECK-NEXT: br label [[CLEANUP_I]] // CHECK: cleanup.i: // CHECK-NEXT: [[__TAGP_ADDR_1_I]] = phi ptr [ [[INCDEC_PTR_I]], [[IF_END31_I]] ], [ [[__TAGP_ADDR_0_I]], [[IF_ELSE17_I]] ] @@ -141,7 +141,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) { // CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i8 [[TMP0]], 48 // CHECK-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[WHILE_COND_I14_I:%.*]] // CHECK: if.then.i: -// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1 +// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 1 // CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I]], align 1, !tbaa [[TBAA4]] // CHECK-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I:%.*]] [ // CHECK-NEXT: i8 120, label [[WHILE_COND_I30_I_PREHEADER:%.*]] @@ -173,7 +173,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) { // CHECK-NEXT: [[CONV25_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64 // CHECK-NEXT: [[ADD26_I_I:%.*]] = add i64 [[MUL24_I_I]], [[DOTSINK]] // CHECK-NEXT: [[ADD28_I_I:%.*]] = add i64 [[ADD26_I_I]], [[CONV25_I_I]] -// CHECK-NEXT: [[INCDEC_PTR_I40_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I]], i64 1 +// CHECK-NEXT: [[INCDEC_PTR_I40_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I31_I]], i64 1 // CHECK-NEXT: br label [[CLEANUP_I36_I]] // CHECK: cleanup.i36.i: // CHECK-NEXT: [[__TAGP_ADDR_1_I37_I]] = phi ptr [ [[INCDEC_PTR_I40_I]], [[IF_END31_I_I]] ], [ [[__TAGP_ADDR_0_I31_I]], [[IF_ELSE17_I_I]] ] @@ -195,7 +195,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) { // CHECK-NEXT: [[CONV5_I_I:%.*]] = zext nneg i8 [[TMP6]] to i64 // CHECK-NEXT: [[ADD_I_I:%.*]] = add i64 [[MUL_I_I]], -48 // CHECK-NEXT: [[SUB_I_I:%.*]] = add i64 [[ADD_I_I]], [[CONV5_I_I]] -// CHECK-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I_I]], i64 1 +// CHECK-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I_I]], i64 1 // CHECK-NEXT: br label [[CLEANUP_I_I]] // CHECK: cleanup.i.i: // CHECK-NEXT: [[__TAGP_ADDR_1_I_I]] = phi ptr [ [[INCDEC_PTR_I_I]], [[IF_THEN_I_I]] ], [ [[__TAGP_ADDR_0_I_I]], [[WHILE_BODY_I_I]] ] @@ -216,7 +216,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) { // CHECK-NEXT: [[CONV5_I26_I:%.*]] = zext nneg i8 [[TMP8]] to i64 // CHECK-NEXT: [[ADD_I27_I:%.*]] = add i64 [[MUL_I25_I]], -48 // CHECK-NEXT: [[SUB_I28_I:%.*]] = add i64 [[ADD_I27_I]], [[CONV5_I26_I]] -// CHECK-NEXT: [[INCDEC_PTR_I29_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I]], i64 1 +// CHECK-NEXT: [[INCDEC_PTR_I29_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I15_I]], i64 1 // CHECK-NEXT: br label [[CLEANUP_I20_I]] // CHECK: cleanup.i20.i: // CHECK-NEXT: [[__TAGP_ADDR_1_I21_I]] = phi ptr [ [[INCDEC_PTR_I29_I]], [[IF_THEN_I24_I]] ], [ [[__TAGP_ADDR_0_I15_I]], [[WHILE_BODY_I18_I]] ] @@ -2367,7 +2367,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // DEFAULT-NEXT: [[CMP_I_I:%.*]] = icmp eq i8 [[TMP0]], 48 // DEFAULT-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[WHILE_COND_I14_I_I:%.*]] // DEFAULT: if.then.i.i: -// DEFAULT-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TAG]], i64 1 // DEFAULT-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]] // DEFAULT-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [ // DEFAULT-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]] @@ -2399,7 +2399,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // DEFAULT-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64 // DEFAULT-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]] // DEFAULT-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 // DEFAULT-NEXT: br label [[CLEANUP_I36_I_I]] // DEFAULT: cleanup.i36.i.i: // DEFAULT-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ] @@ -2421,7 +2421,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // DEFAULT-NEXT: [[CONV5_I_I_I:%.*]] = zext nneg i8 [[TMP6]] to i64 // DEFAULT-NEXT: [[ADD_I_I_I:%.*]] = add i64 [[MUL_I_I_I]], -48 // DEFAULT-NEXT: [[SUB_I_I_I:%.*]] = add i64 [[ADD_I_I_I]], [[CONV5_I_I_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 // DEFAULT-NEXT: br label [[CLEANUP_I_I_I]] // DEFAULT: cleanup.i.i.i: // DEFAULT-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ] @@ -2442,7 +2442,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // DEFAULT-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64 // DEFAULT-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48 // DEFAULT-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 // DEFAULT-NEXT: br label [[CLEANUP_I20_I_I]] // DEFAULT: cleanup.i20.i.i: // DEFAULT-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ] @@ -2466,7 +2466,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // APPROX-NEXT: [[CMP_I_I:%.*]] = icmp eq i8 [[TMP0]], 48 // APPROX-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[WHILE_COND_I14_I_I:%.*]] // APPROX: if.then.i.i: -// APPROX-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TAG]], i64 1 // APPROX-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]] // APPROX-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [ // APPROX-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]] @@ -2498,7 +2498,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // APPROX-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64 // APPROX-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]] // APPROX-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]] -// APPROX-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 // APPROX-NEXT: br label [[CLEANUP_I36_I_I]] // APPROX: cleanup.i36.i.i: // APPROX-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ] @@ -2520,7 +2520,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // APPROX-NEXT: [[CONV5_I_I_I:%.*]] = zext nneg i8 [[TMP6]] to i64 // APPROX-NEXT: [[ADD_I_I_I:%.*]] = add i64 [[MUL_I_I_I]], -48 // APPROX-NEXT: [[SUB_I_I_I:%.*]] = add i64 [[ADD_I_I_I]], [[CONV5_I_I_I]] -// APPROX-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 // APPROX-NEXT: br label [[CLEANUP_I_I_I]] // APPROX: cleanup.i.i.i: // APPROX-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ] @@ -2541,7 +2541,7 @@ extern "C" __device__ double test_modf(double x, double* y) { // APPROX-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64 // APPROX-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48 // APPROX-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]] -// APPROX-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 // APPROX-NEXT: br label [[CLEANUP_I20_I_I]] // APPROX: cleanup.i20.i.i: // APPROX-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ] @@ -2565,7 +2565,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // DEFAULT-NEXT: [[CMP_I_I:%.*]] = icmp eq i8 [[TMP0]], 48 // DEFAULT-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[WHILE_COND_I14_I_I:%.*]] // DEFAULT: if.then.i.i: -// DEFAULT-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TAG]], i64 1 // DEFAULT-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]] // DEFAULT-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [ // DEFAULT-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]] @@ -2597,7 +2597,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // DEFAULT-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64 // DEFAULT-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]] // DEFAULT-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 // DEFAULT-NEXT: br label [[CLEANUP_I36_I_I]] // DEFAULT: cleanup.i36.i.i: // DEFAULT-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ] @@ -2619,7 +2619,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // DEFAULT-NEXT: [[CONV5_I_I_I:%.*]] = zext nneg i8 [[TMP6]] to i64 // DEFAULT-NEXT: [[ADD_I_I_I:%.*]] = add i64 [[MUL_I_I_I]], -48 // DEFAULT-NEXT: [[SUB_I_I_I:%.*]] = add i64 [[ADD_I_I_I]], [[CONV5_I_I_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 // DEFAULT-NEXT: br label [[CLEANUP_I_I_I]] // DEFAULT: cleanup.i.i.i: // DEFAULT-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ] @@ -2640,7 +2640,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // DEFAULT-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64 // DEFAULT-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48 // DEFAULT-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 +// DEFAULT-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 // DEFAULT-NEXT: br label [[CLEANUP_I20_I_I]] // DEFAULT: cleanup.i20.i.i: // DEFAULT-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ] @@ -2663,7 +2663,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // APPROX-NEXT: [[CMP_I_I:%.*]] = icmp eq i8 [[TMP0]], 48 // APPROX-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[WHILE_COND_I14_I_I:%.*]] // APPROX: if.then.i.i: -// APPROX-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TAG]], i64 1 // APPROX-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]] // APPROX-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [ // APPROX-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]] @@ -2695,7 +2695,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // APPROX-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64 // APPROX-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]] // APPROX-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]] -// APPROX-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1 // APPROX-NEXT: br label [[CLEANUP_I36_I_I]] // APPROX: cleanup.i36.i.i: // APPROX-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ] @@ -2717,7 +2717,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // APPROX-NEXT: [[CONV5_I_I_I:%.*]] = zext nneg i8 [[TMP6]] to i64 // APPROX-NEXT: [[ADD_I_I_I:%.*]] = add i64 [[MUL_I_I_I]], -48 // APPROX-NEXT: [[SUB_I_I_I:%.*]] = add i64 [[ADD_I_I_I]], [[CONV5_I_I_I]] -// APPROX-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I_I_I]], i64 1 // APPROX-NEXT: br label [[CLEANUP_I_I_I]] // APPROX: cleanup.i.i.i: // APPROX-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ] @@ -2738,7 +2738,7 @@ extern "C" __device__ float test_nanf(const char *tag) { // APPROX-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64 // APPROX-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48 // APPROX-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]] -// APPROX-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 +// APPROX-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1 // APPROX-NEXT: br label [[CLEANUP_I20_I_I]] // APPROX: cleanup.i20.i.i: // APPROX-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ] @@ -3059,7 +3059,7 @@ extern "C" __device__ double test_normcdfinv(double x) { // DEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[__A_ADDR_0_I3]], align 4, !tbaa [[TBAA16]] // DEFAULT-NEXT: [[MUL_I:%.*]] = fmul contract float [[TMP0]], [[TMP0]] // DEFAULT-NEXT: [[ADD_I]] = fadd contract float [[__R_0_I4]], [[MUL_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 4 +// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 4 // DEFAULT-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // DEFAULT-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL5NORMFIPKF_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP20:![0-9]+]] // DEFAULT: _ZL5normfiPKf.exit: @@ -3079,7 +3079,7 @@ extern "C" __device__ double test_normcdfinv(double x) { // FINITEONLY-NEXT: [[TMP0:%.*]] = load float, ptr [[__A_ADDR_0_I3]], align 4, !tbaa [[TBAA16]] // FINITEONLY-NEXT: [[MUL_I:%.*]] = fmul nnan ninf contract float [[TMP0]], [[TMP0]] // FINITEONLY-NEXT: [[ADD_I]] = fadd nnan ninf contract float [[__R_0_I4]], [[MUL_I]] -// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 4 +// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 4 // FINITEONLY-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // FINITEONLY-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL5NORMFIPKF_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP20:![0-9]+]] // FINITEONLY: _ZL5normfiPKf.exit: @@ -3099,7 +3099,7 @@ extern "C" __device__ double test_normcdfinv(double x) { // APPROX-NEXT: [[TMP0:%.*]] = load float, ptr [[__A_ADDR_0_I3]], align 4, !tbaa [[TBAA16]] // APPROX-NEXT: [[MUL_I:%.*]] = fmul contract float [[TMP0]], [[TMP0]] // APPROX-NEXT: [[ADD_I]] = fadd contract float [[__R_0_I4]], [[MUL_I]] -// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 4 +// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 4 // APPROX-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // APPROX-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL5NORMFIPKF_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP20:![0-9]+]] // APPROX: _ZL5normfiPKf.exit: @@ -3123,7 +3123,7 @@ extern "C" __device__ float test_normf(int x, const float *y) { // DEFAULT-NEXT: [[TMP0:%.*]] = load double, ptr [[__A_ADDR_0_I3]], align 8, !tbaa [[TBAA18]] // DEFAULT-NEXT: [[MUL_I:%.*]] = fmul contract double [[TMP0]], [[TMP0]] // DEFAULT-NEXT: [[ADD_I]] = fadd contract double [[__R_0_I4]], [[MUL_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 8 +// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 8 // DEFAULT-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // DEFAULT-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL4NORMIPKD_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP21:![0-9]+]] // DEFAULT: _ZL4normiPKd.exit: @@ -3143,7 +3143,7 @@ extern "C" __device__ float test_normf(int x, const float *y) { // FINITEONLY-NEXT: [[TMP0:%.*]] = load double, ptr [[__A_ADDR_0_I3]], align 8, !tbaa [[TBAA18]] // FINITEONLY-NEXT: [[MUL_I:%.*]] = fmul nnan ninf contract double [[TMP0]], [[TMP0]] // FINITEONLY-NEXT: [[ADD_I]] = fadd nnan ninf contract double [[__R_0_I4]], [[MUL_I]] -// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 8 +// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 8 // FINITEONLY-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // FINITEONLY-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL4NORMIPKD_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP21:![0-9]+]] // FINITEONLY: _ZL4normiPKd.exit: @@ -3163,7 +3163,7 @@ extern "C" __device__ float test_normf(int x, const float *y) { // APPROX-NEXT: [[TMP0:%.*]] = load double, ptr [[__A_ADDR_0_I3]], align 8, !tbaa [[TBAA18]] // APPROX-NEXT: [[MUL_I:%.*]] = fmul contract double [[TMP0]], [[TMP0]] // APPROX-NEXT: [[ADD_I]] = fadd contract double [[__R_0_I4]], [[MUL_I]] -// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 8 +// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 8 // APPROX-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // APPROX-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL4NORMIPKD_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP21:![0-9]+]] // APPROX: _ZL4normiPKd.exit: @@ -3483,7 +3483,7 @@ extern "C" __device__ double test_rint(double x) { // DEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[__A_ADDR_0_I3]], align 4, !tbaa [[TBAA16]] // DEFAULT-NEXT: [[MUL_I:%.*]] = fmul contract float [[TMP0]], [[TMP0]] // DEFAULT-NEXT: [[ADD_I]] = fadd contract float [[__R_0_I4]], [[MUL_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 4 +// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 4 // DEFAULT-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // DEFAULT-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL6RNORMFIPKF_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP22:![0-9]+]] // DEFAULT: _ZL6rnormfiPKf.exit: @@ -3503,7 +3503,7 @@ extern "C" __device__ double test_rint(double x) { // FINITEONLY-NEXT: [[TMP0:%.*]] = load float, ptr [[__A_ADDR_0_I3]], align 4, !tbaa [[TBAA16]] // FINITEONLY-NEXT: [[MUL_I:%.*]] = fmul nnan ninf contract float [[TMP0]], [[TMP0]] // FINITEONLY-NEXT: [[ADD_I]] = fadd nnan ninf contract float [[__R_0_I4]], [[MUL_I]] -// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 4 +// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 4 // FINITEONLY-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // FINITEONLY-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL6RNORMFIPKF_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP22:![0-9]+]] // FINITEONLY: _ZL6rnormfiPKf.exit: @@ -3523,7 +3523,7 @@ extern "C" __device__ double test_rint(double x) { // APPROX-NEXT: [[TMP0:%.*]] = load float, ptr [[__A_ADDR_0_I3]], align 4, !tbaa [[TBAA16]] // APPROX-NEXT: [[MUL_I:%.*]] = fmul contract float [[TMP0]], [[TMP0]] // APPROX-NEXT: [[ADD_I]] = fadd contract float [[__R_0_I4]], [[MUL_I]] -// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 4 +// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 4 // APPROX-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // APPROX-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL6RNORMFIPKF_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP22:![0-9]+]] // APPROX: _ZL6rnormfiPKf.exit: @@ -3547,7 +3547,7 @@ extern "C" __device__ float test_rnormf(int x, const float* y) { // DEFAULT-NEXT: [[TMP0:%.*]] = load double, ptr [[__A_ADDR_0_I3]], align 8, !tbaa [[TBAA18]] // DEFAULT-NEXT: [[MUL_I:%.*]] = fmul contract double [[TMP0]], [[TMP0]] // DEFAULT-NEXT: [[ADD_I]] = fadd contract double [[__R_0_I4]], [[MUL_I]] -// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 8 +// DEFAULT-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 8 // DEFAULT-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // DEFAULT-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL5RNORMIPKD_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP23:![0-9]+]] // DEFAULT: _ZL5rnormiPKd.exit: @@ -3567,7 +3567,7 @@ extern "C" __device__ float test_rnormf(int x, const float* y) { // FINITEONLY-NEXT: [[TMP0:%.*]] = load double, ptr [[__A_ADDR_0_I3]], align 8, !tbaa [[TBAA18]] // FINITEONLY-NEXT: [[MUL_I:%.*]] = fmul nnan ninf contract double [[TMP0]], [[TMP0]] // FINITEONLY-NEXT: [[ADD_I]] = fadd nnan ninf contract double [[__R_0_I4]], [[MUL_I]] -// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 8 +// FINITEONLY-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 8 // FINITEONLY-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // FINITEONLY-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL5RNORMIPKD_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP23:![0-9]+]] // FINITEONLY: _ZL5rnormiPKd.exit: @@ -3587,7 +3587,7 @@ extern "C" __device__ float test_rnormf(int x, const float* y) { // APPROX-NEXT: [[TMP0:%.*]] = load double, ptr [[__A_ADDR_0_I3]], align 8, !tbaa [[TBAA18]] // APPROX-NEXT: [[MUL_I:%.*]] = fmul contract double [[TMP0]], [[TMP0]] // APPROX-NEXT: [[ADD_I]] = fadd contract double [[__R_0_I4]], [[MUL_I]] -// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[__A_ADDR_0_I3]], i64 8 +// APPROX-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds nuw i8, ptr [[__A_ADDR_0_I3]], i64 8 // APPROX-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq i32 [[DEC_I]], 0 // APPROX-NEXT: br i1 [[TOBOOL_NOT_I]], label [[_ZL5RNORMIPKD_EXIT]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP23:![0-9]+]] // APPROX: _ZL5rnormiPKd.exit: diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp index 4a06d29ae9dbc..5b88e00b71508 100644 --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -325,7 +325,7 @@ #error "wrong value for __cpp_range_based_for" #endif -#if check(static_assert, 0, 200410, 200410, 201411, 201411, 201411, 202306) +#if check(static_assert, 0, 202306, 202306, 202306, 202306, 202306, 202306) #error "wrong value for __cpp_static_assert" #endif diff --git a/clang/test/Lexer/has_feature_realtime_sanitizer.cpp b/clang/test/Lexer/has_feature_realtime_sanitizer.cpp new file mode 100644 index 0000000000000..76febeb6473a4 --- /dev/null +++ b/clang/test/Lexer/has_feature_realtime_sanitizer.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -E -fsanitize=realtime %s -o - | FileCheck --check-prefix=CHECK-RTSAN %s +// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-RTSAN %s + +#if __has_feature(realtime_sanitizer) +int RealtimeSanitizerEnabled(); +#else +int RealtimeSanitizerDisabled(); +#endif + +// CHECK-RTSAN: RealtimeSanitizerEnabled + +// CHECK-NO-RTSAN: RealtimeSanitizerDisabled diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 5ebbd29b316bf..eca8633114902 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -82,8 +82,6 @@ // CHECK-NEXT: FunctionReturnThunks (SubjectMatchRule_function) // CHECK-NEXT: GNUInline (SubjectMatchRule_function) // CHECK-NEXT: HIPManaged (SubjectMatchRule_variable) -// CHECK-NEXT: HLSLROV (SubjectMatchRule_record_not_is_union) -// CHECK-NEXT: HLSLResourceClass (SubjectMatchRule_field) // CHECK-NEXT: Hot (SubjectMatchRule_function) // CHECK-NEXT: HybridPatchable (SubjectMatchRule_function) // CHECK-NEXT: IBAction (SubjectMatchRule_objc_method_is_instance) diff --git a/clang/test/OpenMP/bug60602.cpp b/clang/test/OpenMP/bug60602.cpp index cb2e4e5b11e33..0789ef958e523 100644 --- a/clang/test/OpenMP/bug60602.cpp +++ b/clang/test/OpenMP/bug60602.cpp @@ -58,13 +58,13 @@ int kernel_within_loop(int *a, int *b, int N, int num_iters) { // CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i64 0 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i64 0 // CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[N_ADDR]], align 4 // CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP8]] to i64 // CHECK-NEXT: [[TMP9:%.*]] = mul nuw i64 [[CONV]], 4 // CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP11:%.*]] = load ptr, ptr [[B_ADDR]], align 8 -// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP11]], i64 0 +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP11]], i64 0 // CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[N_ADDR]], align 4 // CHECK-NEXT: [[CONV2:%.*]] = sext i32 [[TMP12]] to i64 // CHECK-NEXT: [[TMP13:%.*]] = mul nuw i64 [[CONV2]], 4 @@ -134,13 +134,13 @@ int kernel_within_loop(int *a, int *b, int N, int num_iters) { // CHECK-NEXT: [[TMP46:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP47:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP48:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[TMP48]], i64 0 +// CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP48]], i64 0 // CHECK-NEXT: [[TMP49:%.*]] = load i32, ptr [[N_ADDR]], align 4 // CHECK-NEXT: [[CONV5:%.*]] = sext i32 [[TMP49]] to i64 // CHECK-NEXT: [[TMP50:%.*]] = mul nuw i64 [[CONV5]], 4 // CHECK-NEXT: [[TMP51:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP52:%.*]] = load ptr, ptr [[B_ADDR]], align 8 -// CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[TMP52]], i64 0 +// CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP52]], i64 0 // CHECK-NEXT: [[TMP53:%.*]] = load i32, ptr [[N_ADDR]], align 4 // CHECK-NEXT: [[CONV7:%.*]] = sext i32 [[TMP53]] to i64 // CHECK-NEXT: [[TMP54:%.*]] = mul nuw i64 [[CONV7]], 4 diff --git a/clang/test/OpenMP/declare_mapper_codegen.cpp b/clang/test/OpenMP/declare_mapper_codegen.cpp index 52d5ceffa1471..d2954b7a74821 100644 --- a/clang/test/OpenMP/declare_mapper_codegen.cpp +++ b/clang/test/OpenMP/declare_mapper_codegen.cpp @@ -129,7 +129,7 @@ class C { // CK0-DAG: [[BBEGIN:%.+]] = getelementptr inbounds nuw %class.C, ptr [[PTR]], i32 0, i32 1 // CK0-DAG: [[BBEGIN2:%.+]] = getelementptr inbounds nuw %class.C, ptr [[PTR]], i32 0, i32 1 // CK0-DAG: [[BARRBEGIN:%.+]] = load ptr, ptr [[BBEGIN2]] -// CK0-DAG: [[BARRBEGINGEP:%.+]] = getelementptr inbounds double, ptr [[BARRBEGIN]], i[[sz:64|32]] 0 +// CK0-DAG: [[BARRBEGINGEP:%.+]] = getelementptr inbounds nuw double, ptr [[BARRBEGIN]], i[[sz:64|32]] 0 // CK0-DAG: [[BEND:%.+]] = getelementptr ptr, ptr [[BBEGIN]], i32 1 // CK0-DAG: [[ABEGINI:%.+]] = ptrtoint ptr [[ABEGIN]] to i64 // CK0-DAG: [[BENDI:%.+]] = ptrtoint ptr [[BEND]] to i64 @@ -965,7 +965,7 @@ class C { // CK4-DAG: [[BBEGIN:%.+]] = getelementptr inbounds nuw %class.C, ptr [[PTR]], i32 0, i32 1 // CK4-DAG: [[BBEGIN2:%.+]] = getelementptr inbounds nuw %class.C, ptr [[PTR]], i32 0, i32 1 // CK4-DAG: [[BARRBEGIN:%.+]] = load ptr, ptr [[BBEGIN2]] -// CK4-DAG: [[BARRBEGINGEP:%.+]] = getelementptr inbounds double, ptr [[BARRBEGIN]], i[[sz:64|32]] 0 +// CK4-DAG: [[BARRBEGINGEP:%.+]] = getelementptr inbounds nuw double, ptr [[BARRBEGIN]], i[[sz:64|32]] 0 // CK4-DAG: [[BEND:%.+]] = getelementptr ptr, ptr [[BBEGIN]], i32 1 // CK4-DAG: [[ABEGINI:%.+]] = ptrtoint ptr [[ABEGIN]] to i64 // CK4-DAG: [[BENDI:%.+]] = ptrtoint ptr [[BEND]] to i64 diff --git a/clang/test/OpenMP/distribute_codegen.cpp b/clang/test/OpenMP/distribute_codegen.cpp index ea619cb6e0f26..6c588ba25db30 100644 --- a/clang/test/OpenMP/distribute_codegen.cpp +++ b/clang/test/OpenMP/distribute_codegen.cpp @@ -662,24 +662,24 @@ int fint(void) { return ftemplate(); } // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK1-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK1-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK1-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK1-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK1-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: @@ -1574,21 +1574,21 @@ int fint(void) { return ftemplate(); } // CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i32 [[TMP15]] +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i32 [[TMP15]] // CHECK3-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK3-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i32 [[TMP18]] +// CHECK3-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i32 [[TMP18]] // CHECK3-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[MUL4:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK3-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i32 [[TMP21]] +// CHECK3-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i32 [[TMP21]] // CHECK3-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[MUL6:%.*]] = fmul float [[MUL4]], [[TMP22]] // CHECK3-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK3-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i32 [[TMP24]] +// CHECK3-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i32 [[TMP24]] // CHECK3-NEXT: store float [[MUL6]], ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK3: omp.body.continue: @@ -2252,24 +2252,24 @@ int fint(void) { return ftemplate(); } // CHECK17-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK17-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK17-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK17-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK17-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK17-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK17-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK17-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK17-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK17-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK17-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK17-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK17-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK17-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK17-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK17: omp.body.continue: @@ -2790,21 +2790,21 @@ int fint(void) { return ftemplate(); } // CHECK19-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP12]] -// CHECK19-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i32 [[TMP15]] +// CHECK19-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i32 [[TMP15]] // CHECK19-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP12]] -// CHECK19-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i32 [[TMP18]] +// CHECK19-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i32 [[TMP18]] // CHECK19-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[MUL4:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP12]] -// CHECK19-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i32 [[TMP21]] +// CHECK19-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i32 [[TMP21]] // CHECK19-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[MUL6:%.*]] = fmul float [[MUL4]], [[TMP22]] // CHECK19-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP12]] -// CHECK19-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i32 [[TMP24]] +// CHECK19-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i32 [[TMP24]] // CHECK19-NEXT: store float [[MUL6]], ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP12]] // CHECK19-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK19: omp.body.continue: diff --git a/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp index b019b4ff92ad5..93a6779ac02e8 100644 --- a/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp @@ -175,16 +175,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP3]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP4]], i64 0 // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP6]] // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP7]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP7]], i64 9 // CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP8]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]] @@ -214,7 +214,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP22]] // CHECK1-NEXT: store ptr [[_TMP6]], ptr [[_TMP5]], align 8 // CHECK1-NEXT: store ptr [[TMP23]], ptr [[_TMP6]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP24]], align 8 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -229,19 +229,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP30]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 0 // CHECK1-NEXT: [[TMP32:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds ptr, ptr [[TMP32]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP32]], i64 0 // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[ARRAYIDX8]], align 8 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i8, ptr [[TMP33]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP33]], i64 0 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP35:%.*]] = sext i32 [[TMP34]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN10:%.*]] = add nsw i64 -1, [[TMP35]] // CHECK1-NEXT: [[TMP36:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds ptr, ptr [[TMP36]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP36]], i64 9 // CHECK1-NEXT: [[TMP37:%.*]] = load ptr, ptr [[ARRAYIDX11]], align 8 -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds i8, ptr [[TMP37]], i64 [[LB_ADD_LEN10]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP37]], i64 [[LB_ADD_LEN10]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[TMP38]], align 8 @@ -562,9 +562,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/distribute_simd_codegen.cpp b/clang/test/OpenMP/distribute_simd_codegen.cpp index f7353172e235c..ad93fd6030ac7 100644 --- a/clang/test/OpenMP/distribute_simd_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_codegen.cpp @@ -706,24 +706,24 @@ int fint(void) { return ftemplate(); } // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK1-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK1-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK1-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK1-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK1-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP17]] // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: @@ -1682,21 +1682,21 @@ int fint(void) { return ftemplate(); } // CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i32 [[TMP15]] +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i32 [[TMP15]] // CHECK3-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] -// CHECK3-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i32 [[TMP18]] +// CHECK3-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i32 [[TMP18]] // CHECK3-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[MUL4:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] -// CHECK3-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i32 [[TMP21]] +// CHECK3-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i32 [[TMP21]] // CHECK3-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[MUL6:%.*]] = fmul float [[MUL4]], [[TMP22]] // CHECK3-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] -// CHECK3-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i32 [[TMP24]] +// CHECK3-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i32 [[TMP24]] // CHECK3-NEXT: store float [[MUL6]], ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK3: omp.body.continue: @@ -2664,24 +2664,24 @@ int fint(void) { return ftemplate(); } // CHECK5-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK5-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK5-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK5-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK5-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK5-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK5-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK5: omp.body.continue: @@ -3671,21 +3671,21 @@ int fint(void) { return ftemplate(); } // CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK7-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i32 [[TMP15]] +// CHECK7-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i32 [[TMP15]] // CHECK7-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK7-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i32 [[TMP18]] +// CHECK7-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i32 [[TMP18]] // CHECK7-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[MUL4:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK7-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK7-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i32 [[TMP21]] +// CHECK7-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i32 [[TMP21]] // CHECK7-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[MUL6:%.*]] = fmul float [[MUL4]], [[TMP22]] // CHECK7-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK7-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i32 [[TMP24]] +// CHECK7-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i32 [[TMP24]] // CHECK7-NEXT: store float [[MUL6]], ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK7: omp.body.continue: @@ -4290,24 +4290,24 @@ int fint(void) { return ftemplate(); } // CHECK9-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP5]] to i64 -// CHECK9-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i64 [[IDXPROM]] +// CHECK9-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP4]], i64 [[IDXPROM]] // CHECK9-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[TMP7:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[IDXPROM1:%.*]] = zext i32 [[TMP8]] to i64 -// CHECK9-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i64 [[IDXPROM1]] +// CHECK9-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i64 [[IDXPROM1]] // CHECK9-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[MUL3:%.*]] = fmul float [[TMP6]], [[TMP9]] // CHECK9-NEXT: [[TMP10:%.*]] = load ptr, ptr [[D_ADDR]], align 8, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP11]] to i64 -// CHECK9-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[IDXPROM4]] +// CHECK9-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM4]] // CHECK9-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[MUL6:%.*]] = fmul float [[MUL3]], [[TMP12]] // CHECK9-NEXT: [[TMP13:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP14]] to i64 -// CHECK9-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM7]] +// CHECK9-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM7]] // CHECK9-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4, !llvm.access.group [[ACC_GRP9]] // CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK9: omp.body.continue: @@ -4606,21 +4606,21 @@ int fint(void) { return ftemplate(); } // CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B_ADDR]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] -// CHECK11-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i32 [[TMP5]] +// CHECK11-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP4]], i32 [[TMP5]] // CHECK11-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[TMP7:%.*]] = load ptr, ptr [[C_ADDR]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] -// CHECK11-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i32 [[TMP8]] +// CHECK11-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i32 [[TMP8]] // CHECK11-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX1]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[MUL2:%.*]] = fmul float [[TMP6]], [[TMP9]] // CHECK11-NEXT: [[TMP10:%.*]] = load ptr, ptr [[D_ADDR]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] -// CHECK11-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i32 [[TMP11]] +// CHECK11-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i32 [[TMP11]] // CHECK11-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[MUL4:%.*]] = fmul float [[MUL2]], [[TMP12]] // CHECK11-NEXT: [[TMP13:%.*]] = load ptr, ptr [[A_ADDR]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] -// CHECK11-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i32 [[TMP14]] +// CHECK11-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i32 [[TMP14]] // CHECK11-NEXT: store float [[MUL4]], ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK11: omp.body.continue: @@ -4928,24 +4928,24 @@ int fint(void) { return ftemplate(); } // CHECK13-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP5]] to i64 -// CHECK13-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i64 [[IDXPROM]] +// CHECK13-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP4]], i64 [[IDXPROM]] // CHECK13-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[TMP7:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[IDXPROM1:%.*]] = zext i32 [[TMP8]] to i64 -// CHECK13-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i64 [[IDXPROM1]] +// CHECK13-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i64 [[IDXPROM1]] // CHECK13-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[MUL3:%.*]] = fmul float [[TMP6]], [[TMP9]] // CHECK13-NEXT: [[TMP10:%.*]] = load ptr, ptr [[D_ADDR]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP11]] to i64 -// CHECK13-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[IDXPROM4]] +// CHECK13-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM4]] // CHECK13-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[MUL6:%.*]] = fmul float [[MUL3]], [[TMP12]] // CHECK13-NEXT: [[TMP13:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP14]] to i64 -// CHECK13-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM7]] +// CHECK13-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM7]] // CHECK13-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4, !llvm.access.group [[ACC_GRP10]] // CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK13: omp.body.continue: @@ -5275,21 +5275,21 @@ int fint(void) { return ftemplate(); } // CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B_ADDR]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK15-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i32 [[TMP5]] +// CHECK15-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP4]], i32 [[TMP5]] // CHECK15-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[TMP7:%.*]] = load ptr, ptr [[C_ADDR]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK15-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i32 [[TMP8]] +// CHECK15-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i32 [[TMP8]] // CHECK15-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX1]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[MUL2:%.*]] = fmul float [[TMP6]], [[TMP9]] // CHECK15-NEXT: [[TMP10:%.*]] = load ptr, ptr [[D_ADDR]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK15-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i32 [[TMP11]] +// CHECK15-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i32 [[TMP11]] // CHECK15-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[MUL4:%.*]] = fmul float [[MUL2]], [[TMP12]] // CHECK15-NEXT: [[TMP13:%.*]] = load ptr, ptr [[A_ADDR]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP11]] -// CHECK15-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i32 [[TMP14]] +// CHECK15-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i32 [[TMP14]] // CHECK15-NEXT: store float [[MUL4]], ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP11]] // CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK15: omp.body.continue: @@ -5782,24 +5782,24 @@ int fint(void) { return ftemplate(); } // CHECK17-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK17-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK17-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK17-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK17-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK17-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK17-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK17-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK17-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK17-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK17-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK17-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK17-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK17-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP18]] // CHECK17-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK17: omp.body.continue: @@ -6373,21 +6373,21 @@ int fint(void) { return ftemplate(); } // CHECK19-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK19-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i32 [[TMP15]] +// CHECK19-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i32 [[TMP15]] // CHECK19-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK19-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i32 [[TMP18]] +// CHECK19-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i32 [[TMP18]] // CHECK19-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[MUL4:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK19-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i32 [[TMP21]] +// CHECK19-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i32 [[TMP21]] // CHECK19-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[MUL6:%.*]] = fmul float [[MUL4]], [[TMP22]] // CHECK19-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] -// CHECK19-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i32 [[TMP24]] +// CHECK19-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i32 [[TMP24]] // CHECK19-NEXT: store float [[MUL6]], ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK19-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK19: omp.body.continue: @@ -6970,24 +6970,24 @@ int fint(void) { return ftemplate(); } // CHECK21-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK21-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK21-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK21-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK21-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK21-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK21-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK21-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK21-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK21-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK21-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK21-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK21-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK21-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK21-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP19]] // CHECK21-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK21: omp.body.continue: @@ -7592,21 +7592,21 @@ int fint(void) { return ftemplate(); } // CHECK23-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP20]] -// CHECK23-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i32 [[TMP15]] +// CHECK23-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i32 [[TMP15]] // CHECK23-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP20]] -// CHECK23-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i32 [[TMP18]] +// CHECK23-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i32 [[TMP18]] // CHECK23-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX3]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[MUL4:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK23-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP20]] -// CHECK23-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i32 [[TMP21]] +// CHECK23-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i32 [[TMP21]] // CHECK23-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX5]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[MUL6:%.*]] = fmul float [[MUL4]], [[TMP22]] // CHECK23-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !llvm.access.group [[ACC_GRP20]] -// CHECK23-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i32 [[TMP24]] +// CHECK23-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i32 [[TMP24]] // CHECK23-NEXT: store float [[MUL6]], ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP20]] // CHECK23-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK23: omp.body.continue: diff --git a/clang/test/OpenMP/for_linear_codegen.cpp b/clang/test/OpenMP/for_linear_codegen.cpp index 395ccdbeed763..5a21fe8509fd3 100644 --- a/clang/test/OpenMP/for_linear_codegen.cpp +++ b/clang/test/OpenMP/for_linear_codegen.cpp @@ -650,7 +650,7 @@ int main() { // CHECK1-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP16]], [[MUL9]] // CHECK1-NEXT: store i32 [[ADD10]], ptr [[LVAR5]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = load ptr, ptr [[PVAR4]], align 8 -// CHECK1-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 1 +// CHECK1-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP18]], i32 1 // CHECK1-NEXT: store ptr [[INCDEC_PTR]], ptr [[PVAR4]], align 8 // CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[_TMP6]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 diff --git a/clang/test/OpenMP/for_reduction_codegen.cpp b/clang/test/OpenMP/for_reduction_codegen.cpp index ea32e98bf1423..83632db238484 100644 --- a/clang/test/OpenMP/for_reduction_codegen.cpp +++ b/clang/test/OpenMP/for_reduction_codegen.cpp @@ -1021,14 +1021,14 @@ int main() { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP5:%.*]] = mul nsw i64 1, [[TMP1]] // CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[TMP5]] -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX]], i64 0 // CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [2 x i32], ptr [[TMP3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = sext i32 [[TMP6]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP7]] // CHECK1-NEXT: [[TMP8:%.*]] = mul nsw i64 1, [[TMP1]] // CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[TMP8]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX5]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX5]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX6]] to i64 // CHECK1-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX3]] to i64 // CHECK1-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]] @@ -1054,16 +1054,16 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = sub i64 [[TMP17]], [[TMP18]] // CHECK1-NEXT: [[TMP20:%.*]] = sdiv exact i64 [[TMP19]], ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64) // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i32, ptr [[VLA7]], i64 [[TMP20]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [4 x %struct.S]], ptr [[TMP4]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw [10 x [4 x %struct.S]], ptr [[TMP4]], i64 0, i64 1 // CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[ARRAYIDX8]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i64 1 // CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [2 x i32], ptr [[TMP3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX10]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = sext i32 [[TMP22]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN11:%.*]] = add nsw i64 0, [[TMP23]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [4 x %struct.S]], ptr [[TMP4]], i64 0, i64 [[LB_ADD_LEN11]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw [10 x [4 x %struct.S]], ptr [[TMP4]], i64 0, i64 [[LB_ADD_LEN11]] // CHECK1-NEXT: [[ARRAYDECAY13:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[ARRAYIDX12]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY13]], i64 2 +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY13]], i64 2 // CHECK1-NEXT: [[TMP24:%.*]] = ptrtoint ptr [[ARRAYIDX14]] to i64 // CHECK1-NEXT: [[TMP25:%.*]] = ptrtoint ptr [[ARRAYIDX9]] to i64 // CHECK1-NEXT: [[TMP26:%.*]] = sub i64 [[TMP24]], [[TMP25]] @@ -1580,10 +1580,10 @@ int main() { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = mul nsw i64 1, [[TMP1]] // CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[TMP3]] -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = mul nsw i64 1, [[TMP1]] // CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[TMP4]] -// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX4]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX4]], i64 1 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [1 x [2 x i32]], ptr [[ARR6]], i32 0, i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[ARRAY_BEGIN]], i64 2 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP5]] @@ -1757,13 +1757,13 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP2]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP2]], i64 1 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 4 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP3]], i64 4 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP4]], i64 6 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP4]], i64 6 // CHECK1-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[ARRAYIDX3]] to i64 // CHECK1-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[ARRAYIDX1]] to i64 // CHECK1-NEXT: [[TMP7:%.*]] = sub i64 [[TMP5]], [[TMP6]] @@ -1963,11 +1963,11 @@ int main() { // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 1 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP2]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP2]], i64 1 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 1 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP4]], i64 6 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP4]], i64 6 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [1 x [6 x %struct.S]], ptr [[VAR24]], i32 0, i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr [[STRUCT_S]], ptr [[ARRAY_BEGIN]], i64 6 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP5]] @@ -2148,13 +2148,13 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 1 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP2]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP2]], i64 1 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP3]], i64 1 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP4]], i64 6 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP4]], i64 6 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [1 x [6 x %struct.S]], ptr [[VAR24]], i32 0, i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr [[STRUCT_S]], ptr [[ARRAY_BEGIN]], i64 6 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP5]] @@ -2335,13 +2335,13 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 1 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP2]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP2]], i64 1 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP3]], i64 1 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP4]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP4]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR24]]) // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 8 @@ -2459,8 +2459,8 @@ int main() { // CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x %struct.S], ptr [[TMP0]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [5 x %struct.S], ptr [[TMP0]], i64 0, i64 4 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [5 x %struct.S], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [5 x %struct.S], ptr [[TMP0]], i64 0, i64 4 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [5 x %struct.S], ptr [[VVAR22]], i32 0, i32 0 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_S:%.*]], ptr [[ARRAY_BEGIN]], i64 5 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP1]] @@ -2641,9 +2641,9 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[TMP2]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4 x %struct.S], ptr [[TMP2]], i64 0, i64 1 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[TMP3]], i64 0, i64 2 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [4 x %struct.S], ptr [[TMP3]], i64 0, i64 2 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[VAR34]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_S:%.*]], ptr [[ARRAY_BEGIN]], i64 2 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP4]] @@ -2826,9 +2826,9 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[TMP2]], i64 0, i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4 x %struct.S], ptr [[TMP2]], i64 0, i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[TMP3]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [4 x %struct.S], ptr [[TMP3]], i64 0, i64 1 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[VAR34]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_S:%.*]], ptr [[ARRAY_BEGIN]], i64 2 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP4]] @@ -3012,9 +3012,9 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[TMP2]], i64 0, i64 2 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4 x %struct.S], ptr [[TMP2]], i64 0, i64 2 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[TMP3]], i64 0, i64 3 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [4 x %struct.S], ptr [[TMP3]], i64 0, i64 3 // CHECK1-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[ARRAYIDX3]] to i64 // CHECK1-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK1-NEXT: [[TMP6:%.*]] = sub i64 [[TMP4]], [[TMP5]] @@ -3974,8 +3974,8 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [42 x %struct.S.0], ptr [[TMP0]], i64 0, i64 1 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [42 x %struct.S.0], ptr [[TMP0]], i64 0, i64 40 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [42 x %struct.S.0], ptr [[TMP0]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [42 x %struct.S.0], ptr [[TMP0]], i64 0, i64 40 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [40 x %struct.S.0], ptr [[ARR4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr [[STRUCT_S_0]], ptr [[ARRAY_BEGIN]], i64 40 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP6]] diff --git a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp index 16d6c23542fce..82f94c949eea6 100644 --- a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp +++ b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp @@ -1074,14 +1074,14 @@ int main() { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP5:%.*]] = mul nsw i64 1, [[TMP1]] // CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[TMP5]] -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX]], i64 0 // CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [2 x i32], ptr [[TMP3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = sext i32 [[TMP6]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP7]] // CHECK1-NEXT: [[TMP8:%.*]] = mul nsw i64 1, [[TMP1]] // CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[TMP8]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX5]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX5]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX6]] to i64 // CHECK1-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX3]] to i64 // CHECK1-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]] @@ -1109,16 +1109,16 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = sub i64 [[TMP17]], [[TMP18]] // CHECK1-NEXT: [[TMP20:%.*]] = sdiv exact i64 [[TMP19]], ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64) // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i32, ptr [[VLA7]], i64 [[TMP20]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], ptr [[TMP4]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw [10 x [4 x %struct.S.0]], ptr [[TMP4]], i64 0, i64 1 // CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x %struct.S.0], ptr [[ARRAYIDX9]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], ptr [[ARRAYDECAY]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0:%.*]], ptr [[ARRAYDECAY]], i64 1 // CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [2 x i32], ptr [[TMP3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = sext i32 [[TMP22]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN12:%.*]] = add nsw i64 0, [[TMP23]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], ptr [[TMP4]], i64 0, i64 [[LB_ADD_LEN12]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw [10 x [4 x %struct.S.0]], ptr [[TMP4]], i64 0, i64 [[LB_ADD_LEN12]] // CHECK1-NEXT: [[ARRAYDECAY14:%.*]] = getelementptr inbounds [4 x %struct.S.0], ptr [[ARRAYIDX13]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYDECAY14]], i64 2 +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0]], ptr [[ARRAYDECAY14]], i64 2 // CHECK1-NEXT: [[TMP24:%.*]] = ptrtoint ptr [[ARRAYIDX15]] to i64 // CHECK1-NEXT: [[TMP25:%.*]] = ptrtoint ptr [[ARRAYIDX10]] to i64 // CHECK1-NEXT: [[TMP26:%.*]] = sub i64 [[TMP24]], [[TMP25]] @@ -1669,13 +1669,13 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], ptr [[TMP2]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0:%.*]], ptr [[TMP2]], i64 1 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 4 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP3]], i64 4 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[TMP4]], i64 6 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0]], ptr [[TMP4]], i64 6 // CHECK1-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[ARRAYIDX3]] to i64 // CHECK1-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[ARRAYIDX1]] to i64 // CHECK1-NEXT: [[TMP7:%.*]] = sub i64 [[TMP5]], [[TMP6]] @@ -1877,8 +1877,8 @@ int main() { // CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x %struct.S.0], ptr [[TMP0]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [5 x %struct.S.0], ptr [[TMP0]], i64 0, i64 4 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [5 x %struct.S.0], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [5 x %struct.S.0], ptr [[TMP0]], i64 0, i64 4 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [5 x %struct.S.0], ptr [[VVAR22]], i32 0, i32 0 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_S_0:%.*]], ptr [[ARRAY_BEGIN]], i64 5 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP1]] @@ -2066,9 +2066,9 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x %struct.S.0], ptr [[TMP2]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4 x %struct.S.0], ptr [[TMP2]], i64 0, i64 1 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[_TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [4 x %struct.S.0], ptr [[TMP3]], i64 0, i64 2 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [4 x %struct.S.0], ptr [[TMP3]], i64 0, i64 2 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[VAR34]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_S_0:%.*]], ptr [[ARRAY_BEGIN]], i64 2 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP4]] @@ -2979,8 +2979,8 @@ int main() { // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [42 x %struct.S], ptr [[TMP0]], i64 0, i64 1 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [42 x %struct.S], ptr [[TMP0]], i64 0, i64 40 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [42 x %struct.S], ptr [[TMP0]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [42 x %struct.S], ptr [[TMP0]], i64 0, i64 40 // CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [40 x %struct.S], ptr [[ARR4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr [[STRUCT_S:%.*]], ptr [[ARRAY_BEGIN]], i64 40 // CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP6]] diff --git a/clang/test/OpenMP/for_reduction_task_codegen.cpp b/clang/test/OpenMP/for_reduction_task_codegen.cpp index ea93323de77d0..b875279c2a144 100644 --- a/clang/test/OpenMP/for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/for_reduction_task_codegen.cpp @@ -68,16 +68,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP3]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP5:%.*]] = sext i32 [[TMP4]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP5]] // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP6]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP6]], i64 9 // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP7]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP7]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP10:%.*]] = sub i64 [[TMP8]], [[TMP9]] @@ -107,7 +107,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP21]] // CHECK1-NEXT: store ptr [[_TMP6]], ptr [[_TMP5]], align 8 // CHECK1-NEXT: store ptr [[TMP22]], ptr [[_TMP6]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP23]], align 8 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -122,19 +122,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP28]], align 8 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP29]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds ptr, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load ptr, ptr [[ARRAYIDX8]], align 8 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i8, ptr [[TMP32]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 0 // CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP34:%.*]] = sext i32 [[TMP33]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN10:%.*]] = add nsw i64 -1, [[TMP34]] // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds ptr, ptr [[TMP35]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP35]], i64 9 // CHECK1-NEXT: [[TMP36:%.*]] = load ptr, ptr [[ARRAYIDX11]], align 8 -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds i8, ptr [[TMP36]], i64 [[LB_ADD_LEN10]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP36]], i64 [[LB_ADD_LEN10]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP30]], align 8 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[TMP37]], align 8 @@ -459,9 +459,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/for_scan_codegen.cpp b/clang/test/OpenMP/for_scan_codegen.cpp index 4cf18a76fbfef..61e6534db471e 100644 --- a/clang/test/OpenMP/for_scan_codegen.cpp +++ b/clang/test/OpenMP/for_scan_codegen.cpp @@ -39,13 +39,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:.+]] @@ -72,13 +72,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -132,13 +132,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE:[^,]+]] @@ -179,13 +179,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:[^,]+]] @@ -217,13 +217,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -280,13 +280,13 @@ void baz(int n) { // CHECK: [[IF_THEN]]: // CHECK: [[BASE_IDX_SUB_1:%.+]] = sub nuw i64 [[BASE_IDX]], 1 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX_SUB_1]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE]] diff --git a/clang/test/OpenMP/for_simd_scan_codegen.cpp b/clang/test/OpenMP/for_simd_scan_codegen.cpp index 29af5f74c5b5b..829f2656042fb 100644 --- a/clang/test/OpenMP/for_simd_scan_codegen.cpp +++ b/clang/test/OpenMP/for_simd_scan_codegen.cpp @@ -39,13 +39,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:.+]] @@ -72,13 +72,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -132,13 +132,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE:[^,]+]] @@ -179,13 +179,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:[^,]+]] @@ -217,13 +217,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -280,13 +280,13 @@ void baz(int n) { // CHECK: [[IF_THEN]]: // CHECK: [[BASE_IDX_SUB_1:%.+]] = sub nuw i64 [[BASE_IDX]], 1 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX_SUB_1]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE]] diff --git a/clang/test/OpenMP/irbuilder_for_iterator.cpp b/clang/test/OpenMP/irbuilder_for_iterator.cpp index 0098a7db575c3..ec1c3af744b49 100644 --- a/clang/test/OpenMP/irbuilder_for_iterator.cpp +++ b/clang/test/OpenMP/irbuilder_for_iterator.cpp @@ -78,18 +78,18 @@ extern "C" void workshareloop_iterator(float *a, float *b, float *c) { // CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP8]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP11]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP9]], [[TMP12]] // CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP14]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM4]] // CHECK-NEXT: store float [[MUL]], ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_rangefor.cpp b/clang/test/OpenMP/irbuilder_for_rangefor.cpp index 45b34621afbb9..86a043e638bc3 100644 --- a/clang/test/OpenMP/irbuilder_for_rangefor.cpp +++ b/clang/test/OpenMP/irbuilder_for_rangefor.cpp @@ -94,18 +94,18 @@ extern "C" void workshareloop_rangefor(float *a, float *b, float *c) { // CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP11]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP14]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP12]], [[TMP15]] // CHECK-NEXT: [[TMP16:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP17:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP17]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM4]] // CHECK-NEXT: store float [[MUL]], ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_unsigned.c b/clang/test/OpenMP/irbuilder_for_unsigned.c index b0043b823ac85..675871a87b3bd 100644 --- a/clang/test/OpenMP/irbuilder_for_unsigned.c +++ b/clang/test/OpenMP/irbuilder_for_unsigned.c @@ -65,24 +65,24 @@ extern "C" void workshareloop_unsigned(float *a, float *b, float *c, float *d) { // CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP10]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP9]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP9]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP11:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP12]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP12]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP14:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP11]], [[TMP14]] // CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP16]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP15]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP15]], i64 [[IDXPROM4]] // CHECK-NEXT: [[TMP17:%.*]] = load float, ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: [[MUL6:%.*]] = fmul float [[MUL]], [[TMP17]] // CHECK-NEXT: [[TMP18:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP19:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP19]] to i64 -// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP18]], i64 [[IDXPROM7]] +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP18]], i64 [[IDXPROM7]] // CHECK-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_unsigned_auto.c b/clang/test/OpenMP/irbuilder_for_unsigned_auto.c index 19b2770bfa2df..39ede3ef971d0 100644 --- a/clang/test/OpenMP/irbuilder_for_unsigned_auto.c +++ b/clang/test/OpenMP/irbuilder_for_unsigned_auto.c @@ -66,24 +66,24 @@ extern "C" void workshareloop_unsigned_auto(float *a, float *b, float *c, float // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP4]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP7]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP5]], [[TMP8]] // CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP10]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP9]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP9]], i64 [[IDXPROM4]] // CHECK-NEXT: [[TMP11:%.*]] = load float, ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: [[MUL6:%.*]] = fmul float [[MUL]], [[TMP11]] // CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP12]], i64 [[IDXPROM7]] +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP12]], i64 [[IDXPROM7]] // CHECK-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_unsigned_down.c b/clang/test/OpenMP/irbuilder_for_unsigned_down.c index 6e179826a6efa..5515f086c34a7 100644 --- a/clang/test/OpenMP/irbuilder_for_unsigned_down.c +++ b/clang/test/OpenMP/irbuilder_for_unsigned_down.c @@ -67,7 +67,7 @@ extern "C" void workshareloop_unsigned_down(float *a) { // CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP11]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM]] // CHECK-NEXT: store float [[CONV]], ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_unsigned_dynamic.c b/clang/test/OpenMP/irbuilder_for_unsigned_dynamic.c index 8f3297061938b..f20b60e608d2f 100644 --- a/clang/test/OpenMP/irbuilder_for_unsigned_dynamic.c +++ b/clang/test/OpenMP/irbuilder_for_unsigned_dynamic.c @@ -66,24 +66,24 @@ extern "C" void workshareloop_unsigned_dynamic(float *a, float *b, float *c, flo // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP4]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP7]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP5]], [[TMP8]] // CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP10]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP9]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP9]], i64 [[IDXPROM4]] // CHECK-NEXT: [[TMP11:%.*]] = load float, ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: [[MUL6:%.*]] = fmul float [[MUL]], [[TMP11]] // CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP12]], i64 [[IDXPROM7]] +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP12]], i64 [[IDXPROM7]] // CHECK-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_unsigned_dynamic_chunked.c b/clang/test/OpenMP/irbuilder_for_unsigned_dynamic_chunked.c index c2b0948bf7aeb..599f256243b11 100644 --- a/clang/test/OpenMP/irbuilder_for_unsigned_dynamic_chunked.c +++ b/clang/test/OpenMP/irbuilder_for_unsigned_dynamic_chunked.c @@ -66,24 +66,24 @@ extern "C" void workshareloop_unsigned_dynamic_chunked(float *a, float *b, float // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP4]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP7]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP5]], [[TMP8]] // CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP10]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP9]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP9]], i64 [[IDXPROM4]] // CHECK-NEXT: [[TMP11:%.*]] = load float, ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: [[MUL6:%.*]] = fmul float [[MUL]], [[TMP11]] // CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP12]], i64 [[IDXPROM7]] +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP12]], i64 [[IDXPROM7]] // CHECK-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_unsigned_runtime.c b/clang/test/OpenMP/irbuilder_for_unsigned_runtime.c index 68becf9f694ad..c27bcba155910 100644 --- a/clang/test/OpenMP/irbuilder_for_unsigned_runtime.c +++ b/clang/test/OpenMP/irbuilder_for_unsigned_runtime.c @@ -66,24 +66,24 @@ extern "C" void workshareloop_unsigned_runtime(float *a, float *b, float *c, flo // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP4]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP7]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP5]], [[TMP8]] // CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP10]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP9]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP9]], i64 [[IDXPROM4]] // CHECK-NEXT: [[TMP11:%.*]] = load float, ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: [[MUL6:%.*]] = fmul float [[MUL]], [[TMP11]] // CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP12]], i64 [[IDXPROM7]] +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP12]], i64 [[IDXPROM7]] // CHECK-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c b/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c index 71fb6b5473da8..b937568ca9f11 100644 --- a/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c +++ b/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c @@ -108,24 +108,24 @@ extern "C" void workshareloop_unsigned_static_chunked(float *a, float *b, float // CHECK-NEXT: [[TMP17:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM]] // CHECK-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK-NEXT: [[TMP20:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM2]] // CHECK-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP19]], [[TMP22]] // CHECK-NEXT: [[TMP23:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM4]] // CHECK-NEXT: [[TMP25:%.*]] = load float, ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: [[MUL6:%.*]] = fmul float [[MUL]], [[TMP25]] // CHECK-NEXT: [[TMP26:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[I]], align 4 // CHECK-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP27]] to i64 -// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP26]], i64 [[IDXPROM7]] +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP26]], i64 [[IDXPROM7]] // CHECK-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: diff --git a/clang/test/OpenMP/map_struct_ordering.cpp b/clang/test/OpenMP/map_struct_ordering.cpp index d5b22d8ff2a4d..a52ddad465f37 100644 --- a/clang/test/OpenMP/map_struct_ordering.cpp +++ b/clang/test/OpenMP/map_struct_ordering.cpp @@ -57,7 +57,7 @@ int map_struct() { // CHECK-NEXT: [[DATUM:%.*]] = getelementptr inbounds nuw [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 0, i32 0 // CHECK-NEXT: [[DATUM2:%.*]] = getelementptr inbounds nuw [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 0, i32 0 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DATUM2]], align 8 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i64 0 +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i64 0 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 1 // CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 // CHECK-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[DAT]] to i64 diff --git a/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp b/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp index e90f0783787c0..7d467293d0c8f 100644 --- a/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp @@ -76,7 +76,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[VLA:%.*]] = alloca i16, i64 [[TMP2]], align 16 // CHECK1-NEXT: store i64 [[TMP2]], ptr [[__VLA_EXPR0]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[A]], ptr [[TMP4]], align 8 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -91,7 +91,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP9]], align 8 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP10]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[B]], ptr [[TMP11]], align 8 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 1 @@ -106,7 +106,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..2, ptr [[TMP16]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP17]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC_ADDR]], ptr [[TMP18]], align 8 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 1 @@ -124,7 +124,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP25:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 3, ptr [[DOTRD_INPUT_]]) // CHECK1-NEXT: store ptr [[TMP25]], ptr [[DOTTASK_RED_]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[C]], ptr [[TMP26]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 1 @@ -139,7 +139,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..6, ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP32]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP33]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 1 diff --git a/clang/test/OpenMP/master_taskloop_reduction_codegen.cpp b/clang/test/OpenMP/master_taskloop_reduction_codegen.cpp index 180ff3a94d24c..b0652c843845c 100644 --- a/clang/test/OpenMP/master_taskloop_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_reduction_codegen.cpp @@ -84,9 +84,9 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB1:.+]], ptr [[TMP25]], // CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK-DAG: call void @llvm.memset.p0.i64(ptr align 8 [[TMP26]], i8 0, i64 4, i1 false) -// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 0 +// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 0 // CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, % -// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] +// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], // CHECK-DAG: [[TMP28]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0 // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], @@ -138,10 +138,10 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB4:.+]], ptr [[TMP59]], // CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_8]], i32 0, i32 6 // CHECK-DAG: store i32 1, ptr [[TMP60]], -// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 // CHECK: [[TMP62:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 4, ptr [[DOTRD_INPUT_]]) // CHECK: [[TMP63:%.*]] = load i32, ptr [[N]], // CHECK: store i32 [[TMP63]], ptr [[DOTCAPTURE_EXPR_]], 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 2061da7c4d781..b0d00c5f539b1 100644 --- a/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp @@ -76,7 +76,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[VLA:%.*]] = alloca i16, i64 [[TMP2]], align 16 // CHECK1-NEXT: store i64 [[TMP2]], ptr [[__VLA_EXPR0]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[A]], ptr [[TMP4]], align 8 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -91,7 +91,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP9]], align 8 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP10]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[B]], ptr [[TMP11]], align 8 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 1 @@ -106,7 +106,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..2, ptr [[TMP16]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP17]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC_ADDR]], ptr [[TMP18]], align 8 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 1 @@ -124,7 +124,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP25:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 3, ptr [[DOTRD_INPUT_]]) // CHECK1-NEXT: store ptr [[TMP25]], ptr [[DOTTASK_RED_]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[C]], ptr [[TMP26]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 1 @@ -139,7 +139,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..6, ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP32]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP33]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 1 diff --git a/clang/test/OpenMP/master_taskloop_simd_reduction_codegen.cpp b/clang/test/OpenMP/master_taskloop_simd_reduction_codegen.cpp index a69844dc4dee2..7def61251b24e 100644 --- a/clang/test/OpenMP/master_taskloop_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_reduction_codegen.cpp @@ -80,9 +80,9 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB1:.+]], ptr [[TMP25]], // CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK-DAG: call void @llvm.memset.p0.i64(ptr align 8 [[TMP26]], i8 0, i64 4, i1 false) -// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 0 +// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 0 // CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, % -// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] +// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], // CHECK-DAG: [[TMP28]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0 // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], @@ -134,10 +134,10 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB4:.+]], ptr [[TMP59]], // CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_8]], i32 0, i32 6 // CHECK-DAG: store i32 1, ptr [[TMP60]], -// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 // CHECK: [[TMP62:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 4, ptr [[DOTRD_INPUT_]]) // CHECK: [[TMP63:%.*]] = load i32, ptr [[N]], // CHECK: store i32 [[TMP63]], ptr [[DOTCAPTURE_EXPR_]], diff --git a/clang/test/OpenMP/ordered_codegen.cpp b/clang/test/OpenMP/ordered_codegen.cpp index 0a73eaefc9808..67285cfaef34d 100644 --- a/clang/test/OpenMP/ordered_codegen.cpp +++ b/clang/test/OpenMP/ordered_codegen.cpp @@ -255,21 +255,21 @@ void foo_simd(int low, int up) { // CHECK1-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[TMP0]]) // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK1-NEXT: [[TMP7:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i64 [[TMP7]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i64 [[TMP7]] // CHECK1-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK1-NEXT: [[TMP10:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP9]], i64 [[TMP10]] +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP9]], i64 [[TMP10]] // CHECK1-NEXT: [[TMP11:%.*]] = load float, ptr [[ARRAYIDX2]], align 4 // CHECK1-NEXT: [[MUL3:%.*]] = fmul float [[TMP8]], [[TMP11]] // CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP12]], i64 [[TMP13]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP12]], i64 [[TMP13]] // CHECK1-NEXT: [[TMP14:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 // CHECK1-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP14]] // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK1-NEXT: [[TMP16:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP15]], i64 [[TMP16]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP15]], i64 [[TMP16]] // CHECK1-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4 // CHECK1-NEXT: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP0]]) // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] @@ -485,24 +485,24 @@ void foo_simd(int low, int up) { // CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK1-NEXT: [[TMP9:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP9]] to i64 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP8]], i64 [[IDXPROM]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP8]], i64 [[IDXPROM]] // CHECK1-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK1-NEXT: [[TMP12:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-NEXT: [[IDXPROM7:%.*]] = zext i8 [[TMP12]] to i64 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[IDXPROM7]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[IDXPROM7]] // CHECK1-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX8]], align 4 // CHECK1-NEXT: [[MUL9:%.*]] = fmul float [[TMP10]], [[TMP13]] // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-NEXT: [[IDXPROM10:%.*]] = zext i8 [[TMP15]] to i64 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM10]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM10]] // CHECK1-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX11]], align 4 // CHECK1-NEXT: [[MUL12:%.*]] = fmul float [[MUL9]], [[TMP16]] // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-NEXT: [[IDXPROM13:%.*]] = zext i8 [[TMP18]] to i64 -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM13]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM13]] // CHECK1-NEXT: store float [[MUL12]], ptr [[ARRAYIDX14]], align 4 // CHECK1-NEXT: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP0]]) // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] @@ -866,21 +866,21 @@ void foo_simd(int low, int up) { // CHECK1-IRBUILDER-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]]) // CHECK1-IRBUILDER-NEXT: [[TMP5:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP6:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP5]], i64 [[TMP6]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP5]], i64 [[TMP6]] // CHECK1-IRBUILDER-NEXT: [[TMP7:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK1-IRBUILDER-NEXT: [[TMP8:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP9:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP8]], i64 [[TMP9]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP8]], i64 [[TMP9]] // CHECK1-IRBUILDER-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 // CHECK1-IRBUILDER-NEXT: [[MUL5:%.*]] = fmul float [[TMP7]], [[TMP10]] // CHECK1-IRBUILDER-NEXT: [[TMP11:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK1-IRBUILDER-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX6]], align 4 // CHECK1-IRBUILDER-NEXT: [[MUL7:%.*]] = fmul float [[MUL5]], [[TMP13]] // CHECK1-IRBUILDER-NEXT: [[TMP14:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK1-IRBUILDER-NEXT: store float [[MUL7]], ptr [[ARRAYIDX8]], align 4 // CHECK1-IRBUILDER-NEXT: br label [[OMP_INNER_FOR_BODY_ORDERED_AFTER:%.*]] // CHECK1-IRBUILDER: omp.inner.for.body.ordered.after: @@ -1110,24 +1110,24 @@ void foo_simd(int low, int up) { // CHECK1-IRBUILDER-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP8:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-IRBUILDER-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP8]] to i64 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i64 [[IDXPROM]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i64 [[IDXPROM]] // CHECK1-IRBUILDER-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK1-IRBUILDER-NEXT: [[TMP10:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP11:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-IRBUILDER-NEXT: [[IDXPROM9:%.*]] = zext i8 [[TMP11]] to i64 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[IDXPROM9]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM9]] // CHECK1-IRBUILDER-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX10]], align 4 // CHECK1-IRBUILDER-NEXT: [[MUL11:%.*]] = fmul float [[TMP9]], [[TMP12]] // CHECK1-IRBUILDER-NEXT: [[TMP13:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP14:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-IRBUILDER-NEXT: [[IDXPROM12:%.*]] = zext i8 [[TMP14]] to i64 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM12]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM12]] // CHECK1-IRBUILDER-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX13]], align 4 // CHECK1-IRBUILDER-NEXT: [[MUL14:%.*]] = fmul float [[MUL11]], [[TMP15]] // CHECK1-IRBUILDER-NEXT: [[TMP16:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK1-IRBUILDER-NEXT: [[TMP17:%.*]] = load i8, ptr [[I]], align 1 // CHECK1-IRBUILDER-NEXT: [[IDXPROM15:%.*]] = zext i8 [[TMP17]] to i64 -// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM15]] +// CHECK1-IRBUILDER-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM15]] // CHECK1-IRBUILDER-NEXT: store float [[MUL14]], ptr [[ARRAYIDX16]], align 4 // CHECK1-IRBUILDER-NEXT: br label [[OMP_INNER_FOR_BODY_ORDERED_AFTER:%.*]] // CHECK1-IRBUILDER: omp.inner.for.body.ordered.after: @@ -1495,21 +1495,21 @@ void foo_simd(int low, int up) { // CHECK3-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[TMP0]]) // CHECK3-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK3-NEXT: [[TMP7:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i64 [[TMP7]] +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i64 [[TMP7]] // CHECK3-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK3-NEXT: [[TMP10:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP9]], i64 [[TMP10]] +// CHECK3-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP9]], i64 [[TMP10]] // CHECK3-NEXT: [[TMP11:%.*]] = load float, ptr [[ARRAYIDX2]], align 4 // CHECK3-NEXT: [[MUL3:%.*]] = fmul float [[TMP8]], [[TMP11]] // CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK3-NEXT: [[TMP13:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP12]], i64 [[TMP13]] +// CHECK3-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP12]], i64 [[TMP13]] // CHECK3-NEXT: [[TMP14:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 // CHECK3-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP14]] // CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK3-NEXT: [[TMP16:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP15]], i64 [[TMP16]] +// CHECK3-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP15]], i64 [[TMP16]] // CHECK3-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4 // CHECK3-NEXT: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP0]]) // CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] @@ -1725,24 +1725,24 @@ void foo_simd(int low, int up) { // CHECK3-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK3-NEXT: [[TMP9:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP9]] to i64 -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP8]], i64 [[IDXPROM]] +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP8]], i64 [[IDXPROM]] // CHECK3-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK3-NEXT: [[TMP12:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-NEXT: [[IDXPROM7:%.*]] = zext i8 [[TMP12]] to i64 -// CHECK3-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[IDXPROM7]] +// CHECK3-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[IDXPROM7]] // CHECK3-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX8]], align 4 // CHECK3-NEXT: [[MUL9:%.*]] = fmul float [[TMP10]], [[TMP13]] // CHECK3-NEXT: [[TMP14:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK3-NEXT: [[TMP15:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-NEXT: [[IDXPROM10:%.*]] = zext i8 [[TMP15]] to i64 -// CHECK3-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM10]] +// CHECK3-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM10]] // CHECK3-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX11]], align 4 // CHECK3-NEXT: [[MUL12:%.*]] = fmul float [[MUL9]], [[TMP16]] // CHECK3-NEXT: [[TMP17:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK3-NEXT: [[TMP18:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-NEXT: [[IDXPROM13:%.*]] = zext i8 [[TMP18]] to i64 -// CHECK3-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM13]] +// CHECK3-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM13]] // CHECK3-NEXT: store float [[MUL12]], ptr [[ARRAYIDX14]], align 4 // CHECK3-NEXT: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP0]]) // CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] @@ -2106,21 +2106,21 @@ void foo_simd(int low, int up) { // CHECK3-IRBUILDER-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]]) // CHECK3-IRBUILDER-NEXT: [[TMP5:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP6:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP5]], i64 [[TMP6]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP5]], i64 [[TMP6]] // CHECK3-IRBUILDER-NEXT: [[TMP7:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK3-IRBUILDER-NEXT: [[TMP8:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP9:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP8]], i64 [[TMP9]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP8]], i64 [[TMP9]] // CHECK3-IRBUILDER-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 // CHECK3-IRBUILDER-NEXT: [[MUL5:%.*]] = fmul float [[TMP7]], [[TMP10]] // CHECK3-IRBUILDER-NEXT: [[TMP11:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK3-IRBUILDER-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX6]], align 4 // CHECK3-IRBUILDER-NEXT: [[MUL7:%.*]] = fmul float [[MUL5]], [[TMP13]] // CHECK3-IRBUILDER-NEXT: [[TMP14:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK3-IRBUILDER-NEXT: store float [[MUL7]], ptr [[ARRAYIDX8]], align 4 // CHECK3-IRBUILDER-NEXT: br label [[OMP_INNER_FOR_BODY_ORDERED_AFTER:%.*]] // CHECK3-IRBUILDER: omp.inner.for.body.ordered.after: @@ -2350,24 +2350,24 @@ void foo_simd(int low, int up) { // CHECK3-IRBUILDER-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP8:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-IRBUILDER-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP8]] to i64 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i64 [[IDXPROM]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i64 [[IDXPROM]] // CHECK3-IRBUILDER-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK3-IRBUILDER-NEXT: [[TMP10:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP11:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-IRBUILDER-NEXT: [[IDXPROM9:%.*]] = zext i8 [[TMP11]] to i64 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[IDXPROM9]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM9]] // CHECK3-IRBUILDER-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX10]], align 4 // CHECK3-IRBUILDER-NEXT: [[MUL11:%.*]] = fmul float [[TMP9]], [[TMP12]] // CHECK3-IRBUILDER-NEXT: [[TMP13:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP14:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-IRBUILDER-NEXT: [[IDXPROM12:%.*]] = zext i8 [[TMP14]] to i64 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM12]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM12]] // CHECK3-IRBUILDER-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX13]], align 4 // CHECK3-IRBUILDER-NEXT: [[MUL14:%.*]] = fmul float [[MUL11]], [[TMP15]] // CHECK3-IRBUILDER-NEXT: [[TMP16:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK3-IRBUILDER-NEXT: [[TMP17:%.*]] = load i8, ptr [[I]], align 1 // CHECK3-IRBUILDER-NEXT: [[IDXPROM15:%.*]] = zext i8 [[TMP17]] to i64 -// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM15]] +// CHECK3-IRBUILDER-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM15]] // CHECK3-IRBUILDER-NEXT: store float [[MUL14]], ptr [[ARRAYIDX16]], align 4 // CHECK3-IRBUILDER-NEXT: br label [[OMP_INNER_FOR_BODY_ORDERED_AFTER:%.*]] // CHECK3-IRBUILDER: omp.inner.for.body.ordered.after: @@ -2674,21 +2674,21 @@ void foo_simd(int low, int up) { // CHECK5: for.body: // CHECK5-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK5-NEXT: [[TMP2:%.*]] = load i64, ptr [[I]], align 8 -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i64 [[TMP2]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i64 [[TMP2]] // CHECK5-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK5-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK5-NEXT: [[TMP5:%.*]] = load i64, ptr [[I]], align 8 -// CHECK5-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i64 [[TMP5]] +// CHECK5-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw float, ptr [[TMP4]], i64 [[TMP5]] // CHECK5-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX1]], align 4 // CHECK5-NEXT: [[MUL:%.*]] = fmul float [[TMP3]], [[TMP6]] // CHECK5-NEXT: [[TMP7:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = load i64, ptr [[I]], align 8 -// CHECK5-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP7]], i64 [[TMP8]] +// CHECK5-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i64 [[TMP8]] // CHECK5-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX2]], align 4 // CHECK5-NEXT: [[MUL3:%.*]] = fmul float [[MUL]], [[TMP9]] // CHECK5-NEXT: [[TMP10:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK5-NEXT: [[TMP11:%.*]] = load i64, ptr [[I]], align 8 -// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP10]], i64 [[TMP11]] +// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[TMP11]] // CHECK5-NEXT: store float [[MUL3]], ptr [[ARRAYIDX4]], align 4 // CHECK5-NEXT: br label [[FOR_INC:%.*]] // CHECK5: for.inc: @@ -2804,24 +2804,24 @@ void foo_simd(int low, int up) { // CHECK5-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8 // CHECK5-NEXT: [[TMP3:%.*]] = load i8, ptr [[I]], align 1 // CHECK5-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP3]] to i64 -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i64 [[IDXPROM]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP2]], i64 [[IDXPROM]] // CHECK5-NEXT: [[TMP4:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK5-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK5-NEXT: [[TMP6:%.*]] = load i8, ptr [[I]], align 1 // CHECK5-NEXT: [[IDXPROM4:%.*]] = zext i8 [[TMP6]] to i64 -// CHECK5-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP5]], i64 [[IDXPROM4]] +// CHECK5-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP5]], i64 [[IDXPROM4]] // CHECK5-NEXT: [[TMP7:%.*]] = load float, ptr [[ARRAYIDX5]], align 4 // CHECK5-NEXT: [[MUL:%.*]] = fmul float [[TMP4]], [[TMP7]] // CHECK5-NEXT: [[TMP8:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK5-NEXT: [[TMP9:%.*]] = load i8, ptr [[I]], align 1 // CHECK5-NEXT: [[IDXPROM6:%.*]] = zext i8 [[TMP9]] to i64 -// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP8]], i64 [[IDXPROM6]] +// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP8]], i64 [[IDXPROM6]] // CHECK5-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX7]], align 4 // CHECK5-NEXT: [[MUL8:%.*]] = fmul float [[MUL]], [[TMP10]] // CHECK5-NEXT: [[TMP11:%.*]] = load ptr, ptr [[A_ADDR]], align 8 // CHECK5-NEXT: [[TMP12:%.*]] = load i8, ptr [[I]], align 1 // CHECK5-NEXT: [[IDXPROM9:%.*]] = zext i8 [[TMP12]] to i64 -// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[IDXPROM9]] +// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[IDXPROM9]] // CHECK5-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4 // CHECK5-NEXT: br label [[FOR_INC:%.*]] // CHECK5: for.inc: diff --git a/clang/test/OpenMP/parallel_for_codegen.cpp b/clang/test/OpenMP/parallel_for_codegen.cpp index 2dec32d71b91a..c7afae419509b 100644 --- a/clang/test/OpenMP/parallel_for_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_codegen.cpp @@ -665,24 +665,24 @@ void range_for_collapsed() { // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4 // CHECK1-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK1-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4 // CHECK1-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK1-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 // CHECK1-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4 // CHECK1-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK1-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4 // CHECK1-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK1-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4 // CHECK1-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK1-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4 // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: @@ -779,21 +779,21 @@ void range_for_collapsed() { // CHECK1-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK1-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK1-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]] // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]] // CHECK1-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]] // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]] // CHECK1-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: @@ -882,21 +882,21 @@ void range_for_collapsed() { // CHECK1-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK1-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK1-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]] // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]] // CHECK1-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]] // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]] // CHECK1-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: @@ -1159,24 +1159,24 @@ void range_for_collapsed() { // CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[TMP14:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP14]] to i64 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM]] // CHECK1-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[TMP17:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[IDXPROM6:%.*]] = zext i8 [[TMP17]] to i64 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM6]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM6]] // CHECK1-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[MUL8:%.*]] = fmul float [[TMP15]], [[TMP18]] // CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[TMP20:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[IDXPROM9:%.*]] = zext i8 [[TMP20]] to i64 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP19]], i64 [[IDXPROM9]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP19]], i64 [[IDXPROM9]] // CHECK1-NEXT: [[TMP21:%.*]] = load float, ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[MUL11:%.*]] = fmul float [[MUL8]], [[TMP21]] // CHECK1-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[TMP23:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: [[IDXPROM12:%.*]] = zext i8 [[TMP23]] to i64 -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i64 [[IDXPROM12]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i64 [[IDXPROM12]] // CHECK1-NEXT: store float [[MUL11]], ptr [[ARRAYIDX13]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: @@ -1303,7 +1303,7 @@ void range_for_collapsed() { // CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[CALL]] to float // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK1-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[VLA1]], i64 [[IDXPROM]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[VLA1]], i64 [[IDXPROM]] // CHECK1-NEXT: [[TMP14:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK1-NEXT: [[ADD4:%.*]] = fadd float [[CONV]], [[TMP14]] // CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[N_ADDR]], align 4 @@ -1312,7 +1312,7 @@ void range_for_collapsed() { // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[I]], align 4 // CHECK1-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP17]] to i64 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM7]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM7]] // CHECK1-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX8]], align 4 // CHECK1-NEXT: [[ADD9:%.*]] = fadd float [[TMP18]], [[ADD6]] // CHECK1-NEXT: store float [[ADD9]], ptr [[ARRAYIDX8]], align 4 @@ -1781,24 +1781,24 @@ void range_for_collapsed() { // CHECK2-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8 // CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4 // CHECK2-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK2-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK2-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4 // CHECK2-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK2-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK2-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK2-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 // CHECK2-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK2-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8 // CHECK2-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4 // CHECK2-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK2-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK2-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK2-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4 // CHECK2-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK2-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK2-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4 // CHECK2-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK2-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK2-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK2-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4 // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: @@ -1895,21 +1895,21 @@ void range_for_collapsed() { // CHECK2-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK2-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK2-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK2-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK2-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]] // CHECK2-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK2-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]] +// CHECK2-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]] // CHECK2-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]] // CHECK2-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK2-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]] +// CHECK2-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]] // CHECK2-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: @@ -1998,21 +1998,21 @@ void range_for_collapsed() { // CHECK2-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK2-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK2-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK2-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK2-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]] // CHECK2-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK2-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]] +// CHECK2-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]] // CHECK2-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]] // CHECK2-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK2-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]] +// CHECK2-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]] // CHECK2-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: @@ -2275,24 +2275,24 @@ void range_for_collapsed() { // CHECK2-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[TMP14:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP14]] to i64 -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM]] // CHECK2-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[TMP17:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[IDXPROM6:%.*]] = zext i8 [[TMP17]] to i64 -// CHECK2-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM6]] +// CHECK2-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM6]] // CHECK2-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[MUL8:%.*]] = fmul float [[TMP15]], [[TMP18]] // CHECK2-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[TMP20:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[IDXPROM9:%.*]] = zext i8 [[TMP20]] to i64 -// CHECK2-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP19]], i64 [[IDXPROM9]] +// CHECK2-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP19]], i64 [[IDXPROM9]] // CHECK2-NEXT: [[TMP21:%.*]] = load float, ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[MUL11:%.*]] = fmul float [[MUL8]], [[TMP21]] // CHECK2-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[TMP23:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: [[IDXPROM12:%.*]] = zext i8 [[TMP23]] to i64 -// CHECK2-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i64 [[IDXPROM12]] +// CHECK2-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i64 [[IDXPROM12]] // CHECK2-NEXT: store float [[MUL11]], ptr [[ARRAYIDX13]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: @@ -2419,7 +2419,7 @@ void range_for_collapsed() { // CHECK2-NEXT: [[CONV:%.*]] = sitofp i32 [[CALL]] to float // CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK2-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[VLA1]], i64 [[IDXPROM]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[VLA1]], i64 [[IDXPROM]] // CHECK2-NEXT: [[TMP14:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK2-NEXT: [[ADD4:%.*]] = fadd float [[CONV]], [[TMP14]] // CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[N_ADDR]], align 4 @@ -2428,7 +2428,7 @@ void range_for_collapsed() { // CHECK2-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[I]], align 4 // CHECK2-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP17]] to i64 -// CHECK2-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM7]] +// CHECK2-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM7]] // CHECK2-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX8]], align 4 // CHECK2-NEXT: [[ADD9:%.*]] = fadd float [[TMP18]], [[ADD6]] // CHECK2-NEXT: store float [[ADD9]], ptr [[ARRAYIDX8]], align 4 @@ -2897,24 +2897,24 @@ void range_for_collapsed() { // CHECK5-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8, !dbg [[DBG45:![0-9]+]] // CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64, !dbg [[DBG45]] -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]], !dbg [[DBG45]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]], !dbg [[DBG45]] // CHECK5-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8, !dbg [[DBG45]] // CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64, !dbg [[DBG45]] -// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]], !dbg [[DBG45]] +// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]], !dbg [[DBG45]] // CHECK5-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]], !dbg [[DBG45]] // CHECK5-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8, !dbg [[DBG45]] // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64, !dbg [[DBG45]] -// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]], !dbg [[DBG45]] +// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]], !dbg [[DBG45]] // CHECK5-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]], !dbg [[DBG45]] // CHECK5-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8, !dbg [[DBG45]] // CHECK5-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64, !dbg [[DBG45]] -// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]], !dbg [[DBG45]] +// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]], !dbg [[DBG45]] // CHECK5-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4, !dbg [[DBG45]] // CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG46:![0-9]+]] // CHECK5: omp.body.continue: @@ -3011,21 +3011,21 @@ void range_for_collapsed() { // CHECK5-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !dbg [[DBG54]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !dbg [[DBG56:![0-9]+]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]], !dbg [[DBG56]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]], !dbg [[DBG56]] // CHECK5-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] -// CHECK5-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]], !dbg [[DBG56]] +// CHECK5-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]], !dbg [[DBG56]] // CHECK5-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]], !dbg [[DBG56]] // CHECK5-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] -// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]], !dbg [[DBG56]] +// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]], !dbg [[DBG56]] // CHECK5-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]], !dbg [[DBG56]] // CHECK5-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] -// CHECK5-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]], !dbg [[DBG56]] +// CHECK5-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]], !dbg [[DBG56]] // CHECK5-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !dbg [[DBG56]], !llvm.access.group [[ACC_GRP55]] // CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG57:![0-9]+]] // CHECK5: omp.body.continue: @@ -3114,21 +3114,21 @@ void range_for_collapsed() { // CHECK5-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !dbg [[DBG66]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !dbg [[DBG68:![0-9]+]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]], !dbg [[DBG68]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]], !dbg [[DBG68]] // CHECK5-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] -// CHECK5-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]], !dbg [[DBG68]] +// CHECK5-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]], !dbg [[DBG68]] // CHECK5-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]], !dbg [[DBG68]] // CHECK5-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] -// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]], !dbg [[DBG68]] +// CHECK5-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]], !dbg [[DBG68]] // CHECK5-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]], !dbg [[DBG68]] // CHECK5-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] -// CHECK5-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]], !dbg [[DBG68]] +// CHECK5-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]], !dbg [[DBG68]] // CHECK5-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !dbg [[DBG68]], !llvm.access.group [[ACC_GRP67]] // CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG69:![0-9]+]] // CHECK5: omp.body.continue: @@ -3391,24 +3391,24 @@ void range_for_collapsed() { // CHECK5-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP1]], align 8, !dbg [[DBG97:![0-9]+]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[TMP14:%.*]] = load i8, ptr [[I]], align 1, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP14]] to i64, !dbg [[DBG97]] -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM]], !dbg [[DBG97]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM]], !dbg [[DBG97]] // CHECK5-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP2]], align 8, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[TMP17:%.*]] = load i8, ptr [[I]], align 1, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[IDXPROM6:%.*]] = zext i8 [[TMP17]] to i64, !dbg [[DBG97]] -// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM6]], !dbg [[DBG97]] +// CHECK5-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM6]], !dbg [[DBG97]] // CHECK5-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[MUL8:%.*]] = fmul float [[TMP15]], [[TMP18]], !dbg [[DBG97]] // CHECK5-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP3]], align 8, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[TMP20:%.*]] = load i8, ptr [[I]], align 1, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[IDXPROM9:%.*]] = zext i8 [[TMP20]] to i64, !dbg [[DBG97]] -// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP19]], i64 [[IDXPROM9]], !dbg [[DBG97]] +// CHECK5-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP19]], i64 [[IDXPROM9]], !dbg [[DBG97]] // CHECK5-NEXT: [[TMP21:%.*]] = load float, ptr [[ARRAYIDX10]], align 4, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[MUL11:%.*]] = fmul float [[MUL8]], [[TMP21]], !dbg [[DBG97]] // CHECK5-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP0]], align 8, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[TMP23:%.*]] = load i8, ptr [[I]], align 1, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: [[IDXPROM12:%.*]] = zext i8 [[TMP23]] to i64, !dbg [[DBG97]] -// CHECK5-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i64 [[IDXPROM12]], !dbg [[DBG97]] +// CHECK5-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i64 [[IDXPROM12]], !dbg [[DBG97]] // CHECK5-NEXT: store float [[MUL11]], ptr [[ARRAYIDX13]], align 4, !dbg [[DBG97]], !llvm.access.group [[ACC_GRP95]] // CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG98:![0-9]+]] // CHECK5: omp.body.continue: @@ -3535,7 +3535,7 @@ void range_for_collapsed() { // CHECK5-NEXT: [[CONV:%.*]] = sitofp i32 [[CALL]] to float, !dbg [[DBG111]] // CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG111]] // CHECK5-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP13]] to i64, !dbg [[DBG111]] -// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[VLA1]], i64 [[IDXPROM]], !dbg [[DBG111]] +// CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[VLA1]], i64 [[IDXPROM]], !dbg [[DBG111]] // CHECK5-NEXT: [[TMP14:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !dbg [[DBG111]] // CHECK5-NEXT: [[ADD4:%.*]] = fadd float [[CONV]], [[TMP14]], !dbg [[DBG111]] // CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[N_ADDR]], align 4, !dbg [[DBG111]] @@ -3544,7 +3544,7 @@ void range_for_collapsed() { // CHECK5-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP0]], align 8, !dbg [[DBG111]] // CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG111]] // CHECK5-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP17]] to i64, !dbg [[DBG111]] -// CHECK5-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM7]], !dbg [[DBG111]] +// CHECK5-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM7]], !dbg [[DBG111]] // CHECK5-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX8]], align 4, !dbg [[DBG111]] // CHECK5-NEXT: [[ADD9:%.*]] = fadd float [[TMP18]], [[ADD6]], !dbg [[DBG111]] // CHECK5-NEXT: store float [[ADD9]], ptr [[ARRAYIDX8]], align 4, !dbg [[DBG111]] @@ -4013,24 +4013,24 @@ void range_for_collapsed() { // CHECK6-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP1]], align 8 // CHECK6-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4 // CHECK6-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP15]] to i64 -// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[IDXPROM]] +// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM]] // CHECK6-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK6-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP2]], align 8 // CHECK6-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4 // CHECK6-NEXT: [[IDXPROM3:%.*]] = zext i32 [[TMP18]] to i64 -// CHECK6-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[IDXPROM3]] +// CHECK6-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM3]] // CHECK6-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 // CHECK6-NEXT: [[MUL5:%.*]] = fmul float [[TMP16]], [[TMP19]] // CHECK6-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP3]], align 8 // CHECK6-NEXT: [[TMP21:%.*]] = load i32, ptr [[I]], align 4 // CHECK6-NEXT: [[IDXPROM6:%.*]] = zext i32 [[TMP21]] to i64 -// CHECK6-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[IDXPROM6]] +// CHECK6-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[IDXPROM6]] // CHECK6-NEXT: [[TMP22:%.*]] = load float, ptr [[ARRAYIDX7]], align 4 // CHECK6-NEXT: [[MUL8:%.*]] = fmul float [[MUL5]], [[TMP22]] // CHECK6-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK6-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4 // CHECK6-NEXT: [[IDXPROM9:%.*]] = zext i32 [[TMP24]] to i64 -// CHECK6-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP23]], i64 [[IDXPROM9]] +// CHECK6-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP23]], i64 [[IDXPROM9]] // CHECK6-NEXT: store float [[MUL8]], ptr [[ARRAYIDX10]], align 4 // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: @@ -4127,21 +4127,21 @@ void range_for_collapsed() { // CHECK6-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK6-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK6-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK6-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK6-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]] // CHECK6-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK6-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]] +// CHECK6-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]] // CHECK6-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]] // CHECK6-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP5]] -// CHECK6-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]] +// CHECK6-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]] // CHECK6-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !llvm.access.group [[ACC_GRP5]] // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: @@ -4230,21 +4230,21 @@ void range_for_collapsed() { // CHECK6-NEXT: store i64 [[ADD1]], ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[TMP12:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 [[TMP12]] +// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[TMP12]] // CHECK6-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[TMP15:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK6-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[TMP14]], i64 [[TMP15]] +// CHECK6-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[TMP15]] // CHECK6-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX2]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[MUL3:%.*]] = fmul float [[TMP13]], [[TMP16]] // CHECK6-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[TMP18:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK6-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 [[TMP18]] +// CHECK6-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[TMP18]] // CHECK6-NEXT: [[TMP19:%.*]] = load float, ptr [[ARRAYIDX4]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[MUL5:%.*]] = fmul float [[MUL3]], [[TMP19]] // CHECK6-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: [[TMP21:%.*]] = load i64, ptr [[I]], align 8, !llvm.access.group [[ACC_GRP8]] -// CHECK6-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP20]], i64 [[TMP21]] +// CHECK6-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP20]], i64 [[TMP21]] // CHECK6-NEXT: store float [[MUL5]], ptr [[ARRAYIDX6]], align 4, !llvm.access.group [[ACC_GRP8]] // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: @@ -4507,24 +4507,24 @@ void range_for_collapsed() { // CHECK6-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP1]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[TMP14:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[IDXPROM:%.*]] = zext i8 [[TMP14]] to i64 -// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP13]], i64 [[IDXPROM]] +// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM]] // CHECK6-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP2]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[TMP17:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[IDXPROM6:%.*]] = zext i8 [[TMP17]] to i64 -// CHECK6-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM6]] +// CHECK6-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM6]] // CHECK6-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX7]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[MUL8:%.*]] = fmul float [[TMP15]], [[TMP18]] // CHECK6-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP3]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[TMP20:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[IDXPROM9:%.*]] = zext i8 [[TMP20]] to i64 -// CHECK6-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP19]], i64 [[IDXPROM9]] +// CHECK6-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw float, ptr [[TMP19]], i64 [[IDXPROM9]] // CHECK6-NEXT: [[TMP21:%.*]] = load float, ptr [[ARRAYIDX10]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[MUL11:%.*]] = fmul float [[MUL8]], [[TMP21]] // CHECK6-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP0]], align 8, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[TMP23:%.*]] = load i8, ptr [[I]], align 1, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: [[IDXPROM12:%.*]] = zext i8 [[TMP23]] to i64 -// CHECK6-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i64 [[IDXPROM12]] +// CHECK6-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i64 [[IDXPROM12]] // CHECK6-NEXT: store float [[MUL11]], ptr [[ARRAYIDX13]], align 4, !llvm.access.group [[ACC_GRP14]] // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: @@ -4649,7 +4649,7 @@ void range_for_collapsed() { // CHECK6-NEXT: [[CONV:%.*]] = sitofp i32 [[CALL]] to float // CHECK6-NEXT: [[TMP13:%.*]] = load i32, ptr [[I]], align 4 // CHECK6-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP13]] to i64 -// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[VLA1]], i64 [[IDXPROM]] +// CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[VLA1]], i64 [[IDXPROM]] // CHECK6-NEXT: [[TMP14:%.*]] = load float, ptr [[ARRAYIDX]], align 4 // CHECK6-NEXT: [[ADD4:%.*]] = fadd float [[CONV]], [[TMP14]] // CHECK6-NEXT: [[TMP15:%.*]] = load i32, ptr [[N_ADDR]], align 4 @@ -4658,7 +4658,7 @@ void range_for_collapsed() { // CHECK6-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK6-NEXT: [[TMP17:%.*]] = load i32, ptr [[I]], align 4 // CHECK6-NEXT: [[IDXPROM7:%.*]] = zext i32 [[TMP17]] to i64 -// CHECK6-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP16]], i64 [[IDXPROM7]] +// CHECK6-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM7]] // CHECK6-NEXT: [[TMP18:%.*]] = load float, ptr [[ARRAYIDX8]], align 4 // CHECK6-NEXT: [[ADD9:%.*]] = fadd float [[TMP18]], [[ADD6]] // CHECK6-NEXT: store float [[ADD9]], ptr [[ARRAYIDX8]], align 4 diff --git a/clang/test/OpenMP/parallel_for_linear_codegen.cpp b/clang/test/OpenMP/parallel_for_linear_codegen.cpp index 8b46797ae253f..15eb0dfa42af5 100644 --- a/clang/test/OpenMP/parallel_for_linear_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_linear_codegen.cpp @@ -337,7 +337,7 @@ int main() { // CHECK1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP14]], [[MUL6]] // CHECK1-NEXT: store i32 [[ADD7]], ptr [[LVAR3]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[PVAR2]], align 8 -// CHECK1-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 1 +// CHECK1-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP16]], i32 1 // CHECK1-NEXT: store ptr [[INCDEC_PTR]], ptr [[PVAR2]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[LVAR3]], align 4 // CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP17]], 1 diff --git a/clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp index 752aec788bf34..59d169d7a1738 100644 --- a/clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp @@ -83,16 +83,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -122,7 +122,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP6]], ptr [[_TMP5]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP6]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -137,19 +137,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX8]], align 8 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN10:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX11]], align 8 -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN10]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN10]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[TMP36]], align 8 @@ -470,9 +470,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/parallel_for_scan_codegen.cpp b/clang/test/OpenMP/parallel_for_scan_codegen.cpp index 161534814a793..67b32407c712f 100644 --- a/clang/test/OpenMP/parallel_for_scan_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_scan_codegen.cpp @@ -28,9 +28,9 @@ void baz(int n) { // CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call( // CHECK: [[LAST:%.+]] = mul nsw i64 9, % - // CHECK: [[LAST_REF:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[LAST]] + // CHECK: [[LAST_REF:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[LAST]] // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 16 @_ZZ3baziE1a, ptr align 4 [[LAST_REF]], i64 %{{.+}}, i1 false) - // CHECK: [[LAST_REF_B:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 9 + // CHECK: [[LAST_REF_B:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 9 // CHECK: [[LAST_VAL:%.+]] = load double, ptr [[LAST_REF_B]], // CHECK: store double [[LAST_VAL]], ptr @_ZZ3baziE1b, @@ -58,13 +58,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS:%.+]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF:%.+]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF:%.+]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:.+]] @@ -91,13 +91,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -151,13 +151,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE:[^,]+]] @@ -188,13 +188,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS:%.+]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF:%.+]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF:%.+]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:[^,]+]] @@ -226,13 +226,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -289,13 +289,13 @@ void baz(int n) { // CHECK: [[IF_THEN]]: // CHECK: [[BASE_IDX_SUB_1:%.+]] = sub nuw i64 [[BASE_IDX]], 1 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX_SUB_1]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE]] diff --git a/clang/test/OpenMP/parallel_for_simd_scan_codegen.cpp b/clang/test/OpenMP/parallel_for_simd_scan_codegen.cpp index 7e973a602a65c..cac997753d480 100644 --- a/clang/test/OpenMP/parallel_for_simd_scan_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_simd_scan_codegen.cpp @@ -51,13 +51,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS:%.+]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF:%.+]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF:%.+]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:.+]] @@ -84,13 +84,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -144,13 +144,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE:[^,]+]] @@ -181,13 +181,13 @@ void baz(int n) { // CHECK: [[BASE_IDX_I:%.+]] = load i32, ptr [[IV_ADDR:%.+]], // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS:%.+]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF:%.+]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF:%.+]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_BUF_IDX]], ptr {{.*}}[[A_PRIV]], i64 [[BYTES]], i1 false) // b_buffer[i] = b_priv; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF:%.+]], i64 [[BASE_IDX]] // CHECK: [[B_PRIV:%.+]] = load double, ptr [[B_PRIV_ADDR]], // CHECK: store double [[B_PRIV]], ptr [[B_BUF_IDX]], // CHECK: br label %[[LOOP_CONTINUE:[^,]+]] @@ -219,13 +219,13 @@ void baz(int n) { // a_buffer[i] += a_buffer[i-pow(2, k)]; // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[I]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[I]] // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] - // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[IDX_SUB_K2POW]] // CHECK: [[A_BUF_END:%.+]] = getelementptr float, ptr [[A_BUF_IDX]], i64 [[NUM_ELEMS]] // CHECK: [[ISEMPTY:%.+]] = icmp eq ptr [[A_BUF_IDX]], [[A_BUF_END]] // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] @@ -282,13 +282,13 @@ void baz(int n) { // CHECK: [[IF_THEN]]: // CHECK: [[BASE_IDX_SUB_1:%.+]] = sub nuw i64 [[BASE_IDX]], 1 // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX_SUB_1]], [[NUM_ELEMS]] - // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, ptr [[A_BUF]], i64 [[IDX]] - // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds nuw [10 x float], ptr [[A_PRIV_ADDR:%.+]], i64 0, i64 0 // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[A_PRIV]], ptr {{.*}}[[A_BUF_IDX]], i64 [[BYTES]], i1 false) // b_priv = b_buffer[i]; - // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds nuw double, ptr [[B_BUF]], i64 [[BASE_IDX_SUB_1]] // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, ptr [[B_BUF_IDX]], // CHECK: store double [[B_BUF_IDX_VAL]], ptr [[B_PRIV_ADDR]], // CHECK: br label %[[SCAN_PHASE]] diff --git a/clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp b/clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp index b17757a5f978a..c1fe00f238001 100644 --- a/clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp @@ -72,16 +72,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -111,7 +111,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP5]], ptr [[TMP]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP5]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -126,19 +126,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX7]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN9:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[TMP36]], align 8 @@ -425,9 +425,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/parallel_master_taskloop_reduction_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_reduction_codegen.cpp index 3c74aaca3f46d..1d106922435d5 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_reduction_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_reduction_codegen.cpp @@ -84,9 +84,9 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB1:.+]], ptr [[TMP25]], // CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK-DAG: call void @llvm.memset.p0.i64(ptr align 8 [[TMP26]], i8 0, i64 4, i1 false) -// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C:%.+]], i64 0, i64 0 +// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C:%.+]], i64 0, i64 0 // CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, % -// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] +// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], // CHECK-DAG: [[TMP28]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0 // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], @@ -138,10 +138,10 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB4:.+]], ptr [[TMP59]], // CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_8]], i32 0, i32 6 // CHECK-DAG: store i32 1, ptr [[TMP60]], -// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 // CHECK: [[TMP62:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0:%.+]], i32 4, ptr [[DOTRD_INPUT_]]) // CHECK: [[TMP63:%.*]] = load i32, ptr [[N:%.+]], // CHECK: store i32 [[TMP63]], ptr [[DOTCAPTURE_EXPR_]], diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_codegen.cpp index 7d4216ddde6a3..9a524c3b94c6e 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_codegen.cpp @@ -84,9 +84,9 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB1:.+]], ptr [[TMP25]], // CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK-DAG: call void @llvm.memset.p0.i64(ptr align 8 [[TMP26]], i8 0, i64 4, i1 false) -// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C:%.+]], i64 0, i64 0 +// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C:%.+]], i64 0, i64 0 // CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, % -// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] +// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], // CHECK-DAG: [[TMP28]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0 // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], @@ -138,10 +138,10 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB4:.+]], ptr [[TMP59]], // CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_8]], i32 0, i32 6 // CHECK-DAG: store i32 1, ptr [[TMP60]], -// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 // CHECK: [[TMP62:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0:%.+]], i32 4, ptr [[DOTRD_INPUT_]]) // CHECK: [[TMP63:%.*]] = load i32, ptr [[N:%.+]], // CHECK: store i32 [[TMP63]], ptr [[DOTCAPTURE_EXPR_]], diff --git a/clang/test/OpenMP/parallel_reduction_codegen.cpp b/clang/test/OpenMP/parallel_reduction_codegen.cpp index f49faa6b89deb..ce76429b871fe 100644 --- a/clang/test/OpenMP/parallel_reduction_codegen.cpp +++ b/clang/test/OpenMP/parallel_reduction_codegen.cpp @@ -354,9 +354,9 @@ int main() { // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 // CHECK1-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[TMP0]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i16, ptr [[TMP0]], i64 0 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[X_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i16, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[ARRAYIDX1]] to i64 // CHECK1-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK1-NEXT: [[TMP4:%.*]] = sub i64 [[TMP2]], [[TMP3]] @@ -1632,9 +1632,9 @@ int main() { // CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 // CHECK3-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8 -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[TMP0]], i64 0 +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i16, ptr [[TMP0]], i64 0 // CHECK3-NEXT: [[TMP1:%.*]] = load ptr, ptr [[X_ADDR]], align 8 -// CHECK3-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i64 0 +// CHECK3-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i16, ptr [[TMP1]], i64 0 // CHECK3-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[ARRAYIDX1]] to i64 // CHECK3-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK3-NEXT: [[TMP4:%.*]] = sub i64 [[TMP2]], [[TMP3]] @@ -2142,9 +2142,9 @@ int main() { // CHECK4-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 // CHECK4-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8 // CHECK4-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8 -// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[TMP0]], i64 0 +// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i16, ptr [[TMP0]], i64 0 // CHECK4-NEXT: [[TMP1:%.*]] = load ptr, ptr [[X_ADDR]], align 8 -// CHECK4-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i64 0 +// CHECK4-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i16, ptr [[TMP1]], i64 0 // CHECK4-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[ARRAYIDX1]] to i64 // CHECK4-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK4-NEXT: [[TMP4:%.*]] = sub i64 [[TMP2]], [[TMP3]] diff --git a/clang/test/OpenMP/parallel_reduction_task_codegen.cpp b/clang/test/OpenMP/parallel_reduction_task_codegen.cpp index 208f7a41aa3db..40cc3103b1c0f 100644 --- a/clang/test/OpenMP/parallel_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/parallel_reduction_task_codegen.cpp @@ -72,16 +72,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -111,7 +111,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP5]], ptr [[TMP]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP5]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -126,19 +126,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX7]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN9:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[TMP36]], align 8 @@ -416,9 +416,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp b/clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp index 6d73652c3ea27..61597a074cf59 100644 --- a/clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp @@ -81,16 +81,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -120,7 +120,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP5]], ptr [[TMP]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP5]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -135,19 +135,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX7]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN9:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[TMP36]], align 8 @@ -458,9 +458,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/reduction_implicit_map.cpp b/clang/test/OpenMP/reduction_implicit_map.cpp index 4d2b93ffd4712..a7db3da7d1f86 100644 --- a/clang/test/OpenMP/reduction_implicit_map.cpp +++ b/clang/test/OpenMP/reduction_implicit_map.cpp @@ -133,9 +133,9 @@ int main() // CHECK-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 // CHECK-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i64 0 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i64 0 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8 -// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i64 0 +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i64 0 // CHECK-NEXT: store double 0.000000e+00, ptr [[E2]], align 8 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[E_ADDR]], align 8 // CHECK-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP2]] to i64 @@ -529,16 +529,16 @@ int main() // CHECK1-NEXT: store i64 9, ptr [[DOTOMP_UB]], align 8 // CHECK1-NEXT: store i64 1, ptr [[DOTOMP_STRIDE]], align 8 // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 0 // CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x [10 x double]], ptr [[ARRAYIDX]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYDECAY]], i64 2 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [10 x double], ptr [[ARRAYDECAY]], i64 2 // CHECK1-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYIDX1]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY2]], i64 1 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw double, ptr [[ARRAYDECAY2]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 1 // CHECK1-NEXT: [[ARRAYDECAY5:%.*]] = getelementptr inbounds [10 x [10 x double]], ptr [[ARRAYIDX4]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYDECAY5]], i64 5 +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [10 x double], ptr [[ARRAYDECAY5]], i64 5 // CHECK1-NEXT: [[ARRAYDECAY7:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYIDX6]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY7]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw double, ptr [[ARRAYDECAY7]], i64 1 // CHECK1-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[ARRAYIDX8]] to i64 // CHECK1-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[ARRAYIDX3]] to i64 // CHECK1-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], [[TMP2]] @@ -564,18 +564,18 @@ int main() // CHECK1-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]] // CHECK1-NEXT: [[TMP12:%.*]] = sdiv exact i64 [[TMP11]], ptrtoint (ptr getelementptr (double, ptr null, i32 1) to i64) // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr double, ptr [[VLA]], i64 [[TMP12]] -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [1 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [1 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 0 // CHECK1-NEXT: [[ARRAYDECAY10:%.*]] = getelementptr inbounds [10 x [10 x double]], ptr [[ARRAYIDX9]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYDECAY10]], i64 2 +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw [10 x double], ptr [[ARRAYDECAY10]], i64 2 // CHECK1-NEXT: [[ARRAYDECAY12:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYIDX11]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY12]], i64 1 -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 1 +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw double, ptr [[ARRAYDECAY12]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw [10 x [10 x [10 x double]]], ptr [[TMP0]], i64 0, i64 1 // CHECK1-NEXT: [[ARRAYDECAY15:%.*]] = getelementptr inbounds [10 x [10 x double]], ptr [[ARRAYIDX14]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYDECAY15]], i64 5 +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw [10 x double], ptr [[ARRAYDECAY15]], i64 5 // CHECK1-NEXT: [[ARRAYDECAY17:%.*]] = getelementptr inbounds [10 x double], ptr [[ARRAYIDX16]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY17]], i64 1 +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw double, ptr [[ARRAYDECAY17]], i64 1 // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX13]], ptr [[TMP15]], align 8 @@ -852,7 +852,7 @@ int main() // CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i32 0 // CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[INPUT_ADDR]], align 4 // CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[INPUT_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 0 +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i32 0 // CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 // CHECK2-NEXT: [[TMP9:%.*]] = mul nuw i32 [[TMP8]], 4 // CHECK2-NEXT: [[TMP10:%.*]] = sext i32 [[TMP9]] to i64 @@ -930,10 +930,10 @@ int main() // CHECK2-NEXT: [[TMP46:%.*]] = load ptr, ptr [[INPUT_ADDR]], align 4 // CHECK2-NEXT: [[TMP47:%.*]] = load ptr, ptr [[OUTPUT_ADDR]], align 4 // CHECK2-NEXT: [[TMP48:%.*]] = load ptr, ptr [[OUTPUT_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[TMP48]], i32 0 +// CHECK2-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP48]], i32 0 // CHECK2-NEXT: [[TMP49:%.*]] = load ptr, ptr [[INPUT_ADDR]], align 4 // CHECK2-NEXT: [[TMP50:%.*]] = load ptr, ptr [[INPUT_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[TMP50]], i32 0 +// CHECK2-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP50]], i32 0 // CHECK2-NEXT: [[TMP51:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 // CHECK2-NEXT: [[TMP52:%.*]] = mul nuw i32 [[TMP51]], 4 // CHECK2-NEXT: [[TMP53:%.*]] = sext i32 [[TMP52]] to i64 @@ -1007,7 +1007,7 @@ int main() // CHECK2-NEXT: [[TMP86:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 // CHECK2-NEXT: store i32 [[TMP86]], ptr [[SIZE_CASTED21]], align 4 // CHECK2-NEXT: [[TMP87:%.*]] = load i32, ptr [[SIZE_CASTED21]], align 4 -// CHECK2-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds [10 x i32], ptr [[A]], i32 0, i32 0 +// CHECK2-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds nuw [10 x i32], ptr [[A]], i32 0, i32 0 // CHECK2-NEXT: [[TMP88:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK2-NEXT: store i32 [[TMP87]], ptr [[TMP88]], align 4 // CHECK2-NEXT: [[TMP89:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 @@ -1480,9 +1480,9 @@ int main() // CHECK2-NEXT: store ptr [[OUTPUT]], ptr [[OUTPUT_ADDR]], align 4 // CHECK2-NEXT: store ptr [[INPUT]], ptr [[INPUT_ADDR]], align 4 // CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[OUTPUT_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 0 +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i32 0 // CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[OUTPUT_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 2 +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 2 // CHECK2-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [3 x i32], ptr [[OUTPUT2]], i32 0, i32 0 // CHECK2-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[ARRAY_BEGIN]], i32 3 // CHECK2-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP2]] @@ -1664,9 +1664,9 @@ int main() // CHECK2-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 // CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[OUTPUT_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0 +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP6]], i32 0 // CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[OUTPUT_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 2 +// CHECK2-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i32 2 // CHECK2-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [3 x i32], ptr [[OUTPUT4]], i32 0, i32 0 // CHECK2-NEXT: [[TMP8:%.*]] = getelementptr i32, ptr [[ARRAY_BEGIN]], i32 3 // CHECK2-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP8]] @@ -1878,8 +1878,8 @@ int main() // CHECK2-NEXT: store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4 // CHECK2-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 4 // CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 4 -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], ptr [[TMP0]], i32 0, i32 0 -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x i32], ptr [[TMP0]], i32 0, i32 1 +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [10 x i32], ptr [[TMP0]], i32 0, i32 0 +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [10 x i32], ptr [[TMP0]], i32 0, i32 1 // CHECK2-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x i32], ptr [[A2]], i32 0, i32 0 // CHECK2-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[ARRAY_BEGIN]], i32 2 // CHECK2-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN]], [[TMP1]] diff --git a/clang/test/OpenMP/sections_reduction_task_codegen.cpp b/clang/test/OpenMP/sections_reduction_task_codegen.cpp index 1a2cf7aede321..5d749eeb81776 100644 --- a/clang/test/OpenMP/sections_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/sections_reduction_task_codegen.cpp @@ -82,16 +82,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP3]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP5:%.*]] = sext i32 [[TMP4]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP5]] // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP6]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP6]], i64 9 // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP7]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP7]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP10:%.*]] = sub i64 [[TMP8]], [[TMP9]] @@ -121,7 +121,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP21]] // CHECK1-NEXT: store ptr [[_TMP5]], ptr [[TMP]], align 8 // CHECK1-NEXT: store ptr [[TMP22]], ptr [[_TMP5]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP23]], align 8 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -136,19 +136,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP28]], align 8 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP29]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load ptr, ptr [[ARRAYIDX7]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[TMP32]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 0 // CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP34:%.*]] = sext i32 [[TMP33]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN9:%.*]] = add nsw i64 -1, [[TMP34]] // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds ptr, ptr [[TMP35]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP35]], i64 9 // CHECK1-NEXT: [[TMP36:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[TMP36]], i64 [[LB_ADD_LEN9]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP36]], i64 [[LB_ADD_LEN9]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP30]], align 8 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[TMP37]], align 8 @@ -463,9 +463,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp b/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp index d912f801a33db..19a523ee165c8 100644 --- a/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp +++ b/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp @@ -54,12 +54,12 @@ int main() { // CHECK: [[SIZES:%.+]] = alloca [6 x i64], // CHECK: [[VLA_ADDR:%.+]] = alloca float, i64 %{{.+}}, // CHECK: [[PTR:%.+]] = load ptr, ptr [[PTR_ADDR]], -// CHECK-NEXT: [[ARR_IDX:%.+]] = getelementptr inbounds float, ptr [[PTR]], i64 3 +// CHECK-NEXT: [[ARR_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[PTR]], i64 3 // CHECK: [[P5:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8 // CHECK-NEXT: [[ARR_IDX1:%.+]] = getelementptr inbounds float, ptr [[P5]], i64 0 // CHECK: [[P7:%.+]] = load ptr, ptr [[REF_ADDR]], // CHECK-NEXT: [[REF:%.+]] = load ptr, ptr [[REF_ADDR]], -// CHECK-NEXT: [[ARR_IDX2:%.+]] = getelementptr inbounds [4 x float], ptr [[ARR_ADDR]], i64 0, i64 0 +// CHECK-NEXT: [[ARR_IDX2:%.+]] = getelementptr inbounds nuw [4 x float], ptr [[ARR_ADDR]], i64 0, i64 0 // CHECK: [[P10:%.+]] = mul nuw i64 {{.+}}, 4 // CHECK-NEXT: [[ARR_IDX5:%.+]] = getelementptr inbounds float, ptr [[VLA_ADDR]], i64 0 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[SIZES]], ptr align 8 [[SIZES1]], i64 48, i1 false) @@ -132,14 +132,14 @@ int main() { // CHECK: [[SIZES:%.+]] = alloca [6 x i64], // CHECK: [[A_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS:%.+]], i32 0, i32 0 // CHECK: [[PTR_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 1 -// CHECK: [[ARR_IDX:%.+]] = getelementptr inbounds i32, ptr %{{.+}}, i64 3 +// CHECK: [[ARR_IDX:%.+]] = getelementptr inbounds nuw i32, ptr %{{.+}}, i64 3 // CHECK: [[REF_REF:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 2 // CHECK: [[REF_PTR:%.+]] = load ptr, ptr [[REF_REF]], // CHECK-NEXT: [[P3:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 1 // CHECK: [[ARR_IDX5:%.+]] = getelementptr inbounds i32, ptr {{.+}}, i64 0 // CHECK: [[ARR_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 3 -// CHECK: [[ARR_IDX6:%.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0 +// CHECK: [[ARR_IDX6:%.+]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0 // CHECK: [[A_ADDR2:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 0 // CHECK: [[P4:%.+]] = mul nuw i64 [[CONV:%.+]], 4 // CHECK: [[A_ADDR3:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 0 @@ -147,7 +147,7 @@ int main() { // CHECK: [[L6:%.+]] = sext i32 [[L5]] to i64 // CHECK: [[LB_ADD_LEN:%lb_add_len]] = add nsw i64 -1, [[L6]] // CHECK: [[ARR_ADDR9:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 3 -// CHECK: [[ARR_IDX10:%arrayidx.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR9]], i64 0, i64 %lb_add_len +// CHECK: [[ARR_IDX10:%arrayidx.+]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR_ADDR9]], i64 0, i64 %lb_add_len // CHECK: [[ARR_END:%.+]] = getelementptr i32, ptr [[ARR_IDX10]], i32 1 // CHECK: [[E:%.+]] = ptrtoint ptr [[ARR_END]] to i64 // CHECK: [[B:%.+]] = ptrtoint ptr [[A_ADDR]] to i64 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 c90819dc2a22f..6d1c0213d648c 100644 --- a/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp +++ b/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp @@ -49,14 +49,14 @@ void foo(float *&lr, T *&tr) { // CK1-NOT: store ptr [[VAL]], ptr [[DECL]], // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[TT:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds double, ptr [[TT]], i32 1 + // CK1: getelementptr inbounds nuw double, ptr [[TT]], i32 1 #pragma omp target data map(g[:10]) use_device_ptr(g) { ++g; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE00]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds double, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw double, ptr [[TTT]], i32 1 ++g; // CK1: [[T1:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -67,26 +67,26 @@ void foo(float *&lr, T *&tr) { // CK1-NOT: store ptr [[VAL]], ptr [[DECL]], // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds float, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TT1]], i32 1 #pragma omp target data map(l[:10]) use_device_ptr(l) { ++l; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE01]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds float, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTT]], i32 1 ++l; // CK1-NOT: call void @__tgt_target // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds float, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTT]], i32 1 #pragma omp target data map(l[:10]) use_device_ptr(l) if(0) { ++l; } // CK1-NOT: call void @__tgt_target // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds float, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTT]], i32 1 ++l; // CK1: [[T1:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -97,14 +97,14 @@ void foo(float *&lr, T *&tr) { // CK1-NOT: store ptr [[VAL]], ptr [[DECL]], // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds float, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TT1]], i32 1 #pragma omp target data map(l[:10]) use_device_ptr(l) if(1) { ++l; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE03]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds float, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTT]], i32 1 ++l; // CK1: [[CMP:%.+]] = icmp ne ptr %{{.+}}, null @@ -119,12 +119,12 @@ void foo(float *&lr, T *&tr) { // CK1-NOT: store ptr [[VAL]], ptr [[DECL]], // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds float, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TT1]], i32 1 // CK1: br label %[[BEND:.+]] // CK1: [[BELSE]]: // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds float, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTT]], i32 1 // CK1: br label %[[BEND]] #pragma omp target data map(l[:10]) use_device_ptr(l) if(lr != 0) { @@ -142,7 +142,7 @@ void foo(float *&lr, T *&tr) { // CK1: [[BEND]]: // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds float, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTT]], i32 1 ++l; // CK1: [[T2:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -156,7 +156,7 @@ void foo(float *&lr, T *&tr) { // CK1: store ptr [[PVTV]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], // CK1: [[TT2:%.+]] = load ptr, ptr [[TT1]], - // CK1: getelementptr inbounds float, ptr [[TT2]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TT2]], i32 1 #pragma omp target data map(lr[:10]) use_device_ptr(lr) { ++lr; @@ -164,7 +164,7 @@ void foo(float *&lr, T *&tr) { // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE05]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], // CK1: [[TTTT:%.+]] = load ptr, ptr [[TTT]], - // CK1: getelementptr inbounds float, ptr [[TTTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTTT]], i32 1 ++lr; // CK1: [[T1:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -175,14 +175,14 @@ void foo(float *&lr, T *&tr) { // CK1-NOT: store ptr [[VAL]], ptr [[DECL]], // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds i32, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TT1]], i32 1 #pragma omp target data map(t[:10]) use_device_ptr(t) { ++t; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE06]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds i32, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TTT]], i32 1 ++t; // CK1: [[T2:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -196,7 +196,7 @@ void foo(float *&lr, T *&tr) { // CK1: store ptr [[PVTV]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], // CK1: [[TT2:%.+]] = load ptr, ptr [[TT1]], - // CK1: getelementptr inbounds i32, ptr [[TT2]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TT2]], i32 1 #pragma omp target data map(tr[:10]) use_device_ptr(tr) { ++tr; @@ -204,7 +204,7 @@ void foo(float *&lr, T *&tr) { // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE07]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], // CK1: [[TTTT:%.+]] = load ptr, ptr [[TTT]], - // CK1: getelementptr inbounds i32, ptr [[TTTT]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TTTT]], i32 1 ++tr; // CK1: [[T1:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -215,14 +215,14 @@ void foo(float *&lr, T *&tr) { // CK1-NOT: store ptr [[VAL]], ptr [[DECL]], // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds float, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TT1]], i32 1 #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l) { ++l; ++t; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE08]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds float, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[TTT]], i32 1 ++l; ++t; @@ -232,18 +232,18 @@ void foo(float *&lr, T *&tr) { // CK1: [[VAL:%.+]] = load ptr, ptr {{%.+}}, // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[_TT1:%.+]] = load ptr, ptr [[_PVT]], - // CK1: getelementptr inbounds float, ptr [[_TT1]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[_TT1]], i32 1 // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds i32, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TT1]], i32 1 #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l) use_device_ptr(t) { ++l; ++t; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE09]] // CK1: [[_TTT:%.+]] = load ptr, ptr {{%.+}}, - // CK1: getelementptr inbounds float, ptr [[_TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[_TTT]], i32 1 // CK1: [[TTT:%.+]] = load ptr, ptr {{%.+}}, - // CK1: getelementptr inbounds i32, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TTT]], i32 1 ++l; ++t; // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE10]] @@ -252,18 +252,18 @@ void foo(float *&lr, T *&tr) { // CK1: [[VAL:%.+]] = load ptr, ptr {{%.+}}, // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[_TT1:%.+]] = load ptr, ptr [[_PVT]], - // CK1: getelementptr inbounds float, ptr [[_TT1]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[_TT1]], i32 1 // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds i32, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TT1]], i32 1 #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l,t) { ++l; ++t; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE10]] // CK1: [[_TTT:%.+]] = load ptr, ptr {{%.+}}, - // CK1: getelementptr inbounds float, ptr [[_TTT]], i32 1 + // CK1: getelementptr inbounds nuw float, ptr [[_TTT]], i32 1 // CK1: [[TTT:%.+]] = load ptr, ptr {{%.+}}, - // CK1: getelementptr inbounds i32, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TTT]], i32 1 ++l; ++t; // CK1: [[T1:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -274,14 +274,14 @@ void foo(float *&lr, T *&tr) { // CK1-NOT: store ptr [[VAL]], ptr [[DECL]], // CK1: store ptr [[VAL]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], - // CK1: getelementptr inbounds i32, ptr [[TT1]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TT1]], i32 1 #pragma omp target data map(l[:10]) use_device_ptr(t) { ++l; ++t; } // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE11]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK1: getelementptr inbounds i32, ptr [[TTT]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TTT]], i32 1 ++l; ++t; // CK1: [[T2:%.+]] = load ptr, ptr [[DECL:%.+]], @@ -295,7 +295,7 @@ void foo(float *&lr, T *&tr) { // CK1: store ptr [[PVTV]], ptr [[PVT:%.+]], // CK1: [[TT1:%.+]] = load ptr, ptr [[PVT]], // CK1: [[TT2:%.+]] = load ptr, ptr [[TT1]], - // CK1: getelementptr inbounds i32, ptr [[TT2]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TT2]], i32 1 #pragma omp target data map(l[:10]) use_device_ptr(tr) { ++l; ++tr; @@ -303,7 +303,7 @@ void foo(float *&lr, T *&tr) { // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE12]] // CK1: [[TTT:%.+]] = load ptr, ptr [[DECL]], // CK1: [[TTTT:%.+]] = load ptr, ptr [[TTT]], - // CK1: getelementptr inbounds i32, ptr [[TTTT]], i32 1 + // CK1: getelementptr inbounds nuw i32, ptr [[TTTT]], i32 1 ++l; ++tr; } @@ -354,7 +354,7 @@ struct ST { // CK2: store ptr [[PVT]], ptr [[PVT2:%.+]], // CK2: [[TT1:%.+]] = load ptr, ptr [[PVT2]], // CK2: [[TT2:%.+]] = load ptr, ptr [[TT1]], - // CK2: getelementptr inbounds double, ptr [[TT2]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[TT2]], i32 1 #pragma omp target data map(a[:10]) use_device_ptr(a) { a++; @@ -362,7 +362,7 @@ struct ST { // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE00]] // CK2: [[DECL:%.+]] = getelementptr inbounds nuw [[ST]], ptr %this1, i32 0, i32 0 // CK2: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK2: getelementptr inbounds double, ptr [[TTT]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[TTT]], i32 1 a++; // CK2: [[BP:%.+]] = getelementptr inbounds [2 x ptr], ptr %{{.+}}, i32 0, i32 1 @@ -373,7 +373,7 @@ struct ST { // CK2: store ptr [[PVT]], ptr [[PVT2:%.+]], // CK2: [[TT1:%.+]] = load ptr, ptr [[PVT2]], // CK2: [[TT2:%.+]] = load ptr, ptr [[TT1]], - // CK2: getelementptr inbounds double, ptr [[TT2]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[TT2]], i32 1 #pragma omp target data map(b[:10]) use_device_ptr(b) { b++; @@ -382,7 +382,7 @@ struct ST { // CK2: [[DECL:%.+]] = getelementptr inbounds nuw [[ST]], ptr %{{.+}}, i32 0, i32 1 // CK2: [[TTT:%.+]] = load ptr, ptr [[DECL]], // CK2: [[TTTT:%.+]] = load ptr, ptr [[TTT]], - // CK2: getelementptr inbounds double, ptr [[TTTT]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[TTTT]], i32 1 b++; // CK2: [[BP:%.+]] = getelementptr inbounds [3 x ptr], ptr %{{.+}}, i32 0, i32 2 @@ -393,7 +393,7 @@ struct ST { // CK2: store ptr [[PVT]], ptr [[PVT2:%.+]], // CK2: [[TT1:%.+]] = load ptr, ptr [[PVT2]], // CK2: [[TT2:%.+]] = load ptr, ptr [[TT1]], - // CK2: getelementptr inbounds double, ptr [[TT2]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[TT2]], i32 1 #pragma omp target data map(la[:10]) use_device_ptr(a) { a++; @@ -402,7 +402,7 @@ struct ST { // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE02]] // CK2: [[DECL:%.+]] = getelementptr inbounds nuw [[ST]], ptr %this1, i32 0, i32 0 // CK2: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK2: getelementptr inbounds double, ptr [[TTT]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[TTT]], i32 1 a++; la++; @@ -419,10 +419,10 @@ struct ST { // CK2: store ptr [[PVT1]], ptr [[_PVT1:%.+]], // CK2: [[TT2:%.+]] = load ptr, ptr [[_PVT2]], // CK2: [[_TT2:%.+]] = load ptr, ptr [[TT2]], - // CK2: getelementptr inbounds double, ptr [[_TT2]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[_TT2]], i32 1 // CK2: [[TT1:%.+]] = load ptr, ptr [[_PVT1]], // CK2: [[_TT1:%.+]] = load ptr, ptr [[TT1]], - // CK2: getelementptr inbounds double, ptr [[_TT1]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[_TT1]], i32 1 #pragma omp target data map(b[:10]) use_device_ptr(a, b) { a++; @@ -431,11 +431,11 @@ struct ST { // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE03]] // CK2: [[DECL:%.+]] = getelementptr inbounds nuw [[ST]], ptr %this1, i32 0, i32 0 // CK2: [[TTT:%.+]] = load ptr, ptr [[DECL]], - // CK2: getelementptr inbounds double, ptr [[TTT]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[TTT]], i32 1 // CK2: [[_DECL:%.+]] = getelementptr inbounds nuw [[ST]], ptr %this1, i32 0, i32 1 // CK2: [[_TTT:%.+]] = load ptr, ptr [[_DECL]], // CK2: [[_TTTT:%.+]] = load ptr, ptr [[_TTT]], - // CK2: getelementptr inbounds double, ptr [[_TTTT]], i32 1 + // CK2: getelementptr inbounds nuw double, ptr [[_TTTT]], i32 1 a++; b++; } diff --git a/clang/test/OpenMP/target_has_device_addr_codegen.cpp b/clang/test/OpenMP/target_has_device_addr_codegen.cpp index 08bcc87ca5f0a..39eaedb0e48d1 100644 --- a/clang/test/OpenMP/target_has_device_addr_codegen.cpp +++ b/clang/test/OpenMP/target_has_device_addr_codegen.cpp @@ -586,7 +586,7 @@ void use_template() { // CHECK-NEXT: store ptr [[K]], ptr [[K_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[K_ADDR]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CHECK-NEXT: ret void // @@ -601,7 +601,7 @@ void use_template() { // CHECK-NEXT: store ptr [[TMP0]], ptr [[TMP]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP1]], align 8 // CHECK-NEXT: ret void // @@ -1079,7 +1079,7 @@ void use_template() { // CHECK-NEXT: store ptr [[K]], ptr [[K_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[K_ADDR]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CHECK-NEXT: ret void // @@ -1094,7 +1094,7 @@ void use_template() { // CHECK-NEXT: store ptr [[TMP0]], ptr [[TMP]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP1]], align 8 // CHECK-NEXT: ret void // @@ -1133,7 +1133,7 @@ void use_template() { // CHECK-NEXT: store ptr [[K]], ptr [[K_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[K_ADDR]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CHECK-NEXT: ret void // @@ -1148,7 +1148,7 @@ void use_template() { // CHECK-NEXT: store ptr [[TMP0]], ptr [[TMP]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i32 1 +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP2]], i32 1 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP1]], align 8 // CHECK-NEXT: ret void // @@ -1422,14 +1422,14 @@ void use_template() { // SIMD-ONLY0-NEXT: store ptr [[K]], ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: store ptr [[AA]], ptr [[RAA]], align 8 // SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load ptr, ptr [[K]], align 8 -// SIMD-ONLY0-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// SIMD-ONLY0-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // SIMD-ONLY0-NEXT: store ptr [[INCDEC_PTR]], ptr [[K]], align 8 // SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load ptr, ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: store ptr [[TMP2]], ptr [[TMP]], align 8 // SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load ptr, ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP]], align 8 // SIMD-ONLY0-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 -// SIMD-ONLY0-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i32 1 +// SIMD-ONLY0-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP5]], i32 1 // SIMD-ONLY0-NEXT: store ptr [[INCDEC_PTR1]], ptr [[TMP4]], align 8 // SIMD-ONLY0-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], ptr [[AA]], i64 0, i64 0 // SIMD-ONLY0-NEXT: store i32 1, ptr [[ARRAYIDX]], align 4 @@ -1478,14 +1478,14 @@ void use_template() { // SIMD-ONLY0-NEXT: store ptr [[TMP0]], ptr [[K]], align 8 // SIMD-ONLY0-NEXT: store ptr [[K]], ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load ptr, ptr [[K]], align 8 -// SIMD-ONLY0-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// SIMD-ONLY0-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // SIMD-ONLY0-NEXT: store ptr [[INCDEC_PTR]], ptr [[K]], align 8 // SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load ptr, ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: store ptr [[TMP2]], ptr [[TMP]], align 8 // SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load ptr, ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP]], align 8 // SIMD-ONLY0-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 -// SIMD-ONLY0-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i32 1 +// SIMD-ONLY0-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP5]], i32 1 // SIMD-ONLY0-NEXT: store ptr [[INCDEC_PTR1]], ptr [[TMP4]], align 8 // SIMD-ONLY0-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], ptr [[AA]], i64 0, i64 0 // SIMD-ONLY0-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 @@ -1520,14 +1520,14 @@ void use_template() { // SIMD-ONLY0-NEXT: store ptr [[TMP0]], ptr [[K]], align 8 // SIMD-ONLY0-NEXT: store ptr [[K]], ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load ptr, ptr [[K]], align 8 -// SIMD-ONLY0-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i32 1 +// SIMD-ONLY0-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i32 1 // SIMD-ONLY0-NEXT: store ptr [[INCDEC_PTR]], ptr [[K]], align 8 // SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load ptr, ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: store ptr [[TMP2]], ptr [[TMP]], align 8 // SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load ptr, ptr [[Z]], align 8 // SIMD-ONLY0-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP]], align 8 // SIMD-ONLY0-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 -// SIMD-ONLY0-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i32 1 +// SIMD-ONLY0-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i32 1 // SIMD-ONLY0-NEXT: store ptr [[INCDEC_PTR1]], ptr [[TMP4]], align 8 // SIMD-ONLY0-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[AA]], i64 0, i64 0 // SIMD-ONLY0-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 diff --git a/clang/test/OpenMP/target_in_reduction_codegen.cpp b/clang/test/OpenMP/target_in_reduction_codegen.cpp index fb715e2de2a59..56191ee575136 100644 --- a/clang/test/OpenMP/target_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_in_reduction_codegen.cpp @@ -70,7 +70,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[VLA:%.*]] = alloca i16, i64 [[TMP2]], align 16 // CHECK1-NEXT: store i64 [[TMP2]], ptr [[__VLA_EXPR0]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[A]], ptr [[TMP4]], align 8 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -85,7 +85,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP11]], align 8 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP12]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[B]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 1 @@ -100,7 +100,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..2, ptr [[TMP21]], align 8 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP22]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC_ADDR]], ptr [[TMP24]], align 8 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 1 @@ -118,7 +118,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP35:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 3, ptr [[DOTRD_INPUT_]]) // CHECK1-NEXT: store ptr [[TMP35]], ptr [[DOTTASK_RED_]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[C]], ptr [[TMP36]], align 8 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 1 @@ -133,7 +133,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..6, ptr [[TMP43]], align 8 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP44]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP46]], align 8 // CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 1 diff --git a/clang/test/OpenMP/target_is_device_ptr_codegen.cpp b/clang/test/OpenMP/target_is_device_ptr_codegen.cpp index 3a1c168533c37..505c34e21733c 100644 --- a/clang/test/OpenMP/target_is_device_ptr_codegen.cpp +++ b/clang/test/OpenMP/target_is_device_ptr_codegen.cpp @@ -2142,7 +2142,7 @@ void bar() { // CK10-NEXT: [[G_ADDR:%.*]] = alloca ptr, align 8 // CK10-NEXT: store ptr [[G]], ptr [[G_ADDR]], align 8 // CK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[G_ADDR]], align 8 -// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR]], ptr [[G_ADDR]], align 8 // CK10-NEXT: ret void // @@ -2153,7 +2153,7 @@ void bar() { // CK10-NEXT: [[L_ADDR:%.*]] = alloca ptr, align 8 // CK10-NEXT: store ptr [[L]], ptr [[L_ADDR]], align 8 // CK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[L_ADDR]], align 8 -// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP0]], i32 1 +// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP0]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR]], ptr [[L_ADDR]], align 8 // CK10-NEXT: ret void // @@ -2164,7 +2164,7 @@ void bar() { // CK10-NEXT: [[T_ADDR:%.*]] = alloca ptr, align 8 // CK10-NEXT: store ptr [[T]], ptr [[T_ADDR]], align 8 // CK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_ADDR]], align 8 -// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1 +// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR]], ptr [[T_ADDR]], align 8 // CK10-NEXT: ret void // @@ -2178,7 +2178,7 @@ void bar() { // CK10-NEXT: store ptr [[LR_ADDR]], ptr [[TMP]], align 8 // CK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK10-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK10-NEXT: ret void // @@ -2192,7 +2192,7 @@ void bar() { // CK10-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 8 // CK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK10-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK10-NEXT: ret void // @@ -2206,7 +2206,7 @@ void bar() { // CK10-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 8 // CK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK10-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK10-NEXT: ret void // @@ -2224,11 +2224,11 @@ void bar() { // CK10-NEXT: store ptr [[LR_ADDR]], ptr [[_TMP1]], align 8 // CK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK10-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK10-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8 // CK10-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 8 -// CK10-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i32 1 +// CK10-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i32 1 // CK10-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP2]], align 8 // CK10-NEXT: ret void // @@ -2613,7 +2613,7 @@ void bar() { // CK11-NEXT: [[G_ADDR:%.*]] = alloca ptr, align 8 // CK11-NEXT: store ptr [[G]], ptr [[G_ADDR]], align 8 // CK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[G_ADDR]], align 8 -// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR]], ptr [[G_ADDR]], align 8 // CK11-NEXT: ret void // @@ -2624,7 +2624,7 @@ void bar() { // CK11-NEXT: [[L_ADDR:%.*]] = alloca ptr, align 8 // CK11-NEXT: store ptr [[L]], ptr [[L_ADDR]], align 8 // CK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[L_ADDR]], align 8 -// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP0]], i32 1 +// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP0]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR]], ptr [[L_ADDR]], align 8 // CK11-NEXT: ret void // @@ -2635,7 +2635,7 @@ void bar() { // CK11-NEXT: [[T_ADDR:%.*]] = alloca ptr, align 8 // CK11-NEXT: store ptr [[T]], ptr [[T_ADDR]], align 8 // CK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_ADDR]], align 8 -// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1 +// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR]], ptr [[T_ADDR]], align 8 // CK11-NEXT: ret void // @@ -2649,7 +2649,7 @@ void bar() { // CK11-NEXT: store ptr [[LR_ADDR]], ptr [[TMP]], align 8 // CK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK11-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK11-NEXT: ret void // @@ -2663,7 +2663,7 @@ void bar() { // CK11-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 8 // CK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK11-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK11-NEXT: ret void // @@ -2677,7 +2677,7 @@ void bar() { // CK11-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 8 // CK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK11-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK11-NEXT: ret void // @@ -2695,11 +2695,11 @@ void bar() { // CK11-NEXT: store ptr [[LR_ADDR]], ptr [[_TMP1]], align 8 // CK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 // CK11-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 -// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 8 // CK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8 // CK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 8 -// CK11-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i32 1 +// CK11-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i32 1 // CK11-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP2]], align 8 // CK11-NEXT: ret void // @@ -3084,7 +3084,7 @@ void bar() { // CK12-NEXT: [[G_ADDR:%.*]] = alloca ptr, align 4 // CK12-NEXT: store ptr [[G]], ptr [[G_ADDR]], align 4 // CK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[G_ADDR]], align 4 -// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR]], ptr [[G_ADDR]], align 4 // CK12-NEXT: ret void // @@ -3095,7 +3095,7 @@ void bar() { // CK12-NEXT: [[L_ADDR:%.*]] = alloca ptr, align 4 // CK12-NEXT: store ptr [[L]], ptr [[L_ADDR]], align 4 // CK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[L_ADDR]], align 4 -// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP0]], i32 1 +// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP0]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR]], ptr [[L_ADDR]], align 4 // CK12-NEXT: ret void // @@ -3106,7 +3106,7 @@ void bar() { // CK12-NEXT: [[T_ADDR:%.*]] = alloca ptr, align 4 // CK12-NEXT: store ptr [[T]], ptr [[T_ADDR]], align 4 // CK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_ADDR]], align 4 -// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1 +// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR]], ptr [[T_ADDR]], align 4 // CK12-NEXT: ret void // @@ -3120,7 +3120,7 @@ void bar() { // CK12-NEXT: store ptr [[LR_ADDR]], ptr [[TMP]], align 4 // CK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK12-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK12-NEXT: ret void // @@ -3134,7 +3134,7 @@ void bar() { // CK12-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 4 // CK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK12-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK12-NEXT: ret void // @@ -3148,7 +3148,7 @@ void bar() { // CK12-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 4 // CK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK12-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK12-NEXT: ret void // @@ -3166,11 +3166,11 @@ void bar() { // CK12-NEXT: store ptr [[LR_ADDR]], ptr [[_TMP1]], align 4 // CK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK12-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK12-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 4 // CK12-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 4 -// CK12-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i32 1 +// CK12-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i32 1 // CK12-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP2]], align 4 // CK12-NEXT: ret void // @@ -3555,7 +3555,7 @@ void bar() { // CK13-NEXT: [[G_ADDR:%.*]] = alloca ptr, align 4 // CK13-NEXT: store ptr [[G]], ptr [[G_ADDR]], align 4 // CK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[G_ADDR]], align 4 -// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR]], ptr [[G_ADDR]], align 4 // CK13-NEXT: ret void // @@ -3566,7 +3566,7 @@ void bar() { // CK13-NEXT: [[L_ADDR:%.*]] = alloca ptr, align 4 // CK13-NEXT: store ptr [[L]], ptr [[L_ADDR]], align 4 // CK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[L_ADDR]], align 4 -// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP0]], i32 1 +// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP0]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR]], ptr [[L_ADDR]], align 4 // CK13-NEXT: ret void // @@ -3577,7 +3577,7 @@ void bar() { // CK13-NEXT: [[T_ADDR:%.*]] = alloca ptr, align 4 // CK13-NEXT: store ptr [[T]], ptr [[T_ADDR]], align 4 // CK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_ADDR]], align 4 -// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1 +// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR]], ptr [[T_ADDR]], align 4 // CK13-NEXT: ret void // @@ -3591,7 +3591,7 @@ void bar() { // CK13-NEXT: store ptr [[LR_ADDR]], ptr [[TMP]], align 4 // CK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK13-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK13-NEXT: ret void // @@ -3605,7 +3605,7 @@ void bar() { // CK13-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 4 // CK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK13-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK13-NEXT: ret void // @@ -3619,7 +3619,7 @@ void bar() { // CK13-NEXT: store ptr [[TR_ADDR]], ptr [[TMP]], align 4 // CK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK13-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK13-NEXT: ret void // @@ -3637,11 +3637,11 @@ void bar() { // CK13-NEXT: store ptr [[LR_ADDR]], ptr [[_TMP1]], align 4 // CK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 4 // CK13-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 -// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 1 +// CK13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP0]], align 4 // CK13-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 4 // CK13-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 4 -// CK13-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds float, ptr [[TMP3]], i32 1 +// CK13-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i32 1 // CK13-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP2]], align 4 // CK13-NEXT: ret void // @@ -3674,34 +3674,34 @@ void bar() { // SIMD-ONLY00-NEXT: store ptr [[LR]], ptr [[LR_ADDR]], align 8 // SIMD-ONLY00-NEXT: store ptr [[TR]], ptr [[TR_ADDR]], align 8 // SIMD-ONLY00-NEXT: [[TMP0:%.*]] = load ptr, ptr @g, align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR]], ptr @g, align 8 // SIMD-ONLY00-NEXT: [[TMP1:%.*]] = load ptr, ptr [[L]], align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR1]], ptr [[L]], align 8 // SIMD-ONLY00-NEXT: [[TMP2:%.*]] = load ptr, ptr [[T]], align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR2]], ptr [[T]], align 8 // SIMD-ONLY00-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LR_ADDR]], align 8 // SIMD-ONLY00-NEXT: store ptr [[TMP3]], ptr [[TMP]], align 8 // SIMD-ONLY00-NEXT: [[TMP4:%.*]] = load ptr, ptr [[LR_ADDR]], align 8 // SIMD-ONLY00-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP]], align 8 // SIMD-ONLY00-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR3]], ptr [[TMP5]], align 8 // SIMD-ONLY00-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY00-NEXT: store ptr [[TMP7]], ptr [[_TMP4]], align 8 // SIMD-ONLY00-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY00-NEXT: [[TMP9:%.*]] = load ptr, ptr [[_TMP4]], align 8 // SIMD-ONLY00-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP10]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR5]], ptr [[TMP9]], align 8 // SIMD-ONLY00-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY00-NEXT: store ptr [[TMP11]], ptr [[_TMP6]], align 8 // SIMD-ONLY00-NEXT: [[TMP12:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY00-NEXT: [[TMP13:%.*]] = load ptr, ptr [[_TMP6]], align 8 // SIMD-ONLY00-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP13]], align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds i32, ptr [[TMP14]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP14]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR7]], ptr [[TMP13]], align 8 // SIMD-ONLY00-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY00-NEXT: store ptr [[TMP15]], ptr [[_TMP8]], align 8 @@ -3711,11 +3711,11 @@ void bar() { // SIMD-ONLY00-NEXT: [[TMP18:%.*]] = load ptr, ptr [[LR_ADDR]], align 8 // SIMD-ONLY00-NEXT: [[TMP19:%.*]] = load ptr, ptr [[_TMP8]], align 8 // SIMD-ONLY00-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP19]], align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds i32, ptr [[TMP20]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP20]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR10]], ptr [[TMP19]], align 8 // SIMD-ONLY00-NEXT: [[TMP21:%.*]] = load ptr, ptr [[_TMP9]], align 8 // SIMD-ONLY00-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP21]], align 8 -// SIMD-ONLY00-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i32 1 +// SIMD-ONLY00-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i32 1 // SIMD-ONLY00-NEXT: store ptr [[INCDEC_PTR11]], ptr [[TMP21]], align 8 // SIMD-ONLY00-NEXT: ret void // @@ -3748,34 +3748,34 @@ void bar() { // SIMD-ONLY01-NEXT: store ptr [[LR]], ptr [[LR_ADDR]], align 8 // SIMD-ONLY01-NEXT: store ptr [[TR]], ptr [[TR_ADDR]], align 8 // SIMD-ONLY01-NEXT: [[TMP0:%.*]] = load ptr, ptr @g, align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR]], ptr @g, align 8 // SIMD-ONLY01-NEXT: [[TMP1:%.*]] = load ptr, ptr [[L]], align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR1]], ptr [[L]], align 8 // SIMD-ONLY01-NEXT: [[TMP2:%.*]] = load ptr, ptr [[T]], align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR2]], ptr [[T]], align 8 // SIMD-ONLY01-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LR_ADDR]], align 8 // SIMD-ONLY01-NEXT: store ptr [[TMP3]], ptr [[TMP]], align 8 // SIMD-ONLY01-NEXT: [[TMP4:%.*]] = load ptr, ptr [[LR_ADDR]], align 8 // SIMD-ONLY01-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP]], align 8 // SIMD-ONLY01-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR3]], ptr [[TMP5]], align 8 // SIMD-ONLY01-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY01-NEXT: store ptr [[TMP7]], ptr [[_TMP4]], align 8 // SIMD-ONLY01-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY01-NEXT: [[TMP9:%.*]] = load ptr, ptr [[_TMP4]], align 8 // SIMD-ONLY01-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP10]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR5]], ptr [[TMP9]], align 8 // SIMD-ONLY01-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY01-NEXT: store ptr [[TMP11]], ptr [[_TMP6]], align 8 // SIMD-ONLY01-NEXT: [[TMP12:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY01-NEXT: [[TMP13:%.*]] = load ptr, ptr [[_TMP6]], align 8 // SIMD-ONLY01-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP13]], align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds i32, ptr [[TMP14]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP14]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR7]], ptr [[TMP13]], align 8 // SIMD-ONLY01-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TR_ADDR]], align 8 // SIMD-ONLY01-NEXT: store ptr [[TMP15]], ptr [[_TMP8]], align 8 @@ -3785,11 +3785,11 @@ void bar() { // SIMD-ONLY01-NEXT: [[TMP18:%.*]] = load ptr, ptr [[LR_ADDR]], align 8 // SIMD-ONLY01-NEXT: [[TMP19:%.*]] = load ptr, ptr [[_TMP8]], align 8 // SIMD-ONLY01-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP19]], align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds i32, ptr [[TMP20]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP20]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR10]], ptr [[TMP19]], align 8 // SIMD-ONLY01-NEXT: [[TMP21:%.*]] = load ptr, ptr [[_TMP9]], align 8 // SIMD-ONLY01-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP21]], align 8 -// SIMD-ONLY01-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i32 1 +// SIMD-ONLY01-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i32 1 // SIMD-ONLY01-NEXT: store ptr [[INCDEC_PTR11]], ptr [[TMP21]], align 8 // SIMD-ONLY01-NEXT: ret void // @@ -3822,34 +3822,34 @@ void bar() { // SIMD-ONLY02-NEXT: store ptr [[LR]], ptr [[LR_ADDR]], align 4 // SIMD-ONLY02-NEXT: store ptr [[TR]], ptr [[TR_ADDR]], align 4 // SIMD-ONLY02-NEXT: [[TMP0:%.*]] = load ptr, ptr @g, align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR]], ptr @g, align 4 // SIMD-ONLY02-NEXT: [[TMP1:%.*]] = load ptr, ptr [[L]], align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR1]], ptr [[L]], align 4 // SIMD-ONLY02-NEXT: [[TMP2:%.*]] = load ptr, ptr [[T]], align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR2]], ptr [[T]], align 4 // SIMD-ONLY02-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LR_ADDR]], align 4 // SIMD-ONLY02-NEXT: store ptr [[TMP3]], ptr [[TMP]], align 4 // SIMD-ONLY02-NEXT: [[TMP4:%.*]] = load ptr, ptr [[LR_ADDR]], align 4 // SIMD-ONLY02-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP]], align 4 // SIMD-ONLY02-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR3]], ptr [[TMP5]], align 4 // SIMD-ONLY02-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY02-NEXT: store ptr [[TMP7]], ptr [[_TMP4]], align 4 // SIMD-ONLY02-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY02-NEXT: [[TMP9:%.*]] = load ptr, ptr [[_TMP4]], align 4 // SIMD-ONLY02-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP10]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR5]], ptr [[TMP9]], align 4 // SIMD-ONLY02-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY02-NEXT: store ptr [[TMP11]], ptr [[_TMP6]], align 4 // SIMD-ONLY02-NEXT: [[TMP12:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY02-NEXT: [[TMP13:%.*]] = load ptr, ptr [[_TMP6]], align 4 // SIMD-ONLY02-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP13]], align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds i32, ptr [[TMP14]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP14]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR7]], ptr [[TMP13]], align 4 // SIMD-ONLY02-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY02-NEXT: store ptr [[TMP15]], ptr [[_TMP8]], align 4 @@ -3859,11 +3859,11 @@ void bar() { // SIMD-ONLY02-NEXT: [[TMP18:%.*]] = load ptr, ptr [[LR_ADDR]], align 4 // SIMD-ONLY02-NEXT: [[TMP19:%.*]] = load ptr, ptr [[_TMP8]], align 4 // SIMD-ONLY02-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP19]], align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds i32, ptr [[TMP20]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP20]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR10]], ptr [[TMP19]], align 4 // SIMD-ONLY02-NEXT: [[TMP21:%.*]] = load ptr, ptr [[_TMP9]], align 4 // SIMD-ONLY02-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP21]], align 4 -// SIMD-ONLY02-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i32 1 +// SIMD-ONLY02-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i32 1 // SIMD-ONLY02-NEXT: store ptr [[INCDEC_PTR11]], ptr [[TMP21]], align 4 // SIMD-ONLY02-NEXT: ret void // @@ -3896,34 +3896,34 @@ void bar() { // SIMD-ONLY03-NEXT: store ptr [[LR]], ptr [[LR_ADDR]], align 4 // SIMD-ONLY03-NEXT: store ptr [[TR]], ptr [[TR_ADDR]], align 4 // SIMD-ONLY03-NEXT: [[TMP0:%.*]] = load ptr, ptr @g, align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR]], ptr @g, align 4 // SIMD-ONLY03-NEXT: [[TMP1:%.*]] = load ptr, ptr [[L]], align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw float, ptr [[TMP1]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR1]], ptr [[L]], align 4 // SIMD-ONLY03-NEXT: [[TMP2:%.*]] = load ptr, ptr [[T]], align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR2]], ptr [[T]], align 4 // SIMD-ONLY03-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LR_ADDR]], align 4 // SIMD-ONLY03-NEXT: store ptr [[TMP3]], ptr [[TMP]], align 4 // SIMD-ONLY03-NEXT: [[TMP4:%.*]] = load ptr, ptr [[LR_ADDR]], align 4 // SIMD-ONLY03-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP]], align 4 // SIMD-ONLY03-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds float, ptr [[TMP6]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP6]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR3]], ptr [[TMP5]], align 4 // SIMD-ONLY03-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY03-NEXT: store ptr [[TMP7]], ptr [[_TMP4]], align 4 // SIMD-ONLY03-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY03-NEXT: [[TMP9:%.*]] = load ptr, ptr [[_TMP4]], align 4 // SIMD-ONLY03-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR5:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP10]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR5]], ptr [[TMP9]], align 4 // SIMD-ONLY03-NEXT: [[TMP11:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY03-NEXT: store ptr [[TMP11]], ptr [[_TMP6]], align 4 // SIMD-ONLY03-NEXT: [[TMP12:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY03-NEXT: [[TMP13:%.*]] = load ptr, ptr [[_TMP6]], align 4 // SIMD-ONLY03-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP13]], align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds i32, ptr [[TMP14]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR7:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP14]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR7]], ptr [[TMP13]], align 4 // SIMD-ONLY03-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TR_ADDR]], align 4 // SIMD-ONLY03-NEXT: store ptr [[TMP15]], ptr [[_TMP8]], align 4 @@ -3933,11 +3933,11 @@ void bar() { // SIMD-ONLY03-NEXT: [[TMP18:%.*]] = load ptr, ptr [[LR_ADDR]], align 4 // SIMD-ONLY03-NEXT: [[TMP19:%.*]] = load ptr, ptr [[_TMP8]], align 4 // SIMD-ONLY03-NEXT: [[TMP20:%.*]] = load ptr, ptr [[TMP19]], align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds i32, ptr [[TMP20]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR10:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP20]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR10]], ptr [[TMP19]], align 4 // SIMD-ONLY03-NEXT: [[TMP21:%.*]] = load ptr, ptr [[_TMP9]], align 4 // SIMD-ONLY03-NEXT: [[TMP22:%.*]] = load ptr, ptr [[TMP21]], align 4 -// SIMD-ONLY03-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds float, ptr [[TMP22]], i32 1 +// SIMD-ONLY03-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr inbounds nuw float, ptr [[TMP22]], i32 1 // SIMD-ONLY03-NEXT: store ptr [[INCDEC_PTR11]], ptr [[TMP21]], align 4 // SIMD-ONLY03-NEXT: ret void // @@ -3951,7 +3951,7 @@ void bar() { // CK20-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // CK20-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // CK20-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 8 -// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK20-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 8 // CK20-NEXT: ret void // @@ -4185,7 +4185,7 @@ void bar() { // CK20-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CK20-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK20-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 8 -// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK20-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 8 // CK20-NEXT: ret void // @@ -4199,7 +4199,7 @@ void bar() { // CK20-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 1 // CK20-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 8 // CK20-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // CK20-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP1]], align 8 // CK20-NEXT: ret void // @@ -4212,12 +4212,12 @@ void bar() { // CK20-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CK20-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK20-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 8 -// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK20-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK20-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 8 // CK20-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[TMP0]], i32 0, i32 1 // CK20-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B]], align 8 // CK20-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 8 -// CK20-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// CK20-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // CK20-NEXT: store ptr [[INCDEC_PTR1]], ptr [[TMP2]], align 8 // CK20-NEXT: ret void // @@ -4231,7 +4231,7 @@ void bar() { // CK21-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // CK21-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // CK21-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 8 -// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK21-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 8 // CK21-NEXT: ret void // @@ -4465,7 +4465,7 @@ void bar() { // CK21-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CK21-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK21-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 8 -// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK21-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 8 // CK21-NEXT: ret void // @@ -4479,7 +4479,7 @@ void bar() { // CK21-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 1 // CK21-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 8 // CK21-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // CK21-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP1]], align 8 // CK21-NEXT: ret void // @@ -4492,12 +4492,12 @@ void bar() { // CK21-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CK21-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK21-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 8 -// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK21-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK21-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 8 // CK21-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[TMP0]], i32 0, i32 1 // CK21-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B]], align 8 // CK21-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 8 -// CK21-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// CK21-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // CK21-NEXT: store ptr [[INCDEC_PTR1]], ptr [[TMP2]], align 8 // CK21-NEXT: ret void // @@ -4511,7 +4511,7 @@ void bar() { // CK22-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // CK22-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // CK22-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 4 -// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK22-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 4 // CK22-NEXT: ret void // @@ -4745,7 +4745,7 @@ void bar() { // CK22-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 // CK22-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK22-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 4 -// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK22-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 4 // CK22-NEXT: ret void // @@ -4759,7 +4759,7 @@ void bar() { // CK22-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 1 // CK22-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 4 // CK22-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 4 -// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // CK22-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP1]], align 4 // CK22-NEXT: ret void // @@ -4772,12 +4772,12 @@ void bar() { // CK22-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 // CK22-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK22-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 4 -// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK22-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK22-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 4 // CK22-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[TMP0]], i32 0, i32 1 // CK22-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B]], align 4 // CK22-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 4 -// CK22-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// CK22-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // CK22-NEXT: store ptr [[INCDEC_PTR1]], ptr [[TMP2]], align 4 // CK22-NEXT: ret void // @@ -4791,7 +4791,7 @@ void bar() { // CK23-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // CK23-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // CK23-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 4 -// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // CK23-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 4 // CK23-NEXT: ret void // @@ -5025,7 +5025,7 @@ void bar() { // CK23-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 // CK23-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK23-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 4 -// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK23-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 4 // CK23-NEXT: ret void // @@ -5039,7 +5039,7 @@ void bar() { // CK23-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 1 // CK23-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 4 // CK23-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 4 -// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // CK23-NEXT: store ptr [[INCDEC_PTR]], ptr [[TMP1]], align 4 // CK23-NEXT: ret void // @@ -5052,12 +5052,12 @@ void bar() { // CK23-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 // CK23-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[TMP0]], i32 0, i32 0 // CK23-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 4 -// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 1 +// CK23-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP1]], i32 1 // CK23-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 4 // CK23-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[TMP0]], i32 0, i32 1 // CK23-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B]], align 4 // CK23-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 4 -// CK23-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// CK23-NEXT: [[INCDEC_PTR1:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // CK23-NEXT: store ptr [[INCDEC_PTR1]], ptr [[TMP2]], align 4 // CK23-NEXT: ret void // @@ -5071,7 +5071,7 @@ void bar() { // SIMD-ONLY10-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // SIMD-ONLY10-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // SIMD-ONLY10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 8 -// SIMD-ONLY10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY10-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 8 // SIMD-ONLY10-NEXT: ret void // @@ -5101,21 +5101,21 @@ void bar() { // SIMD-ONLY10-NEXT: store ptr null, ptr [[LA]], align 8 // SIMD-ONLY10-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A]], align 8 -// SIMD-ONLY10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY10-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY10-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 8 // SIMD-ONLY10-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY10-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 8 // SIMD-ONLY10-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// SIMD-ONLY10-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// SIMD-ONLY10-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // SIMD-ONLY10-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP1]], align 8 // SIMD-ONLY10-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY10-NEXT: [[TMP3:%.*]] = load ptr, ptr [[A3]], align 8 -// SIMD-ONLY10-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// SIMD-ONLY10-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // SIMD-ONLY10-NEXT: store ptr [[INCDEC_PTR4]], ptr [[A3]], align 8 // SIMD-ONLY10-NEXT: [[B5:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY10-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B5]], align 8 // SIMD-ONLY10-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 -// SIMD-ONLY10-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds double, ptr [[TMP5]], i32 1 +// SIMD-ONLY10-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds nuw double, ptr [[TMP5]], i32 1 // SIMD-ONLY10-NEXT: store ptr [[INCDEC_PTR6]], ptr [[TMP4]], align 8 // SIMD-ONLY10-NEXT: ret void // @@ -5145,7 +5145,7 @@ void bar() { // SIMD-ONLY11-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // SIMD-ONLY11-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 8 dereferenceable(16) [[A]], ptr noundef nonnull align 8 dereferenceable(8) [[ARG_ADDR]]) // SIMD-ONLY11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 8 -// SIMD-ONLY11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY11-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 8 // SIMD-ONLY11-NEXT: ret void // @@ -5175,21 +5175,21 @@ void bar() { // SIMD-ONLY11-NEXT: store ptr null, ptr [[LA]], align 8 // SIMD-ONLY11-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A]], align 8 -// SIMD-ONLY11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY11-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY11-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 8 // SIMD-ONLY11-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY11-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 8 // SIMD-ONLY11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8 -// SIMD-ONLY11-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// SIMD-ONLY11-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // SIMD-ONLY11-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP1]], align 8 // SIMD-ONLY11-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[A3]], align 8 -// SIMD-ONLY11-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// SIMD-ONLY11-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // SIMD-ONLY11-NEXT: store ptr [[INCDEC_PTR4]], ptr [[A3]], align 8 // SIMD-ONLY11-NEXT: [[B5:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY11-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B5]], align 8 // SIMD-ONLY11-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 -// SIMD-ONLY11-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds double, ptr [[TMP5]], i32 1 +// SIMD-ONLY11-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds nuw double, ptr [[TMP5]], i32 1 // SIMD-ONLY11-NEXT: store ptr [[INCDEC_PTR6]], ptr [[TMP4]], align 8 // SIMD-ONLY11-NEXT: ret void // @@ -5219,7 +5219,7 @@ void bar() { // SIMD-ONLY12-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // SIMD-ONLY12-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // SIMD-ONLY12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 4 -// SIMD-ONLY12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY12-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 4 // SIMD-ONLY12-NEXT: ret void // @@ -5249,21 +5249,21 @@ void bar() { // SIMD-ONLY12-NEXT: store ptr null, ptr [[LA]], align 4 // SIMD-ONLY12-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A]], align 4 -// SIMD-ONLY12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY12-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY12-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 4 // SIMD-ONLY12-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY12-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 4 // SIMD-ONLY12-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 4 -// SIMD-ONLY12-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// SIMD-ONLY12-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // SIMD-ONLY12-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP1]], align 4 // SIMD-ONLY12-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY12-NEXT: [[TMP3:%.*]] = load ptr, ptr [[A3]], align 4 -// SIMD-ONLY12-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// SIMD-ONLY12-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // SIMD-ONLY12-NEXT: store ptr [[INCDEC_PTR4]], ptr [[A3]], align 4 // SIMD-ONLY12-NEXT: [[B5:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY12-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B5]], align 4 // SIMD-ONLY12-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 4 -// SIMD-ONLY12-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds double, ptr [[TMP5]], i32 1 +// SIMD-ONLY12-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds nuw double, ptr [[TMP5]], i32 1 // SIMD-ONLY12-NEXT: store ptr [[INCDEC_PTR6]], ptr [[TMP4]], align 4 // SIMD-ONLY12-NEXT: ret void // @@ -5293,7 +5293,7 @@ void bar() { // SIMD-ONLY13-NEXT: call void @_ZN2STIdEC1ERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // SIMD-ONLY13-NEXT: call void @_ZN2STIdE3fooERPd(ptr noundef nonnull align 4 dereferenceable(8) [[A]], ptr noundef nonnull align 4 dereferenceable(4) [[ARG_ADDR]]) // SIMD-ONLY13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARG_ADDR]], align 4 -// SIMD-ONLY13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY13-NEXT: store ptr [[INCDEC_PTR]], ptr [[ARG_ADDR]], align 4 // SIMD-ONLY13-NEXT: ret void // @@ -5323,21 +5323,21 @@ void bar() { // SIMD-ONLY13-NEXT: store ptr null, ptr [[LA]], align 4 // SIMD-ONLY13-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_ST:%.*]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A]], align 4 -// SIMD-ONLY13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i32 1 +// SIMD-ONLY13-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP0]], i32 1 // SIMD-ONLY13-NEXT: store ptr [[INCDEC_PTR]], ptr [[A]], align 4 // SIMD-ONLY13-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY13-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B]], align 4 // SIMD-ONLY13-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 4 -// SIMD-ONLY13-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 1 +// SIMD-ONLY13-NEXT: [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw double, ptr [[TMP2]], i32 1 // SIMD-ONLY13-NEXT: store ptr [[INCDEC_PTR2]], ptr [[TMP1]], align 4 // SIMD-ONLY13-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 0 // SIMD-ONLY13-NEXT: [[TMP3:%.*]] = load ptr, ptr [[A3]], align 4 -// SIMD-ONLY13-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 1 +// SIMD-ONLY13-NEXT: [[INCDEC_PTR4:%.*]] = getelementptr inbounds nuw double, ptr [[TMP3]], i32 1 // SIMD-ONLY13-NEXT: store ptr [[INCDEC_PTR4]], ptr [[A3]], align 4 // SIMD-ONLY13-NEXT: [[B5:%.*]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[THIS1]], i32 0, i32 1 // SIMD-ONLY13-NEXT: [[TMP4:%.*]] = load ptr, ptr [[B5]], align 4 // SIMD-ONLY13-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 4 -// SIMD-ONLY13-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds double, ptr [[TMP5]], i32 1 +// SIMD-ONLY13-NEXT: [[INCDEC_PTR6:%.*]] = getelementptr inbounds nuw double, ptr [[TMP5]], i32 1 // SIMD-ONLY13-NEXT: store ptr [[INCDEC_PTR6]], ptr [[TMP4]], align 4 // SIMD-ONLY13-NEXT: ret void // diff --git a/clang/test/OpenMP/target_map_both_pointer_pointee_codegen.cpp b/clang/test/OpenMP/target_map_both_pointer_pointee_codegen.cpp index fcaceac7d3467..87fa7fe462daa 100644 --- a/clang/test/OpenMP/target_map_both_pointer_pointee_codegen.cpp +++ b/clang/test/OpenMP/target_map_both_pointer_pointee_codegen.cpp @@ -45,7 +45,7 @@ void foo() { // CHECK-NEXT: store ptr [[CALL]], ptr [[PTR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[PTR]], align 8 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 0 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i64 0 // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: store ptr [[PTR]], ptr [[TMP2]], align 8 // CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 diff --git a/clang/test/OpenMP/target_map_codegen_01.cpp b/clang/test/OpenMP/target_map_codegen_01.cpp index d112500eb5fdd..9f3553d2377cb 100644 --- a/clang/test/OpenMP/target_map_codegen_01.cpp +++ b/clang/test/OpenMP/target_map_codegen_01.cpp @@ -108,6 +108,6 @@ void implicit_maps_reference (int a, int *b){ // CK2: store ptr [[ADDR]], ptr [[REF]], // CK2: [[T:%.+]] = load ptr, ptr [[REF]], // CK2: [[TT:%.+]] = load ptr, ptr [[T]], -// CK2: getelementptr inbounds i32, ptr [[TT]], i32 1 +// CK2: getelementptr inbounds nuw i32, ptr [[TT]], i32 1 #endif // CK2 #endif diff --git a/clang/test/OpenMP/target_map_codegen_21.cpp b/clang/test/OpenMP/target_map_codegen_21.cpp index a1419b7d4beb8..f5c517692d8c8 100644 --- a/clang/test/OpenMP/target_map_codegen_21.cpp +++ b/clang/test/OpenMP/target_map_codegen_21.cpp @@ -185,7 +185,7 @@ int explicit_maps_globals(void){ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 // CK22-DAG: store ptr @c, ptr [[BP0]] -// CK22-DAG: store ptr getelementptr inbounds ([100 x i32], ptr @c, i{{.+}} 0, i{{.+}} 1), ptr [[P0]] +// CK22-DAG: store ptr getelementptr inbounds nuw ([100 x i32], ptr @c, i{{.+}} 0, i{{.+}} 1), ptr [[P0]] // CK22: call void [[CALL03:@.+]](ptr {{[^,]+}}) #pragma omp target map(c [1:4]) @@ -277,7 +277,7 @@ int explicit_maps_globals(void){ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 // CK22-DAG: store ptr @sc, ptr [[BP0]] -// CK22-DAG: store ptr getelementptr inbounds ([100 x [[ST]]], ptr @sc, i{{.+}} 0, i{{.+}} 1), ptr [[P0]] +// CK22-DAG: store ptr getelementptr inbounds nuw ([100 x [[ST]]], ptr @sc, i{{.+}} 0, i{{.+}} 1), ptr [[P0]] // CK22: call void [[CALL08:@.+]](ptr {{[^,]+}}) #pragma omp target map(sc [1:4]) @@ -369,7 +369,7 @@ int explicit_maps_globals(void){ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 // CK22-DAG: store ptr @stc, ptr [[BP0]] -// CK22-DAG: store ptr getelementptr inbounds ([100 x [[STT]]], ptr @stc, i{{.+}} 0, i{{.+}} 1), ptr [[P0]] +// CK22-DAG: store ptr getelementptr inbounds nuw ([100 x [[STT]]], ptr @stc, i{{.+}} 0, i{{.+}} 1), ptr [[P0]] // CK22: call void [[CALL13:@.+]](ptr {{[^,]+}}) #pragma omp target map(stc [1:4]) diff --git a/clang/test/OpenMP/target_map_codegen_27.cpp b/clang/test/OpenMP/target_map_codegen_27.cpp index fe7ae12e00d13..bfe75bca481be 100644 --- a/clang/test/OpenMP/target_map_codegen_27.cpp +++ b/clang/test/OpenMP/target_map_codegen_27.cpp @@ -82,7 +82,7 @@ void explicit_maps_pointer_references (int *p){ // CK28-DAG: store ptr [[VAR1:%.+]], ptr [[P0]] // CK28-DAG: [[VAR0]] = load ptr, ptr [[VAR00:%.+]], // CK28-DAG: [[VAR00]] = load ptr, ptr [[VAR000:%.+]], -// CK28-DAG: [[VAR1]] = getelementptr inbounds i32, ptr [[VAR11:%.+]], i{{64|32}} 2 +// CK28-DAG: [[VAR1]] = getelementptr inbounds nuw i32, ptr [[VAR11:%.+]], i{{64|32}} 2 // CK28-DAG: [[VAR11]] = load ptr, ptr [[VAR111:%.+]], // CK28-DAG: [[VAR111]] = load ptr, ptr [[VAR1111:%.+]], diff --git a/clang/test/OpenMP/target_map_codegen_28.cpp b/clang/test/OpenMP/target_map_codegen_28.cpp index e92f7e4773ecf..67ea72d791d03 100644 --- a/clang/test/OpenMP/target_map_codegen_28.cpp +++ b/clang/test/OpenMP/target_map_codegen_28.cpp @@ -89,7 +89,7 @@ struct SSB{ // CK29-DAG: store ptr [[VAR1:%.+]], ptr [[BP2]] // CK29-DAG: store ptr [[VAR2:%.+]], ptr [[P2]] // CK29-DAG: [[VAR1]] = getelementptr inbounds nuw [[SSA]], ptr %{{.+}}, i32 0, i32 1 -// CK29-DAG: [[VAR2]] = getelementptr inbounds double, ptr [[VAR22:%.+]], i{{.+}} 0 +// CK29-DAG: [[VAR2]] = getelementptr inbounds nuw double, ptr [[VAR22:%.+]], i{{.+}} 0 // CK29-DAG: [[VAR22]] = load ptr, ptr %{{.+}}, // CK29: call void [[CALL00:@.+]](ptr {{[^,]+}}) @@ -129,7 +129,7 @@ struct SSB{ // CK29-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 // CK29-DAG: store ptr [[VAR1]], ptr [[BP2]] // CK29-DAG: store ptr [[VAR2:%.+]], ptr [[P2]] -// CK29-DAG: [[VAR2]] = getelementptr inbounds double, ptr [[VAR22:%.+]], i{{.+}} 0 +// CK29-DAG: [[VAR2]] = getelementptr inbounds nuw double, ptr [[VAR22:%.+]], i{{.+}} 0 // CK29-DAG: [[VAR22]] = load ptr, ptr %{{.+}}, // CK29: call void [[CALL00:@.+]](ptr {{[^,]+}}) @@ -164,7 +164,7 @@ struct SSB{ // CK29-DAG: store ptr [[VAR1:%.+]], ptr [[BP2]] // CK29-DAG: store ptr [[VAR2:%.+]], ptr [[P2]] // CK29-DAG: [[VAR1]] = getelementptr inbounds nuw [[SSA]], ptr %{{.+}}, i32 0, i32 1 -// CK29-DAG: [[VAR2]] = getelementptr inbounds double, ptr [[VAR22:%.+]], i{{.+}} 0 +// CK29-DAG: [[VAR2]] = getelementptr inbounds nuw double, ptr [[VAR22:%.+]], i{{.+}} 0 // CK29-DAG: [[VAR22]] = load ptr, ptr %{{.+}}, // CK29: call void [[CALL00:@.+]](ptr {{[^,]+}}) diff --git a/clang/test/OpenMP/target_map_codegen_29.cpp b/clang/test/OpenMP/target_map_codegen_29.cpp index 936a01573c2d2..3ca7b228d26c2 100644 --- a/clang/test/OpenMP/target_map_codegen_29.cpp +++ b/clang/test/OpenMP/target_map_codegen_29.cpp @@ -89,7 +89,7 @@ typedef struct StructWithPtrTag : public Base { // CK30-DAG: [[PTR:%.+]] = getelementptr inbounds [4 x ptr], ptr [[PTRS]], i32 0, i32 2 // CK30-DAG: store ptr [[S_PTR1_BEGIN:%.+]], ptr [[PTR]], // CK30-DAG: [[S_PTR1]] = getelementptr inbounds nuw [[STRUCT]], ptr [[S]], i32 0, i32 4 -// CK30-DAG: [[S_PTR1_BEGIN]] = getelementptr inbounds i32, ptr [[S_PTR1_BEGIN_REF:%.+]], i{{64|32}} 0 +// CK30-DAG: [[S_PTR1_BEGIN]] = getelementptr inbounds nuw i32, ptr [[S_PTR1_BEGIN_REF:%.+]], i{{64|32}} 0 // CK30-DAG: [[S_PTR1_BEGIN_REF]] = load ptr, ptr [[S_PTR1:%.+]], // CK30-DAG: [[S_PTR1]] = getelementptr inbounds nuw [[STRUCT]], ptr [[S]], i32 0, i32 4 @@ -98,7 +98,7 @@ typedef struct StructWithPtrTag : public Base { // CK30-DAG: [[PTR:%.+]] = getelementptr inbounds [4 x ptr], ptr [[PTRS]], i32 0, i32 3 // CK30-DAG: store ptr [[S_PTRBASE1_BEGIN:%.+]], ptr [[PTR]], // CK30-DAG: [[S_PTRBASE1]] = getelementptr inbounds nuw [[BASE]], ptr [[S_BASE:%.+]], i32 0, i32 2 -// CK30-DAG: [[S_PTRBASE1_BEGIN]] = getelementptr inbounds i32, ptr [[S_PTRBASE1_BEGIN_REF:%.+]], i{{64|32}} 0 +// CK30-DAG: [[S_PTRBASE1_BEGIN]] = getelementptr inbounds nuw i32, ptr [[S_PTRBASE1_BEGIN_REF:%.+]], i{{64|32}} 0 // CK30-DAG: [[S_PTRBASE1_BEGIN_REF]] = load ptr, ptr [[S_PTRBASE1:%.+]], // CK30-DAG: [[S_PTRBASE1]] = getelementptr inbounds nuw [[BASE]], ptr [[S_BASE:%.+]], i32 0, i32 2 void map_with_deep_copy() { diff --git a/clang/test/OpenMP/target_map_deref_array_codegen.cpp b/clang/test/OpenMP/target_map_deref_array_codegen.cpp index 9d395b0ab8cd8..e61fc7296332b 100644 --- a/clang/test/OpenMP/target_map_deref_array_codegen.cpp +++ b/clang/test/OpenMP/target_map_deref_array_codegen.cpp @@ -75,7 +75,7 @@ void foo(int **t1d) // CHECK-NEXT: [[TMP8:%.*]] = load ptr, ptr [[T1D_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[T1D_ADDR]], align 8 // CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 -// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i64 0 +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP10]], i64 0 // CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: store ptr [[TMP7]], ptr [[TMP11]], align 8 // CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 diff --git a/clang/test/OpenMP/target_map_member_expr_array_section_codegen.cpp b/clang/test/OpenMP/target_map_member_expr_array_section_codegen.cpp index 7a0da002fb944..692e3a4214c9d 100644 --- a/clang/test/OpenMP/target_map_member_expr_array_section_codegen.cpp +++ b/clang/test/OpenMP/target_map_member_expr_array_section_codegen.cpp @@ -28,12 +28,12 @@ struct maptest { // CHECK: getelementptr inbounds // CHECK: [[S_ADDR:%.+]] = getelementptr inbounds nuw %struct.maptest, ptr [[THIS:%.+]], i32 0, i32 0 // CHECK: [[S_DATA_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[S_ADDR]], i32 0, i32 0 - // CHECK: [[S_DATA_0_ADDR:%.+]] = getelementptr inbounds [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 0 + // CHECK: [[S_DATA_0_ADDR:%.+]] = getelementptr inbounds nuw [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 0 // SZ = &this->s.data[6]-&this->s.data[0] // CHECK: [[S_ADDR:%.+]] = getelementptr inbounds nuw %struct.maptest, ptr [[THIS]], i32 0, i32 0 // CHECK: [[S_DATA_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[S_ADDR]], i32 0, i32 0 - // CHECK: [[S_DATA_5_ADDR:%.+]] = getelementptr inbounds [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 5 + // CHECK: [[S_DATA_5_ADDR:%.+]] = getelementptr inbounds nuw [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 5 // CHECK: [[S_DATA_6_ADDR:%.+]] = getelementptr float, ptr [[S_DATA_5_ADDR]], i32 1 // CHECK: [[END_BC:%.+]] = ptrtoint ptr [[S_DATA_6_ADDR]] to i64 // CHECK: [[BEG_BC:%.+]] = ptrtoint ptr [[S_DATA_0_ADDR]] to i64 @@ -64,12 +64,12 @@ struct maptest { // CHECK: [[SIZE:%.+]] = alloca [2 x i64], // CHECK: [[S_ADDR:%.+]] = getelementptr inbounds nuw %struct.maptest, ptr [[THIS:%.+]], i32 0, i32 0 // CHECK: [[S_DATA_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[S_ADDR]], i32 0, i32 0 - // CHECK: [[S_DATA_0_ADDR:%.+]] = getelementptr inbounds [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 0 + // CHECK: [[S_DATA_0_ADDR:%.+]] = getelementptr inbounds nuw [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 0 // SZ = &this->s.data[6]-&this->s.data[0] // CHECK: [[S_ADDR:%.+]] = getelementptr inbounds nuw %struct.maptest, ptr [[THIS]], i32 0, i32 0 // CHECK: [[S_DATA_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[S_ADDR]], i32 0, i32 0 - // CHECK: [[S_DATA_5_ADDR:%.+]] = getelementptr inbounds [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 5 + // CHECK: [[S_DATA_5_ADDR:%.+]] = getelementptr inbounds nuw [6 x float], ptr [[S_DATA_ADDR]], i64 0, i64 5 // CHECK: [[S_DATA_6_ADDR:%.+]] = getelementptr float, ptr [[S_DATA_5_ADDR]], i32 1 // CHECK: [[END_BC:%.+]] = ptrtoint ptr [[S_DATA_6_ADDR]] to i64 // CHECK: [[BEG_BC:%.+]] = ptrtoint ptr [[S_DATA_0_ADDR]] to i64 diff --git a/clang/test/OpenMP/target_map_member_expr_codegen.cpp b/clang/test/OpenMP/target_map_member_expr_codegen.cpp index 9b64647928a24..fb36ba7b78d5b 100644 --- a/clang/test/OpenMP/target_map_member_expr_codegen.cpp +++ b/clang/test/OpenMP/target_map_member_expr_codegen.cpp @@ -223,7 +223,7 @@ void foo() { // CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[A4:%.*]] = getelementptr inbounds nuw [[STRUCT_DESCRIPTOR]], ptr [[TMP10]], i32 0, i32 0 // CHECK-NEXT: [[TMP11:%.*]] = load ptr, ptr [[A4]], align 8 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP11]], i64 0 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 0 // CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[ASIZE]], align 4 // CHECK-NEXT: [[CONV:%.*]] = zext i32 [[TMP12]] to i64 // CHECK-NEXT: [[TMP13:%.*]] = mul nuw i64 [[CONV]], 4 @@ -233,7 +233,7 @@ void foo() { // CHECK-NEXT: [[TMP16:%.*]] = load ptr, ptr [[D_ADDR]], align 8 // CHECK-NEXT: [[C5:%.*]] = getelementptr inbounds nuw [[STRUCT_DESCRIPTOR]], ptr [[TMP16]], i32 0, i32 1 // CHECK-NEXT: [[TMP17:%.*]] = load ptr, ptr [[C5]], align 8 -// CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[TMP17]], i64 0 +// CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 0 // CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[CSIZE]], align 4 // CHECK-NEXT: [[CONV7:%.*]] = zext i32 [[TMP18]] to i64 // CHECK-NEXT: [[TMP19:%.*]] = mul nuw i64 [[CONV7]], 4 @@ -343,7 +343,7 @@ void foo() { // CHECK-NEXT: [[TMP79:%.*]] = load ptr, ptr [[_TMP12]], align 8 // CHECK-NEXT: [[C15:%.*]] = getelementptr inbounds nuw [[STRUCT_DESCRIPTOR]], ptr [[TMP79]], i32 0, i32 1 // CHECK-NEXT: [[TMP80:%.*]] = load ptr, ptr [[C15]], align 8 -// CHECK-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds float, ptr [[TMP80]], i64 0 +// CHECK-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw float, ptr [[TMP80]], i64 0 // CHECK-NEXT: [[TMP81:%.*]] = load i32, ptr [[CSIZE]], align 4 // CHECK-NEXT: [[CONV17:%.*]] = zext i32 [[TMP81]] to i64 // CHECK-NEXT: [[TMP82:%.*]] = mul nuw i64 [[CONV17]], 4 diff --git a/clang/test/OpenMP/target_map_nest_defalut_mapper_codegen.cpp b/clang/test/OpenMP/target_map_nest_defalut_mapper_codegen.cpp index ffb145d8e50fc..775f0b296b1b6 100644 --- a/clang/test/OpenMP/target_map_nest_defalut_mapper_codegen.cpp +++ b/clang/test/OpenMP/target_map_nest_defalut_mapper_codegen.cpp @@ -45,7 +45,7 @@ void foo() { // CHECK-NEXT: [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[ARRAYIDX1]], i32 0, i32 1 // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_C:%.*]], ptr [[F]], i32 0, i32 0 // CHECK-NEXT: store i32 222, ptr [[A]], align 4 -// CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x %struct.D], ptr [[SA]], i64 0, i64 0 +// CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [10 x %struct.D], ptr [[SA]], i64 0, i64 0 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: store ptr [[SA]], ptr [[TMP0]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 diff --git a/clang/test/OpenMP/target_parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/target_parallel_for_reduction_task_codegen.cpp index 3d0710acf0ee7..5cce677e88572 100644 --- a/clang/test/OpenMP/target_parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_reduction_task_codegen.cpp @@ -96,16 +96,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -135,7 +135,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP6]], ptr [[_TMP5]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP6]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -150,19 +150,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX8]], align 8 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN10:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX11]], align 8 -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN10]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN10]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[TMP36]], align 8 @@ -483,9 +483,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/target_parallel_reduction_task_codegen.cpp b/clang/test/OpenMP/target_parallel_reduction_task_codegen.cpp index 28d63dbf8c4a9..c0bb4a6d6cc82 100644 --- a/clang/test/OpenMP/target_parallel_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_reduction_task_codegen.cpp @@ -85,16 +85,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -124,7 +124,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP5]], ptr [[TMP]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP5]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -139,19 +139,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX7]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN9:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[TMP36]], align 8 @@ -429,9 +429,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/target_task_affinity_codegen.cpp b/clang/test/OpenMP/target_task_affinity_codegen.cpp index 85c5d63a6cd9c..53960cee4b730 100644 --- a/clang/test/OpenMP/target_task_affinity_codegen.cpp +++ b/clang/test/OpenMP/target_task_affinity_codegen.cpp @@ -76,7 +76,7 @@ int main() { // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 8 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP3]], align 8 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 @@ -102,7 +102,7 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP0]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[B]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = load ptr, ptr [[B]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP18]], i64 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[TMP17]], ptr [[TMP19]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 @@ -174,9 +174,9 @@ int main() { // CHECK1-NEXT: [[TMP2:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i64 48, i64 8, ptr @.omp_task_entry.) // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x %struct.kmp_task_affinity_info_t], ptr [[DOTAFFS_ARR_ADDR]], i64 0, i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP4]], i64 0 // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i64 1023 +// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP5]], i64 1023 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[ARRAYIDX1]], i32 1 // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP6]] to i64 @@ -299,7 +299,7 @@ int main() { // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A]], align 4 -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 0 +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP2]], i32 0 // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[TMP1]], ptr [[TMP3]], align 4 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 @@ -325,7 +325,7 @@ int main() { // CHECK3-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = load ptr, ptr [[B]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = load ptr, ptr [[B]], align 4 -// CHECK3-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 0 +// CHECK3-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP18]], i32 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[TMP17]], ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 @@ -397,9 +397,9 @@ int main() { // CHECK3-NEXT: [[TMP2:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i32 24, i32 4, ptr @.omp_task_entry.) // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x %struct.kmp_task_affinity_info_t], ptr [[DOTAFFS_ARR_ADDR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 4 -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0 +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP4]], i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = load ptr, ptr [[A_ADDR]], align 4 -// CHECK3-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i32 1023 +// CHECK3-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP5]], i32 1023 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[ARRAYIDX1]], i32 1 // CHECK3-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i32 // CHECK3-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP6]] to i32 @@ -587,9 +587,9 @@ int main() { // CHECK9-NEXT: [[TMP2:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i64 48, i64 8, ptr @.omp_task_entry.) // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x %struct.kmp_task_affinity_info_t], ptr [[DOTAFFS_ARR_ADDR]], i64 0, i64 0 // CHECK9-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK9-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i64 0 +// CHECK9-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP4]], i64 0 // CHECK9-NEXT: [[TMP5:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK9-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i64 1023 +// CHECK9-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP5]], i64 1023 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[ARRAYIDX1]], i32 1 // CHECK9-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK9-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP6]] to i64 @@ -709,9 +709,9 @@ int main() { // CHECK11-NEXT: [[TMP2:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i32 24, i32 4, ptr @.omp_task_entry.) // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x %struct.kmp_task_affinity_info_t], ptr [[DOTAFFS_ARR_ADDR]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 4 -// CHECK11-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0 +// CHECK11-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP4]], i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = load ptr, ptr [[A_ADDR]], align 4 -// CHECK11-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i32 1023 +// CHECK11-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP5]], i32 1023 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[ARRAYIDX1]], i32 1 // CHECK11-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i32 // CHECK11-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP6]] to i32 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp index 6f671dbb27abb..2c36b410af064 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp @@ -91,16 +91,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -130,7 +130,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP5]], ptr [[TMP]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP5]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -145,19 +145,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX7]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN9:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[TMP36]], align 8 @@ -435,16 +435,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP3]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP4]], i64 0 // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP6]] // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP7]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP7]], i64 9 // CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP8]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]] @@ -474,7 +474,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP22]] // CHECK1-NEXT: store ptr [[_TMP6]], ptr [[_TMP5]], align 8 // CHECK1-NEXT: store ptr [[TMP23]], ptr [[_TMP6]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP24]], align 8 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -489,19 +489,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..4, ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP30]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 0 // CHECK1-NEXT: [[TMP32:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds ptr, ptr [[TMP32]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP32]], i64 0 // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[ARRAYIDX8]], align 8 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i8, ptr [[TMP33]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP33]], i64 0 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP35:%.*]] = sext i32 [[TMP34]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN10:%.*]] = add nsw i64 -1, [[TMP35]] // CHECK1-NEXT: [[TMP36:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds ptr, ptr [[TMP36]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP36]], i64 9 // CHECK1-NEXT: [[TMP37:%.*]] = load ptr, ptr [[ARRAYIDX11]], align 8 -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds i8, ptr [[TMP37]], i64 [[LB_ADD_LEN10]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP37]], i64 [[LB_ADD_LEN10]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[TMP38]], align 8 @@ -822,9 +822,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/OpenMP/target_update_codegen.cpp b/clang/test/OpenMP/target_update_codegen.cpp index 5e038989ab6dd..c8211f475c7fc 100644 --- a/clang/test/OpenMP/target_update_codegen.cpp +++ b/clang/test/OpenMP/target_update_codegen.cpp @@ -1118,9 +1118,9 @@ struct ST { void foo(int arg) { ST arr[3][4]; // CK20: [[DIMS:%.+]] = alloca [3 x [[STRUCT_DESCRIPTOR]]], - // CK20: [[ARRAY_IDX:%.+]] = getelementptr inbounds [3 x [4 x [[STRUCT_ST]]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 + // CK20: [[ARRAY_IDX:%.+]] = getelementptr inbounds nuw [3 x [4 x [[STRUCT_ST]]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 // CK20: [[ARRAY_DECAY:%.+]] = getelementptr inbounds [4 x [[STRUCT_ST]]], ptr [[ARRAY_IDX]], {{.+}} 0, {{.+}} 0 - // CK20: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds [[STRUCT_ST]], ptr [[ARRAY_DECAY]], {{.+}} + // CK20: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds nuw [[STRUCT_ST]], ptr [[ARRAY_DECAY]], {{.+}} // CK20: [[BP0:%.+]] = getelementptr inbounds [1 x ptr], ptr [[BP:%.+]], {{.+}} 0, {{.+}} 0 // CK20: store ptr [[ARR]], ptr [[BP0]], // CK20: [[P0:%.+]] = getelementptr inbounds [1 x ptr], ptr [[P:%.+]], {{.+}} 0, {{.+}} 0 @@ -1186,9 +1186,9 @@ struct ST { // CK21: _ZN2ST3fooEv void foo() { // CK21: [[DIMS:%.+]] = alloca [4 x [[STRUCT_DESCRIPTOR]]], - // CK21: [[ARRAY_IDX:%.+]] = getelementptr inbounds [10 x [10 x [10 x ptr]]], ptr [[DPTR:%.+]], {{.+}} 0, {{.+}} 0 + // CK21: [[ARRAY_IDX:%.+]] = getelementptr inbounds nuw [10 x [10 x [10 x ptr]]], ptr [[DPTR:%.+]], {{.+}} 0, {{.+}} 0 // CK21: [[ARRAY_DECAY:%.+]] = getelementptr inbounds [10 x [10 x ptr]], ptr [[ARRAY_IDX]], {{.+}} 0, {{.+}} 0 - // CK21: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds [10 x ptr], ptr [[ARRAY_DECAY]], {{.+}} 1 + // CK21: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds nuw [10 x ptr], ptr [[ARRAY_DECAY]], {{.+}} 1 // CK21: [[ARRAY_DECAY_2:%.+]] = getelementptr inbounds [10 x ptr], ptr [[ARRAY_IDX_1]], {{.+}} 0, {{.+}} 0 // CK21: [[ARRAY_IDX_3:%.+]] = getelementptr inbounds {{.+}}, ptr [[ARRAY_DECAY_2]], {{.+}} 0 // CK21: [[BP0:%.+]] = getelementptr inbounds [2 x ptr], ptr [[BP:%.+]], {{.+}} 0, {{.+}} 0 @@ -1262,9 +1262,9 @@ struct ST { // CK22: _ZN2ST3fooEPA10_Pi void foo(int *arr[5][10]) { // CK22: [[DIMS:%.+]] = alloca [4 x [[STRUCT_DESCRIPTOR]]], - // CK22: [[ARRAY_IDX:%.+]] = getelementptr inbounds [10 x ptr], ptr [[ARR:%.+]], {{.+}} 0 + // CK22: [[ARRAY_IDX:%.+]] = getelementptr inbounds nuw [10 x ptr], ptr [[ARR:%.+]], {{.+}} 0 // CK22: [[ARRAY_DECAY:%.+]] = getelementptr inbounds [10 x ptr], ptr [[ARRAY_IDX]], {{.+}} 0, {{.+}} 0 - // CK22: [[ARRAY_IDX_2:%.+]] = getelementptr inbounds ptr, ptr [[ARRAY_DECAY:%.+]], {{.+}} 1 + // CK22: [[ARRAY_IDX_2:%.+]] = getelementptr inbounds nuw ptr, ptr [[ARRAY_DECAY:%.+]], {{.+}} 1 // CK22: [[BP0:%.+]] = getelementptr inbounds [1 x ptr], ptr [[BP:%.+]], {{.+}} 0, {{.+}} 0 // CK22: [[P0:%.+]] = getelementptr inbounds [1 x ptr], ptr [[P:%.+]], i{{.+}} 0, i{{.+}} 0 // CK22: [[DIM_1:%.+]] = getelementptr inbounds [4 x [[STRUCT_DESCRIPTOR]]], ptr [[DIMS]], {{.+}} 0, {{.+}} 0 @@ -1338,11 +1338,11 @@ void foo(int arg) { float farr[5][5][5]; // CK23: [[ARG_ADDR:%.+]] = alloca i32, // CK23: [[DIMS:%.+]] = alloca [4 x [[STRUCT_DESCRIPTOR]]], - // CK23: [[ARRAY_IDX:%.+]] = getelementptr inbounds [5 x [5 x [5 x float]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 + // CK23: [[ARRAY_IDX:%.+]] = getelementptr inbounds nuw [5 x [5 x [5 x float]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 // CK23: [[ARRAY_DECAY:%.+]] = getelementptr inbounds [5 x [5 x float]], ptr [[ARRAY_IDX]], {{.+}} 0, {{.+}} 0 - // CK23: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds [5 x float], ptr [[ARRAY_DECAY]], {{.+}} + // CK23: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds nuw [5 x float], ptr [[ARRAY_DECAY]], {{.+}} // CK23: [[ARRAY_DECAY_2:%.+]] = getelementptr inbounds [5 x float], ptr [[ARRAY_IDX_1]], {{.+}} 0, {{.+}} 0 - // CK23: [[ARRAY_IDX_2:%.+]] = getelementptr inbounds float, ptr [[ARRAY_DECAY_2]], {{.+}} + // CK23: [[ARRAY_IDX_2:%.+]] = getelementptr inbounds nuw float, ptr [[ARRAY_DECAY_2]], {{.+}} // CK23: [[MUL:%.+]] = mul nuw i64 4, // CK23: [[BP0:%.+]] = getelementptr inbounds [1 x ptr], ptr [[BP:%.+]], {{.+}} 0, {{.+}} 0 // CK23: store ptr [[ARR]], ptr [[BP0]], @@ -1411,11 +1411,11 @@ void foo(int arg) { void foo(int arg) { double darr[3][4][5]; // CK24: [[DIMS:%.+]] = alloca [4 x [[STRUCT_DESCRIPTOR]]], - // CK24: [[ARRAY_IDX:%.+]] = getelementptr inbounds [3 x [4 x [5 x double]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 + // CK24: [[ARRAY_IDX:%.+]] = getelementptr inbounds nuw [3 x [4 x [5 x double]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 // CK24: [[ARRAY_DECAY:%.+]] = getelementptr inbounds [4 x [5 x double]], ptr [[ARRAY_IDX]], {{.+}} 0, {{.+}} 0 - // CK24: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds [5 x double], ptr [[ARRAY_DECAY]], {{.+}} + // CK24: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds nuw [5 x double], ptr [[ARRAY_DECAY]], {{.+}} // CK24: [[ARRAY_DECAY_2:%.+]] = getelementptr inbounds [5 x double], ptr [[ARRAY_IDX_1]], {{.+}} 0, {{.+}} 0 - // CK24: [[ARRAY_IDX_2:%.+]] = getelementptr inbounds double, ptr [[ARRAY_DECAY_2]], {{.+}} + // CK24: [[ARRAY_IDX_2:%.+]] = getelementptr inbounds nuw double, ptr [[ARRAY_DECAY_2]], {{.+}} // CK24: [[MUL:%.+]] = mul nuw i64 8, // CK24: [[SUB:%.+]] = sub nuw i64 4, [[ARG:%.+]] // CK24: [[LEN:%.+]] = udiv {{.+}} [[SUB]], 1 @@ -1488,15 +1488,15 @@ void foo(int arg) { // CK25: [[DIMS:%.+]] = alloca [4 x [[STRUCT_DESCRIPTOR]]], // CK25: [[DIMS_2:%.+]] = alloca [3 x [[STRUCT_DESCRIPTOR]]], - // CK25: [[ARRAY_IDX:%.+]] = getelementptr inbounds [3 x [4 x [5 x i32]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 + // CK25: [[ARRAY_IDX:%.+]] = getelementptr inbounds nuw [3 x [4 x [5 x i32]]], ptr [[ARR:%.+]], {{.+}} 0, {{.+}} 0 // CK25: [[ARRAY_DECAY:%.+]] = getelementptr inbounds [4 x [5 x i32]], ptr [[ARRAY_IDX]], {{.+}} 0, {{.+}} 0 - // CK25: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds [5 x i32], ptr [[ARRAY_DECAY]], {{.+}} + // CK25: [[ARRAY_IDX_1:%.+]] = getelementptr inbounds nuw [5 x i32], ptr [[ARRAY_DECAY]], {{.+}} // CK25: [[ARRAY_DECAY_2:%.+]] = getelementptr inbounds [5 x i32], ptr [[ARRAY_IDX_1]], {{.+}} 0, {{.+}} 0 - // CK25: [[ARRAY_IDX_3:%.+]] = getelementptr inbounds {{.+}}, ptr [[ARRAY_DECAY_2]], {{.+}} 1 + // CK25: [[ARRAY_IDX_3:%.+]] = getelementptr inbounds nuw {{.+}}, ptr [[ARRAY_DECAY_2]], {{.+}} 1 // CK25: [[LEN:%.+]] = sub nuw i64 4, [[ARG_ADDR:%.+]] - // CK25: [[ARRAY_IDX_4:%.+]] = getelementptr inbounds [4 x [3 x float]], ptr [[FARR:%.+]], {{.+}} 0, {{.+}} 0 + // CK25: [[ARRAY_IDX_4:%.+]] = getelementptr inbounds nuw [4 x [3 x float]], ptr [[FARR:%.+]], {{.+}} 0, {{.+}} 0 // CK25: [[ARRAY_DECAY_5:%.+]] = getelementptr inbounds [3 x float], ptr [[ARRAY_IDX_4]], {{.+}} 0, {{.+}} 0 - // CK25: [[ARRAY_IDX_6:%.+]] = getelementptr inbounds float, ptr [[ARRAY_DECAY_5:%.+]], {{.+}} 1 + // CK25: [[ARRAY_IDX_6:%.+]] = getelementptr inbounds nuw float, ptr [[ARRAY_DECAY_5:%.+]], {{.+}} 1 // CK25: [[BP0:%.+]] = getelementptr inbounds [3 x ptr], ptr [[BP:%.+]], i{{.+}} 0, i{{.+}} 0 // CK25: [[P0:%.+]] = getelementptr inbounds [3 x ptr], ptr [[P:%.+]], i{{.+}} 0, i{{.+}} 0 // CK25: [[DIM_1:%.+]] = getelementptr inbounds [4 x [[STRUCT_DESCRIPTOR]]], ptr [[DIMS]], {{.+}} 0, {{.+}} 0 diff --git a/clang/test/OpenMP/task_codegen.c b/clang/test/OpenMP/task_codegen.c index 0d10cbce4aa80..d08eb3762d5c9 100644 --- a/clang/test/OpenMP/task_codegen.c +++ b/clang/test/OpenMP/task_codegen.c @@ -183,7 +183,7 @@ for (int i = 0; i < 10; ++i) // CHECK: [[A:%.+]] = load ptr, ptr [[A_ADDR:%.+]], // CHECK: [[K:%.+]] = load i32, ptr [[K_ADDR]], // CHECK: [[IDX:%.+]] = zext i32 [[K]] to i64 - // CHECK: [[AK_ADDR:%.+]] = getelementptr inbounds ptr, ptr [[A]], i64 [[IDX]] + // CHECK: [[AK_ADDR:%.+]] = getelementptr inbounds nuw ptr, ptr [[A]], i64 [[IDX]] // CHECK: [[AK:%.+]] = load ptr, ptr [[AK_ADDR]], // CHECK: [[I:%.+]] = load i32, ptr [[I_ADDR]], // CHECK: [[IDX:%.+]] = sext i32 [[I]] to i64 diff --git a/clang/test/OpenMP/task_codegen.cpp b/clang/test/OpenMP/task_codegen.cpp index b256c41132ed3..c3e6d9e6b1cf7 100644 --- a/clang/test/OpenMP/task_codegen.cpp +++ b/clang/test/OpenMP/task_codegen.cpp @@ -309,9 +309,9 @@ void test_omp_all_memory() // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP30]], i32 0, i32 2 // CHECK1-NEXT: store i8 1, ptr [[TMP33]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK1-NEXT: [[TMP35:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP35]] +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP35]] // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr i32, ptr [[ARRAYIDX2]], i32 1 // CHECK1-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK1-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP36]] to i64 @@ -346,13 +346,13 @@ void test_omp_all_memory() // CHECK1-NEXT: [[TMP58:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-NEXT: [[TMP59:%.*]] = sext i8 [[TMP58]] to i64 // CHECK1-NEXT: [[TMP60:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP60]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP60]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] // CHECK1-NEXT: [[TMP61:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-NEXT: [[TMP62:%.*]] = sext i8 [[TMP61]] to i64 // CHECK1-NEXT: [[TMP63:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP63]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP63]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr i32, ptr [[ARRAYIDX10]], i32 1 // CHECK1-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[ARRAYIDX8]] to i64 // CHECK1-NEXT: [[TMP66:%.*]] = ptrtoint ptr [[TMP64]] to i64 @@ -384,13 +384,13 @@ void test_omp_all_memory() // CHECK1-NEXT: [[TMP83:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-NEXT: [[TMP84:%.*]] = sext i8 [[TMP83]] to i64 // CHECK1-NEXT: [[TMP85:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP85]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP85]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] // CHECK1-NEXT: [[TMP86:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-NEXT: [[TMP87:%.*]] = sext i8 [[TMP86]] to i64 // CHECK1-NEXT: [[TMP88:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP88]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP88]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] // CHECK1-NEXT: [[TMP89:%.*]] = getelementptr i32, ptr [[ARRAYIDX18]], i32 1 // CHECK1-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[ARRAYIDX16]] to i64 // CHECK1-NEXT: [[TMP91:%.*]] = ptrtoint ptr [[TMP89]] to i64 @@ -427,8 +427,8 @@ void test_omp_all_memory() // CHECK1-NEXT: [[TMP111:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP108]], i32 0, i32 2 // CHECK1-NEXT: store i8 3, ptr [[TMP111]], align 8 // CHECK1-NEXT: [[TMP112:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP112]] -// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 3 +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP112]] +// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 3 // CHECK1-NEXT: [[TMP113:%.*]] = load i32, ptr @a, align 4 // CHECK1-NEXT: [[TMP114:%.*]] = sext i32 [[TMP113]] to i64 // CHECK1-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP114]], 1 @@ -436,8 +436,8 @@ void test_omp_all_memory() // CHECK1-NEXT: [[TMP116:%.*]] = sext i32 [[TMP115]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP116]] // CHECK1-NEXT: [[TMP117:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP2]] -// CHECK1-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP117]] -// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] +// CHECK1-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP117]] +// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] // CHECK1-NEXT: [[TMP118:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK1-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK1-NEXT: [[TMP120:%.*]] = ptrtoint ptr [[TMP118]] to i64 @@ -1432,9 +1432,9 @@ void test_omp_all_memory() // CHECK1-51-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP30]], i32 0, i32 2 // CHECK1-51-NEXT: store i8 1, ptr [[TMP33]], align 8 // CHECK1-51-NEXT: [[TMP34:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK1-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK1-51-NEXT: [[TMP35:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP35]] +// CHECK1-51-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP35]] // CHECK1-51-NEXT: [[TMP36:%.*]] = getelementptr i32, ptr [[ARRAYIDX2]], i32 1 // CHECK1-51-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK1-51-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP36]] to i64 @@ -1469,13 +1469,13 @@ void test_omp_all_memory() // CHECK1-51-NEXT: [[TMP58:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-51-NEXT: [[TMP59:%.*]] = sext i8 [[TMP58]] to i64 // CHECK1-51-NEXT: [[TMP60:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP60]] -// CHECK1-51-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] +// CHECK1-51-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP60]] +// CHECK1-51-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] // CHECK1-51-NEXT: [[TMP61:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-51-NEXT: [[TMP62:%.*]] = sext i8 [[TMP61]] to i64 // CHECK1-51-NEXT: [[TMP63:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP63]] -// CHECK1-51-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] +// CHECK1-51-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP63]] +// CHECK1-51-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] // CHECK1-51-NEXT: [[TMP64:%.*]] = getelementptr i32, ptr [[ARRAYIDX10]], i32 1 // CHECK1-51-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[ARRAYIDX8]] to i64 // CHECK1-51-NEXT: [[TMP66:%.*]] = ptrtoint ptr [[TMP64]] to i64 @@ -1507,13 +1507,13 @@ void test_omp_all_memory() // CHECK1-51-NEXT: [[TMP83:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-51-NEXT: [[TMP84:%.*]] = sext i8 [[TMP83]] to i64 // CHECK1-51-NEXT: [[TMP85:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP85]] -// CHECK1-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] +// CHECK1-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP85]] +// CHECK1-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] // CHECK1-51-NEXT: [[TMP86:%.*]] = load i8, ptr [[B]], align 1 // CHECK1-51-NEXT: [[TMP87:%.*]] = sext i8 [[TMP86]] to i64 // CHECK1-51-NEXT: [[TMP88:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP88]] -// CHECK1-51-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] +// CHECK1-51-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP88]] +// CHECK1-51-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] // CHECK1-51-NEXT: [[TMP89:%.*]] = getelementptr i32, ptr [[ARRAYIDX18]], i32 1 // CHECK1-51-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[ARRAYIDX16]] to i64 // CHECK1-51-NEXT: [[TMP91:%.*]] = ptrtoint ptr [[TMP89]] to i64 @@ -1550,8 +1550,8 @@ void test_omp_all_memory() // CHECK1-51-NEXT: [[TMP111:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP108]], i32 0, i32 2 // CHECK1-51-NEXT: store i8 3, ptr [[TMP111]], align 8 // CHECK1-51-NEXT: [[TMP112:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP112]] -// CHECK1-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 3 +// CHECK1-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP112]] +// CHECK1-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 3 // CHECK1-51-NEXT: [[TMP113:%.*]] = load i32, ptr @a, align 4 // CHECK1-51-NEXT: [[TMP114:%.*]] = sext i32 [[TMP113]] to i64 // CHECK1-51-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP114]], 1 @@ -1559,8 +1559,8 @@ void test_omp_all_memory() // CHECK1-51-NEXT: [[TMP116:%.*]] = sext i32 [[TMP115]] to i64 // CHECK1-51-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP116]] // CHECK1-51-NEXT: [[TMP117:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP117]] -// CHECK1-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] +// CHECK1-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP117]] +// CHECK1-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] // CHECK1-51-NEXT: [[TMP118:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK1-51-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK1-51-NEXT: [[TMP120:%.*]] = ptrtoint ptr [[TMP118]] to i64 @@ -1595,8 +1595,8 @@ void test_omp_all_memory() // CHECK1-51-NEXT: [[TMP139:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP136]], i32 0, i32 2 // CHECK1-51-NEXT: store i8 8, ptr [[TMP139]], align 8 // CHECK1-51-NEXT: [[TMP140:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX31:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP140]] -// CHECK1-51-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX31]], i64 3 +// CHECK1-51-NEXT: [[ARRAYIDX31:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP140]] +// CHECK1-51-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX31]], i64 3 // CHECK1-51-NEXT: [[TMP141:%.*]] = load i32, ptr @a, align 4 // CHECK1-51-NEXT: [[TMP142:%.*]] = sext i32 [[TMP141]] to i64 // CHECK1-51-NEXT: [[LEN_SUB_133:%.*]] = sub nsw i64 [[TMP142]], 1 @@ -1604,8 +1604,8 @@ void test_omp_all_memory() // CHECK1-51-NEXT: [[TMP144:%.*]] = sext i32 [[TMP143]] to i64 // CHECK1-51-NEXT: [[LB_ADD_LEN34:%.*]] = add nsw i64 -1, [[TMP144]] // CHECK1-51-NEXT: [[TMP145:%.*]] = mul nsw i64 [[LB_ADD_LEN34]], [[TMP2]] -// CHECK1-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP145]] -// CHECK1-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_133]] +// CHECK1-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP145]] +// CHECK1-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_133]] // CHECK1-51-NEXT: [[TMP146:%.*]] = getelementptr i32, ptr [[ARRAYIDX36]], i32 1 // CHECK1-51-NEXT: [[TMP147:%.*]] = ptrtoint ptr [[ARRAYIDX32]] to i64 // CHECK1-51-NEXT: [[TMP148:%.*]] = ptrtoint ptr [[TMP146]] to i64 @@ -3040,9 +3040,9 @@ void test_omp_all_memory() // CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP30]], i32 0, i32 2 // CHECK2-NEXT: store i8 1, ptr [[TMP33]], align 8 // CHECK2-NEXT: [[TMP34:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK2-NEXT: [[TMP35:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP35]] +// CHECK2-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP35]] // CHECK2-NEXT: [[TMP36:%.*]] = getelementptr i32, ptr [[ARRAYIDX2]], i32 1 // CHECK2-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK2-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP36]] to i64 @@ -3077,13 +3077,13 @@ void test_omp_all_memory() // CHECK2-NEXT: [[TMP58:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-NEXT: [[TMP59:%.*]] = sext i8 [[TMP58]] to i64 // CHECK2-NEXT: [[TMP60:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP60]] -// CHECK2-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] +// CHECK2-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP60]] +// CHECK2-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] // CHECK2-NEXT: [[TMP61:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-NEXT: [[TMP62:%.*]] = sext i8 [[TMP61]] to i64 // CHECK2-NEXT: [[TMP63:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP63]] -// CHECK2-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] +// CHECK2-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP63]] +// CHECK2-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] // CHECK2-NEXT: [[TMP64:%.*]] = getelementptr i32, ptr [[ARRAYIDX10]], i32 1 // CHECK2-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[ARRAYIDX8]] to i64 // CHECK2-NEXT: [[TMP66:%.*]] = ptrtoint ptr [[TMP64]] to i64 @@ -3115,13 +3115,13 @@ void test_omp_all_memory() // CHECK2-NEXT: [[TMP83:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-NEXT: [[TMP84:%.*]] = sext i8 [[TMP83]] to i64 // CHECK2-NEXT: [[TMP85:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP85]] -// CHECK2-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] +// CHECK2-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP85]] +// CHECK2-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] // CHECK2-NEXT: [[TMP86:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-NEXT: [[TMP87:%.*]] = sext i8 [[TMP86]] to i64 // CHECK2-NEXT: [[TMP88:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP88]] -// CHECK2-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] +// CHECK2-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP88]] +// CHECK2-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] // CHECK2-NEXT: [[TMP89:%.*]] = getelementptr i32, ptr [[ARRAYIDX18]], i32 1 // CHECK2-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[ARRAYIDX16]] to i64 // CHECK2-NEXT: [[TMP91:%.*]] = ptrtoint ptr [[TMP89]] to i64 @@ -3158,8 +3158,8 @@ void test_omp_all_memory() // CHECK2-NEXT: [[TMP111:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP108]], i32 0, i32 2 // CHECK2-NEXT: store i8 3, ptr [[TMP111]], align 8 // CHECK2-NEXT: [[TMP112:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP112]] -// CHECK2-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 3 +// CHECK2-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP112]] +// CHECK2-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 3 // CHECK2-NEXT: [[TMP113:%.*]] = load i32, ptr @a, align 4 // CHECK2-NEXT: [[TMP114:%.*]] = sext i32 [[TMP113]] to i64 // CHECK2-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP114]], 1 @@ -3167,8 +3167,8 @@ void test_omp_all_memory() // CHECK2-NEXT: [[TMP116:%.*]] = sext i32 [[TMP115]] to i64 // CHECK2-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP116]] // CHECK2-NEXT: [[TMP117:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP2]] -// CHECK2-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP117]] -// CHECK2-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] +// CHECK2-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP117]] +// CHECK2-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] // CHECK2-NEXT: [[TMP118:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK2-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK2-NEXT: [[TMP120:%.*]] = ptrtoint ptr [[TMP118]] to i64 @@ -4163,9 +4163,9 @@ void test_omp_all_memory() // CHECK2-51-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP30]], i32 0, i32 2 // CHECK2-51-NEXT: store i8 1, ptr [[TMP33]], align 8 // CHECK2-51-NEXT: [[TMP34:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK2-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK2-51-NEXT: [[TMP35:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP35]] +// CHECK2-51-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP35]] // CHECK2-51-NEXT: [[TMP36:%.*]] = getelementptr i32, ptr [[ARRAYIDX2]], i32 1 // CHECK2-51-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK2-51-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP36]] to i64 @@ -4200,13 +4200,13 @@ void test_omp_all_memory() // CHECK2-51-NEXT: [[TMP58:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-51-NEXT: [[TMP59:%.*]] = sext i8 [[TMP58]] to i64 // CHECK2-51-NEXT: [[TMP60:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP60]] -// CHECK2-51-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] +// CHECK2-51-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP60]] +// CHECK2-51-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX7]], i64 [[TMP59]] // CHECK2-51-NEXT: [[TMP61:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-51-NEXT: [[TMP62:%.*]] = sext i8 [[TMP61]] to i64 // CHECK2-51-NEXT: [[TMP63:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP63]] -// CHECK2-51-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] +// CHECK2-51-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP63]] +// CHECK2-51-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX9]], i64 [[TMP62]] // CHECK2-51-NEXT: [[TMP64:%.*]] = getelementptr i32, ptr [[ARRAYIDX10]], i32 1 // CHECK2-51-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[ARRAYIDX8]] to i64 // CHECK2-51-NEXT: [[TMP66:%.*]] = ptrtoint ptr [[TMP64]] to i64 @@ -4238,13 +4238,13 @@ void test_omp_all_memory() // CHECK2-51-NEXT: [[TMP83:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-51-NEXT: [[TMP84:%.*]] = sext i8 [[TMP83]] to i64 // CHECK2-51-NEXT: [[TMP85:%.*]] = mul nsw i64 4, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP85]] -// CHECK2-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] +// CHECK2-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP85]] +// CHECK2-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP84]] // CHECK2-51-NEXT: [[TMP86:%.*]] = load i8, ptr [[B]], align 1 // CHECK2-51-NEXT: [[TMP87:%.*]] = sext i8 [[TMP86]] to i64 // CHECK2-51-NEXT: [[TMP88:%.*]] = mul nsw i64 9, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP88]] -// CHECK2-51-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] +// CHECK2-51-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP88]] +// CHECK2-51-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX17]], i64 [[TMP87]] // CHECK2-51-NEXT: [[TMP89:%.*]] = getelementptr i32, ptr [[ARRAYIDX18]], i32 1 // CHECK2-51-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[ARRAYIDX16]] to i64 // CHECK2-51-NEXT: [[TMP91:%.*]] = ptrtoint ptr [[TMP89]] to i64 @@ -4281,8 +4281,8 @@ void test_omp_all_memory() // CHECK2-51-NEXT: [[TMP111:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP108]], i32 0, i32 2 // CHECK2-51-NEXT: store i8 3, ptr [[TMP111]], align 8 // CHECK2-51-NEXT: [[TMP112:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP112]] -// CHECK2-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 3 +// CHECK2-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP112]] +// CHECK2-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 3 // CHECK2-51-NEXT: [[TMP113:%.*]] = load i32, ptr @a, align 4 // CHECK2-51-NEXT: [[TMP114:%.*]] = sext i32 [[TMP113]] to i64 // CHECK2-51-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP114]], 1 @@ -4290,8 +4290,8 @@ void test_omp_all_memory() // CHECK2-51-NEXT: [[TMP116:%.*]] = sext i32 [[TMP115]] to i64 // CHECK2-51-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP116]] // CHECK2-51-NEXT: [[TMP117:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP117]] -// CHECK2-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] +// CHECK2-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP117]] +// CHECK2-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[LEN_SUB_1]] // CHECK2-51-NEXT: [[TMP118:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK2-51-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK2-51-NEXT: [[TMP120:%.*]] = ptrtoint ptr [[TMP118]] to i64 @@ -4326,8 +4326,8 @@ void test_omp_all_memory() // CHECK2-51-NEXT: [[TMP139:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP136]], i32 0, i32 2 // CHECK2-51-NEXT: store i8 8, ptr [[TMP139]], align 8 // CHECK2-51-NEXT: [[TMP140:%.*]] = mul nsw i64 0, [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX31:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP140]] -// CHECK2-51-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX31]], i64 3 +// CHECK2-51-NEXT: [[ARRAYIDX31:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP140]] +// CHECK2-51-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX31]], i64 3 // CHECK2-51-NEXT: [[TMP141:%.*]] = load i32, ptr @a, align 4 // CHECK2-51-NEXT: [[TMP142:%.*]] = sext i32 [[TMP141]] to i64 // CHECK2-51-NEXT: [[LEN_SUB_133:%.*]] = sub nsw i64 [[TMP142]], 1 @@ -4335,8 +4335,8 @@ void test_omp_all_memory() // CHECK2-51-NEXT: [[TMP144:%.*]] = sext i32 [[TMP143]] to i64 // CHECK2-51-NEXT: [[LB_ADD_LEN34:%.*]] = add nsw i64 -1, [[TMP144]] // CHECK2-51-NEXT: [[TMP145:%.*]] = mul nsw i64 [[LB_ADD_LEN34]], [[TMP2]] -// CHECK2-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP145]] -// CHECK2-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_133]] +// CHECK2-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP145]] +// CHECK2-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_133]] // CHECK2-51-NEXT: [[TMP146:%.*]] = getelementptr i32, ptr [[ARRAYIDX36]], i32 1 // CHECK2-51-NEXT: [[TMP147:%.*]] = ptrtoint ptr [[ARRAYIDX32]] to i64 // CHECK2-51-NEXT: [[TMP148:%.*]] = ptrtoint ptr [[TMP146]] to i64 @@ -5773,9 +5773,9 @@ void test_omp_all_memory() // CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP29]], i32 0, i32 2 // CHECK3-NEXT: store i8 1, ptr [[TMP32]], align 8 // CHECK3-NEXT: [[TMP33:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP33]] +// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP33]] // CHECK3-NEXT: [[TMP34:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK3-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK3-NEXT: [[TMP35:%.*]] = getelementptr i32, ptr [[ARRAYIDX4]], i32 1 // CHECK3-NEXT: [[TMP36:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK3-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[TMP35]] to i64 @@ -5814,13 +5814,13 @@ void test_omp_all_memory() // CHECK3-NEXT: [[TMP57:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-NEXT: [[TMP58:%.*]] = sext i8 [[TMP57]] to i64 // CHECK3-NEXT: [[TMP59:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP59]] -// CHECK3-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] +// CHECK3-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP59]] +// CHECK3-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] // CHECK3-NEXT: [[TMP60:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-NEXT: [[TMP61:%.*]] = sext i8 [[TMP60]] to i64 // CHECK3-NEXT: [[TMP62:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP62]] -// CHECK3-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] +// CHECK3-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP62]] +// CHECK3-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] // CHECK3-NEXT: [[TMP63:%.*]] = getelementptr i32, ptr [[ARRAYIDX16]], i32 1 // CHECK3-NEXT: [[TMP64:%.*]] = ptrtoint ptr [[ARRAYIDX14]] to i64 // CHECK3-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[TMP63]] to i64 @@ -5854,13 +5854,13 @@ void test_omp_all_memory() // CHECK3-NEXT: [[TMP82:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-NEXT: [[TMP83:%.*]] = sext i8 [[TMP82]] to i64 // CHECK3-NEXT: [[TMP84:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP84]] -// CHECK3-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] +// CHECK3-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP84]] +// CHECK3-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] // CHECK3-NEXT: [[TMP85:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-NEXT: [[TMP86:%.*]] = sext i8 [[TMP85]] to i64 // CHECK3-NEXT: [[TMP87:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP87]] -// CHECK3-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] +// CHECK3-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP87]] +// CHECK3-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] // CHECK3-NEXT: [[TMP88:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK3-NEXT: [[TMP89:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK3-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[TMP88]] to i64 @@ -5899,8 +5899,8 @@ void test_omp_all_memory() // CHECK3-NEXT: [[TMP110:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP107]], i32 0, i32 2 // CHECK3-NEXT: store i8 3, ptr [[TMP110]], align 8 // CHECK3-NEXT: [[TMP111:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP111]] -// CHECK3-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX33]], i64 3 +// CHECK3-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP111]] +// CHECK3-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX33]], i64 3 // CHECK3-NEXT: [[TMP112:%.*]] = load i32, ptr @a, align 4 // CHECK3-NEXT: [[TMP113:%.*]] = sext i32 [[TMP112]] to i64 // CHECK3-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP113]], 1 @@ -5908,8 +5908,8 @@ void test_omp_all_memory() // CHECK3-NEXT: [[TMP115:%.*]] = sext i32 [[TMP114]] to i64 // CHECK3-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP115]] // CHECK3-NEXT: [[TMP116:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP1]] -// CHECK3-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP116]] -// CHECK3-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] +// CHECK3-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP116]] +// CHECK3-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] // CHECK3-NEXT: [[TMP117:%.*]] = getelementptr i32, ptr [[ARRAYIDX36]], i32 1 // CHECK3-NEXT: [[TMP118:%.*]] = ptrtoint ptr [[ARRAYIDX34]] to i64 // CHECK3-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[TMP117]] to i64 @@ -6789,9 +6789,9 @@ void test_omp_all_memory() // CHECK4-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP29]], i32 0, i32 2 // CHECK4-NEXT: store i8 1, ptr [[TMP32]], align 8 // CHECK4-NEXT: [[TMP33:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP33]] +// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP33]] // CHECK4-NEXT: [[TMP34:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK4-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK4-NEXT: [[TMP35:%.*]] = getelementptr i32, ptr [[ARRAYIDX4]], i32 1 // CHECK4-NEXT: [[TMP36:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK4-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[TMP35]] to i64 @@ -6830,13 +6830,13 @@ void test_omp_all_memory() // CHECK4-NEXT: [[TMP57:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-NEXT: [[TMP58:%.*]] = sext i8 [[TMP57]] to i64 // CHECK4-NEXT: [[TMP59:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP59]] -// CHECK4-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] +// CHECK4-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP59]] +// CHECK4-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] // CHECK4-NEXT: [[TMP60:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-NEXT: [[TMP61:%.*]] = sext i8 [[TMP60]] to i64 // CHECK4-NEXT: [[TMP62:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP62]] -// CHECK4-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] +// CHECK4-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP62]] +// CHECK4-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] // CHECK4-NEXT: [[TMP63:%.*]] = getelementptr i32, ptr [[ARRAYIDX16]], i32 1 // CHECK4-NEXT: [[TMP64:%.*]] = ptrtoint ptr [[ARRAYIDX14]] to i64 // CHECK4-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[TMP63]] to i64 @@ -6870,13 +6870,13 @@ void test_omp_all_memory() // CHECK4-NEXT: [[TMP82:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-NEXT: [[TMP83:%.*]] = sext i8 [[TMP82]] to i64 // CHECK4-NEXT: [[TMP84:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP84]] -// CHECK4-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] +// CHECK4-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP84]] +// CHECK4-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] // CHECK4-NEXT: [[TMP85:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-NEXT: [[TMP86:%.*]] = sext i8 [[TMP85]] to i64 // CHECK4-NEXT: [[TMP87:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP87]] -// CHECK4-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] +// CHECK4-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP87]] +// CHECK4-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] // CHECK4-NEXT: [[TMP88:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK4-NEXT: [[TMP89:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK4-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[TMP88]] to i64 @@ -6915,8 +6915,8 @@ void test_omp_all_memory() // CHECK4-NEXT: [[TMP110:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP107]], i32 0, i32 2 // CHECK4-NEXT: store i8 3, ptr [[TMP110]], align 8 // CHECK4-NEXT: [[TMP111:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP111]] -// CHECK4-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX33]], i64 3 +// CHECK4-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP111]] +// CHECK4-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX33]], i64 3 // CHECK4-NEXT: [[TMP112:%.*]] = load i32, ptr @a, align 4 // CHECK4-NEXT: [[TMP113:%.*]] = sext i32 [[TMP112]] to i64 // CHECK4-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP113]], 1 @@ -6924,8 +6924,8 @@ void test_omp_all_memory() // CHECK4-NEXT: [[TMP115:%.*]] = sext i32 [[TMP114]] to i64 // CHECK4-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP115]] // CHECK4-NEXT: [[TMP116:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP1]] -// CHECK4-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP116]] -// CHECK4-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] +// CHECK4-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP116]] +// CHECK4-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] // CHECK4-NEXT: [[TMP117:%.*]] = getelementptr i32, ptr [[ARRAYIDX36]], i32 1 // CHECK4-NEXT: [[TMP118:%.*]] = ptrtoint ptr [[ARRAYIDX34]] to i64 // CHECK4-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[TMP117]] to i64 @@ -7808,9 +7808,9 @@ void test_omp_all_memory() // CHECK3-51-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP29]], i32 0, i32 2 // CHECK3-51-NEXT: store i8 1, ptr [[TMP32]], align 8 // CHECK3-51-NEXT: [[TMP33:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP33]] +// CHECK3-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP33]] // CHECK3-51-NEXT: [[TMP34:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK3-51-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK3-51-NEXT: [[TMP35:%.*]] = getelementptr i32, ptr [[ARRAYIDX4]], i32 1 // CHECK3-51-NEXT: [[TMP36:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK3-51-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[TMP35]] to i64 @@ -7849,13 +7849,13 @@ void test_omp_all_memory() // CHECK3-51-NEXT: [[TMP57:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-51-NEXT: [[TMP58:%.*]] = sext i8 [[TMP57]] to i64 // CHECK3-51-NEXT: [[TMP59:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP59]] -// CHECK3-51-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] +// CHECK3-51-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP59]] +// CHECK3-51-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] // CHECK3-51-NEXT: [[TMP60:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-51-NEXT: [[TMP61:%.*]] = sext i8 [[TMP60]] to i64 // CHECK3-51-NEXT: [[TMP62:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP62]] -// CHECK3-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] +// CHECK3-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP62]] +// CHECK3-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] // CHECK3-51-NEXT: [[TMP63:%.*]] = getelementptr i32, ptr [[ARRAYIDX16]], i32 1 // CHECK3-51-NEXT: [[TMP64:%.*]] = ptrtoint ptr [[ARRAYIDX14]] to i64 // CHECK3-51-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[TMP63]] to i64 @@ -7889,13 +7889,13 @@ void test_omp_all_memory() // CHECK3-51-NEXT: [[TMP82:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-51-NEXT: [[TMP83:%.*]] = sext i8 [[TMP82]] to i64 // CHECK3-51-NEXT: [[TMP84:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP84]] -// CHECK3-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] +// CHECK3-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP84]] +// CHECK3-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] // CHECK3-51-NEXT: [[TMP85:%.*]] = load i8, ptr [[B]], align 1 // CHECK3-51-NEXT: [[TMP86:%.*]] = sext i8 [[TMP85]] to i64 // CHECK3-51-NEXT: [[TMP87:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP87]] -// CHECK3-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] +// CHECK3-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP87]] +// CHECK3-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] // CHECK3-51-NEXT: [[TMP88:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK3-51-NEXT: [[TMP89:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK3-51-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[TMP88]] to i64 @@ -7934,8 +7934,8 @@ void test_omp_all_memory() // CHECK3-51-NEXT: [[TMP110:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP107]], i32 0, i32 2 // CHECK3-51-NEXT: store i8 3, ptr [[TMP110]], align 8 // CHECK3-51-NEXT: [[TMP111:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP111]] -// CHECK3-51-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX33]], i64 3 +// CHECK3-51-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP111]] +// CHECK3-51-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX33]], i64 3 // CHECK3-51-NEXT: [[TMP112:%.*]] = load i32, ptr @a, align 4 // CHECK3-51-NEXT: [[TMP113:%.*]] = sext i32 [[TMP112]] to i64 // CHECK3-51-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP113]], 1 @@ -7943,8 +7943,8 @@ void test_omp_all_memory() // CHECK3-51-NEXT: [[TMP115:%.*]] = sext i32 [[TMP114]] to i64 // CHECK3-51-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP115]] // CHECK3-51-NEXT: [[TMP116:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP116]] -// CHECK3-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] +// CHECK3-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP116]] +// CHECK3-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] // CHECK3-51-NEXT: [[TMP117:%.*]] = getelementptr i32, ptr [[ARRAYIDX36]], i32 1 // CHECK3-51-NEXT: [[TMP118:%.*]] = ptrtoint ptr [[ARRAYIDX34]] to i64 // CHECK3-51-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[TMP117]] to i64 @@ -7981,8 +7981,8 @@ void test_omp_all_memory() // CHECK3-51-NEXT: [[TMP138:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP135]], i32 0, i32 2 // CHECK3-51-NEXT: store i8 8, ptr [[TMP138]], align 8 // CHECK3-51-NEXT: [[TMP139:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX43:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP139]] -// CHECK3-51-NEXT: [[ARRAYIDX44:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX43]], i64 3 +// CHECK3-51-NEXT: [[ARRAYIDX43:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP139]] +// CHECK3-51-NEXT: [[ARRAYIDX44:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX43]], i64 3 // CHECK3-51-NEXT: [[TMP140:%.*]] = load i32, ptr @a, align 4 // CHECK3-51-NEXT: [[TMP141:%.*]] = sext i32 [[TMP140]] to i64 // CHECK3-51-NEXT: [[LEN_SUB_145:%.*]] = sub nsw i64 [[TMP141]], 1 @@ -7990,8 +7990,8 @@ void test_omp_all_memory() // CHECK3-51-NEXT: [[TMP143:%.*]] = sext i32 [[TMP142]] to i64 // CHECK3-51-NEXT: [[LB_ADD_LEN46:%.*]] = add nsw i64 -1, [[TMP143]] // CHECK3-51-NEXT: [[TMP144:%.*]] = mul nsw i64 [[LB_ADD_LEN46]], [[TMP1]] -// CHECK3-51-NEXT: [[ARRAYIDX47:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP144]] -// CHECK3-51-NEXT: [[ARRAYIDX48:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX47]], i64 [[LEN_SUB_145]] +// CHECK3-51-NEXT: [[ARRAYIDX47:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP144]] +// CHECK3-51-NEXT: [[ARRAYIDX48:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX47]], i64 [[LEN_SUB_145]] // CHECK3-51-NEXT: [[TMP145:%.*]] = getelementptr i32, ptr [[ARRAYIDX48]], i32 1 // CHECK3-51-NEXT: [[TMP146:%.*]] = ptrtoint ptr [[ARRAYIDX44]] to i64 // CHECK3-51-NEXT: [[TMP147:%.*]] = ptrtoint ptr [[TMP145]] to i64 @@ -9323,9 +9323,9 @@ void test_omp_all_memory() // CHECK4-51-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP29]], i32 0, i32 2 // CHECK4-51-NEXT: store i8 1, ptr [[TMP32]], align 8 // CHECK4-51-NEXT: [[TMP33:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP33]] +// CHECK4-51-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP33]] // CHECK4-51-NEXT: [[TMP34:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP34]] +// CHECK4-51-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP34]] // CHECK4-51-NEXT: [[TMP35:%.*]] = getelementptr i32, ptr [[ARRAYIDX4]], i32 1 // CHECK4-51-NEXT: [[TMP36:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 // CHECK4-51-NEXT: [[TMP37:%.*]] = ptrtoint ptr [[TMP35]] to i64 @@ -9364,13 +9364,13 @@ void test_omp_all_memory() // CHECK4-51-NEXT: [[TMP57:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-51-NEXT: [[TMP58:%.*]] = sext i8 [[TMP57]] to i64 // CHECK4-51-NEXT: [[TMP59:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP59]] -// CHECK4-51-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] +// CHECK4-51-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP59]] +// CHECK4-51-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX13]], i64 [[TMP58]] // CHECK4-51-NEXT: [[TMP60:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-51-NEXT: [[TMP61:%.*]] = sext i8 [[TMP60]] to i64 // CHECK4-51-NEXT: [[TMP62:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP62]] -// CHECK4-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] +// CHECK4-51-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP62]] +// CHECK4-51-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX15]], i64 [[TMP61]] // CHECK4-51-NEXT: [[TMP63:%.*]] = getelementptr i32, ptr [[ARRAYIDX16]], i32 1 // CHECK4-51-NEXT: [[TMP64:%.*]] = ptrtoint ptr [[ARRAYIDX14]] to i64 // CHECK4-51-NEXT: [[TMP65:%.*]] = ptrtoint ptr [[TMP63]] to i64 @@ -9404,13 +9404,13 @@ void test_omp_all_memory() // CHECK4-51-NEXT: [[TMP82:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-51-NEXT: [[TMP83:%.*]] = sext i8 [[TMP82]] to i64 // CHECK4-51-NEXT: [[TMP84:%.*]] = mul nsw i64 4, [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP84]] -// CHECK4-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] +// CHECK4-51-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP84]] +// CHECK4-51-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX23]], i64 [[TMP83]] // CHECK4-51-NEXT: [[TMP85:%.*]] = load i8, ptr [[B]], align 1 // CHECK4-51-NEXT: [[TMP86:%.*]] = sext i8 [[TMP85]] to i64 // CHECK4-51-NEXT: [[TMP87:%.*]] = mul nsw i64 9, [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP87]] -// CHECK4-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] +// CHECK4-51-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP87]] +// CHECK4-51-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX25]], i64 [[TMP86]] // CHECK4-51-NEXT: [[TMP88:%.*]] = getelementptr i32, ptr [[ARRAYIDX26]], i32 1 // CHECK4-51-NEXT: [[TMP89:%.*]] = ptrtoint ptr [[ARRAYIDX24]] to i64 // CHECK4-51-NEXT: [[TMP90:%.*]] = ptrtoint ptr [[TMP88]] to i64 @@ -9449,8 +9449,8 @@ void test_omp_all_memory() // CHECK4-51-NEXT: [[TMP110:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_DEPEND_INFO]], ptr [[TMP107]], i32 0, i32 2 // CHECK4-51-NEXT: store i8 3, ptr [[TMP110]], align 8 // CHECK4-51-NEXT: [[TMP111:%.*]] = mul nsw i64 0, [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP111]] -// CHECK4-51-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX33]], i64 3 +// CHECK4-51-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP111]] +// CHECK4-51-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX33]], i64 3 // CHECK4-51-NEXT: [[TMP112:%.*]] = load i32, ptr @a, align 4 // CHECK4-51-NEXT: [[TMP113:%.*]] = sext i32 [[TMP112]] to i64 // CHECK4-51-NEXT: [[LEN_SUB_1:%.*]] = sub nsw i64 [[TMP113]], 1 @@ -9458,8 +9458,8 @@ void test_omp_all_memory() // CHECK4-51-NEXT: [[TMP115:%.*]] = sext i32 [[TMP114]] to i64 // CHECK4-51-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP115]] // CHECK4-51-NEXT: [[TMP116:%.*]] = mul nsw i64 [[LB_ADD_LEN]], [[TMP1]] -// CHECK4-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds i32, ptr [[VLA]], i64 [[TMP116]] -// CHECK4-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] +// CHECK4-51-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds nuw i32, ptr [[VLA]], i64 [[TMP116]] +// CHECK4-51-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw i32, ptr [[ARRAYIDX35]], i64 [[LEN_SUB_1]] // CHECK4-51-NEXT: [[TMP117:%.*]] = getelementptr i32, ptr [[ARRAYIDX36]], i32 1 // CHECK4-51-NEXT: [[TMP118:%.*]] = ptrtoint ptr [[ARRAYIDX34]] to i64 // CHECK4-51-NEXT: [[TMP119:%.*]] = ptrtoint ptr [[TMP117]] to i64 diff --git a/clang/test/OpenMP/task_in_reduction_codegen.cpp b/clang/test/OpenMP/task_in_reduction_codegen.cpp index aa2a478137990..29dc12978d7d9 100644 --- a/clang/test/OpenMP/task_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/task_in_reduction_codegen.cpp @@ -90,7 +90,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[VLA:%.*]] = alloca i16, i64 [[TMP2]], align 16 // CHECK1-NEXT: store i64 [[TMP2]], ptr [[__VLA_EXPR0]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[A]], ptr [[TMP4]], align 8 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -105,7 +105,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP9]], align 8 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP10]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[B]], ptr [[TMP11]], align 8 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 1 @@ -120,7 +120,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..2, ptr [[TMP16]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP17]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC_ADDR]], ptr [[TMP18]], align 8 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 1 @@ -138,7 +138,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP25:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 3, ptr [[DOTRD_INPUT_]]) // CHECK1-NEXT: store ptr [[TMP25]], ptr [[DOTTASK_RED_]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[C]], ptr [[TMP26]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 1 @@ -153,7 +153,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..6, ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP32]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP33]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 1 diff --git a/clang/test/OpenMP/taskgroup_task_reduction_codegen.cpp b/clang/test/OpenMP/taskgroup_task_reduction_codegen.cpp index faf86479dfdae..a8577c7a13579 100644 --- a/clang/test/OpenMP/taskgroup_task_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskgroup_task_reduction_codegen.cpp @@ -67,7 +67,7 @@ int main(int argc, char **argv) { // CHECK-DAG: [[A_REF]] = getelementptr inbounds nuw [[T1]], ptr [[GEPA:%[^,]+]], i32 0, i32 0 // CHECK-DAG: store ptr [[A]], ptr [[A_REF:[^,]+]], // CHECK-DAG: [[A_REF]] = getelementptr inbounds nuw [[T1]], ptr [[GEPA]], i32 0, i32 1 -// CHECK-DAG: [[GEPA]] = getelementptr inbounds [3 x [[T1]]], ptr [[RD_IN1]], i64 0, i64 +// CHECK-DAG: [[GEPA]] = getelementptr inbounds nuw [3 x [[T1]]], ptr [[RD_IN1]], i64 0, i64 // CHECK-DAG: [[TMP6:%.+]] = getelementptr inbounds nuw [[T1]], ptr [[GEPA]], i32 0, i32 2 // CHECK-DAG: store i64 4, ptr [[TMP6]], // CHECK-DAG: [[TMP7:%.+]] = getelementptr inbounds nuw [[T1]], ptr [[GEPA]], i32 0, i32 3 @@ -82,7 +82,7 @@ int main(int argc, char **argv) { // CHECK-DAG: [[TMP12]] = getelementptr inbounds nuw [[T1]], ptr [[GEPB:%[^,]+]], i32 0, i32 0 // CHECK-DAG: store ptr [[B]], ptr [[TMP12:%[^,]+]], // CHECK-DAG: [[TMP12]] = getelementptr inbounds nuw [[T1]], ptr [[GEPB]], i32 0, i32 1 -// CHECK-DAG: [[GEPB]] = getelementptr inbounds [3 x [[T1]]], ptr [[RD_IN1]], i64 0, i64 +// CHECK-DAG: [[GEPB]] = getelementptr inbounds nuw [3 x [[T1]]], ptr [[RD_IN1]], i64 0, i64 // CHECK-DAG: [[TMP14:%.+]] = getelementptr inbounds nuw [[T1]], ptr [[GEPB]], i32 0, i32 2 // CHECK-DAG: store i64 4, ptr [[TMP14]], // CHECK-DAG: [[TMP15:%.+]] = getelementptr inbounds nuw [[T1]], ptr [[GEPB]], i32 0, i32 3 @@ -97,7 +97,7 @@ int main(int argc, char **argv) { // CHECK-DAG: [[TMP20]] = getelementptr inbounds nuw [[T1]], ptr [[GEPARGC:%[^,]+]], i32 0, i32 0 // CHECK-DAG: store ptr [[ARGC_ADDR]], ptr [[TMP20:%[^,]+]], // CHECK-DAG: [[TMP20]] = getelementptr inbounds nuw [[T1]], ptr [[GEPARGC]], i32 0, i32 1 -// CHECK-DAG: [[GEPARGC]] = getelementptr inbounds [3 x [[T1]]], ptr [[RD_IN1]], i64 0, i64 +// CHECK-DAG: [[GEPARGC]] = getelementptr inbounds nuw [3 x [[T1]]], ptr [[RD_IN1]], i64 0, i64 // CHECK-DAG: [[TMP22:%.+]] = getelementptr inbounds nuw [[T1]], ptr [[GEPARGC]], i32 0, i32 2 // CHECK-DAG: store i64 4, ptr [[TMP22]], // CHECK-DAG: [[TMP23:%.+]] = getelementptr inbounds nuw [[T1]], ptr [[GEPARGC]], i32 0, i32 3 @@ -116,7 +116,7 @@ int main(int argc, char **argv) { // CHECK-DAG: [[TMP30]] = getelementptr inbounds nuw [[T2]], ptr [[GEPC:%[^,]+]], i32 0, i32 0 // CHECK-DAG: store ptr [[C]], ptr [[TMP30:%[^,]+]], // CHECK-DAG: [[TMP30]] = getelementptr inbounds nuw [[T2]], ptr [[GEPC]], i32 0, i32 1 -// CHECK-DAG: [[GEPC]] = getelementptr inbounds [2 x [[T2]]], ptr [[RD_IN2]], i64 0, i64 +// CHECK-DAG: [[GEPC]] = getelementptr inbounds nuw [2 x [[T2]]], ptr [[RD_IN2]], i64 0, i64 // CHECK-DAG: [[TMP32:%.+]] = getelementptr inbounds nuw [[T2]], ptr [[GEPC]], i32 0, i32 2 // CHECK-DAG: store i64 20, ptr [[TMP32]], // CHECK-DAG: [[TMP33:%.+]] = getelementptr inbounds nuw [[T2]], ptr [[GEPC]], i32 0, i32 3 @@ -131,7 +131,7 @@ int main(int argc, char **argv) { // CHECK-DAG: [[TMP38]] = getelementptr inbounds nuw [[T2]], ptr [[GEPVLA:%[^,]+]], i32 0, i32 0 // CHECK-DAG: store ptr [[VLA]], ptr [[TMP38:%[^,]+]], // CHECK-DAG: [[TMP38]] = getelementptr inbounds nuw [[T2]], ptr [[GEPVLA]], i32 0, i32 1 -// CHECK-DAG: [[GEPVLA]] = getelementptr inbounds [2 x [[T2]]], ptr [[RD_IN2]], i64 0, i64 +// CHECK-DAG: [[GEPVLA]] = getelementptr inbounds nuw [2 x [[T2]]], ptr [[RD_IN2]], i64 0, i64 // CHECK-DAG: [[TMP40:%.+]] = mul nuw i64 [[VLA_SIZE]], 2 // CHECK-DAG: [[TMP41:%.+]] = udiv exact i64 [[TMP40]], ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64) // CHECK-DAG: [[TMP42:%.+]] = getelementptr inbounds nuw [[T2]], ptr [[GEPVLA]], i32 0, i32 2 diff --git a/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp index ae0d007756140..87b4cd2caf18a 100644 --- a/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp @@ -76,7 +76,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[VLA:%.*]] = alloca i16, i64 [[TMP2]], align 16 // CHECK1-NEXT: store i64 [[TMP2]], ptr [[__VLA_EXPR0]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[A]], ptr [[TMP4]], align 8 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -91,7 +91,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP9]], align 8 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP10]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[B]], ptr [[TMP11]], align 8 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 1 @@ -106,7 +106,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..2, ptr [[TMP16]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP17]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC_ADDR]], ptr [[TMP18]], align 8 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 1 @@ -124,7 +124,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP25:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 3, ptr [[DOTRD_INPUT_]]) // CHECK1-NEXT: store ptr [[TMP25]], ptr [[DOTTASK_RED_]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[C]], ptr [[TMP26]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 1 @@ -139,7 +139,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..6, ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP32]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP33]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 1 diff --git a/clang/test/OpenMP/taskloop_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_reduction_codegen.cpp index 3cdc88ba20b77..6eca033eca551 100644 --- a/clang/test/OpenMP/taskloop_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_reduction_codegen.cpp @@ -83,9 +83,9 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB1:.+]], ptr [[TMP25]], // CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK-DAG: call void @llvm.memset.p0.i64(ptr align 8 [[TMP26]], i8 0, i64 4, i1 false) -// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 0 +// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 0 // CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, % -// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] +// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], // CHECK-DAG: [[TMP28]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0 // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], @@ -137,10 +137,10 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB4:.+]], ptr [[TMP59]], // CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_8]], i32 0, i32 6 // CHECK-DAG: store i32 1, ptr [[TMP60]], -// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 // CHECK: [[TMP62:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 4, ptr [[DOTRD_INPUT_]]) // CHECK: [[TMP63:%.*]] = load i32, ptr [[N]], // CHECK: store i32 [[TMP63]], ptr [[DOTCAPTURE_EXPR_]], diff --git a/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp index 6da28d2d973c9..9e4e51a442742 100644 --- a/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp @@ -76,7 +76,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[VLA:%.*]] = alloca i16, i64 [[TMP2]], align 16 // CHECK1-NEXT: store i64 [[TMP2]], ptr [[__VLA_EXPR0]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[A]], ptr [[TMP4]], align 8 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -91,7 +91,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP9]], align 8 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP10]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_1:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[B]], ptr [[TMP11]], align 8 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 1 @@ -106,7 +106,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..2, ptr [[TMP16]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_1]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP17]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_2:%.*]] = getelementptr inbounds nuw [3 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 2 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC_ADDR]], ptr [[TMP18]], align 8 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_2]], i32 0, i32 1 @@ -124,7 +124,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP25:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 3, ptr [[DOTRD_INPUT_]]) // CHECK1-NEXT: store ptr [[TMP25]], ptr [[DOTTASK_RED_]], align 8 // CHECK1-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_4:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[C]], ptr [[TMP26]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 1 @@ -139,7 +139,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..6, ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_4]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP32]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_5:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_3]], i64 0, i64 1 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP33]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_5]], i32 0, i32 1 diff --git a/clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp index d6e40831484aa..83ae053cfd9bd 100644 --- a/clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp @@ -80,9 +80,9 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB1:.+]], ptr [[TMP25]], // CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK-DAG: call void @llvm.memset.p0.i64(ptr align 8 [[TMP26]], i8 0, i64 4, i1 false) -// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 0 +// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 0 // CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, % -// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] +// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [100 x %struct.S], ptr [[C]], i64 0, i64 [[LB_ADD_LEN]] // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], // CHECK-DAG: [[TMP28]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0 // CHECK-DAG: store ptr [[ARRAYIDX5]], ptr [[TMP28:%[^,]+]], @@ -134,10 +134,10 @@ sum = 0.0; // CHECK-DAG: store ptr @[[RED_COMB4:.+]], ptr [[TMP59]], // CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds nuw %struct.kmp_taskred_input_t, ptr [[DOTRD_INPUT_GEP_8]], i32 0, i32 6 // CHECK-DAG: store i32 1, ptr [[TMP60]], -// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 -// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 +// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds nuw [4 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 // CHECK: [[TMP62:%.*]] = call ptr @__kmpc_taskred_init(i32 [[TMP0]], i32 4, ptr [[DOTRD_INPUT_]]) // CHECK: [[TMP63:%.*]] = load i32, ptr [[N]], // CHECK: store i32 [[TMP63]], ptr [[DOTCAPTURE_EXPR_]], diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp index be499e0b36548..7987c2de7dd8f 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp @@ -100,16 +100,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP1]], i64 0 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP4]] // CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP5]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP5]], i64 9 // CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]] @@ -139,7 +139,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP20]] // CHECK1-NEXT: store ptr [[_TMP5]], ptr [[TMP]], align 8 // CHECK1-NEXT: store ptr [[TMP21]], ptr [[_TMP5]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP22]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -154,19 +154,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb., ptr [[TMP27]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_6:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP30]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP30]], i64 0 // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[ARRAYIDX7]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[TMP31]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP31]], i64 0 // CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = sext i32 [[TMP32]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN9:%.*]] = add nsw i64 -1, [[TMP33]] // CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds ptr, ptr [[TMP34]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP34]], i64 9 // CHECK1-NEXT: [[TMP35:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP35]], i64 [[LB_ADD_LEN9]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T]], ptr [[DOTRD_INPUT_GEP_6]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[TMP36]], align 8 @@ -444,16 +444,16 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: store i32 0, ptr [[ARGC1]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP3]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP4]], i64 0 // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP6]] // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds ptr, ptr [[TMP7]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP7]], i64 9 // CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i64 [[LB_ADD_LEN]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP8]], i64 [[LB_ADD_LEN]] // CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX4]] to i64 // CHECK1-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64 // CHECK1-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]] @@ -483,7 +483,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr i8, ptr [[VLA]], i64 [[TMP22]] // CHECK1-NEXT: store ptr [[_TMP6]], ptr [[_TMP5]], align 8 // CHECK1-NEXT: store ptr [[TMP23]], ptr [[_TMP6]], align 8 -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 0 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0:%.*]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 0 // CHECK1-NEXT: store ptr [[ARGC1]], ptr [[TMP24]], align 8 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 1 @@ -498,19 +498,19 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store ptr @.red_comb..4, ptr [[TMP29]], align 8 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_]], i32 0, i32 6 // CHECK1-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP30]], i8 0, i64 4, i1 false) -// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 1 +// CHECK1-NEXT: [[DOTRD_INPUT_GEP_7:%.*]] = getelementptr inbounds nuw [2 x %struct.kmp_taskred_input_t.0], ptr [[DOTRD_INPUT_]], i64 0, i64 1 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 0 // CHECK1-NEXT: [[TMP32:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds ptr, ptr [[TMP32]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP32]], i64 0 // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[ARRAYIDX8]], align 8 -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i8, ptr [[TMP33]], i64 0 +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP33]], i64 0 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP35:%.*]] = sext i32 [[TMP34]] to i64 // CHECK1-NEXT: [[LB_ADD_LEN10:%.*]] = add nsw i64 -1, [[TMP35]] // CHECK1-NEXT: [[TMP36:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds ptr, ptr [[TMP36]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP36]], i64 9 // CHECK1-NEXT: [[TMP37:%.*]] = load ptr, ptr [[ARRAYIDX11]], align 8 -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds i8, ptr [[TMP37]], i64 [[LB_ADD_LEN10]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP37]], i64 [[LB_ADD_LEN10]] // CHECK1-NEXT: store ptr [[VLA]], ptr [[TMP31]], align 8 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASKRED_INPUT_T_0]], ptr [[DOTRD_INPUT_GEP_7]], i32 0, i32 1 // CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[TMP38]], align 8 @@ -831,9 +831,9 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP24]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP25]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds ptr, ptr [[TMP26]], i64 9 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds nuw ptr, ptr [[TMP26]], i64 9 // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP27]], i64 [[LB_ADD_LEN_I]] // CHECK1-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX3_I]] to i64 // CHECK1-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] diff --git a/clang/test/Parser/cxx11-user-defined-literals.cpp b/clang/test/Parser/cxx11-user-defined-literals.cpp index 1a7e780588229..cdd06729efc39 100644 --- a/clang/test/Parser/cxx11-user-defined-literals.cpp +++ b/clang/test/Parser/cxx11-user-defined-literals.cpp @@ -21,7 +21,8 @@ int f() { asm("mov %eax, %rdx"_foo); // expected-error {{user-defined suffix cannot be used here}} } -static_assert(true, "foo"_bar); // expected-error {{user-defined suffix cannot be used here}} +static_assert(true, "foo"_bar); // expected-error {{no matching literal operator for call to 'operator""_bar'}} +// expected-warning@-1 {{'static_assert' with a user-generated message is a C++26 extension}} int cake() __attribute__((availability(macosx, unavailable, message = "is a lie"_x))); // expected-error {{user-defined suffix cannot be used here}} diff --git a/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl b/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl index 29850828ad3bc..24c85c6ccf7d7 100644 --- a/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl +++ b/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl @@ -1,9 +1,16 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s - -// CHECK: -HLSLROVAttr 0x{{[0-9a-f]+}} -struct [[hlsl::is_rov]] Eg1 { - int i; +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} struct MyBuffer definition +// CHECK: FieldDecl 0x{{[0-9a-f]+}} col:68 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov()]]':'__hlsl_resource_t' +struct MyBuffer { + __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov]] h; }; -Eg1 e1; +// CHECK: VarDecl 0x{{[0-9a-f]+}} col:66 res '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]] {{\[\[}}hlsl::is_rov()]]':'__hlsl_resource_t' +__hlsl_resource_t [[hlsl::is_rov]] [[hlsl::resource_class(SRV)]] res; + +// CHECK: FunctionDecl 0x{{[0-9a-f]+}} line:14:6 f 'void () +// CHECK: VarDecl 0x{{[0-9a-f]+}} col:72 r '__hlsl_resource_t {{\[\[}}hlsl::resource_class(Sampler)]] {{\[\[}}hlsl::is_rov()]]':'__hlsl_resource_t' +void f() { + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] [[hlsl::is_rov]] r; +} diff --git a/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl index a21fed22220b6..68b2d9ecb190a 100644 --- a/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl +++ b/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl @@ -1,15 +1,16 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s -verify +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify -// expected-error@+1{{'is_rov' attribute takes no arguments}} -struct [[hlsl::is_rov(3)]] Eg1 { - int i; -}; +// expected-error@+1{{'is_rov' attribute cannot be applied to a declaration}} +[[hlsl::is_rov()]] __hlsl_resource_t res0; -Eg1 e1; +// expected-error@+1{{HLSL resource needs to have [[hlsl::resource_class()]] attribute}} +__hlsl_resource_t [[hlsl::is_rov()]] res1; +// expected-error@+1{{'is_rov' attribute takes no arguments}} +__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov(3)]] res2; + // expected-error@+1{{use of undeclared identifier 'gibberish'}} -struct [[hlsl::is_rov(gibberish)]] Eg2 { - int i; -}; +__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov(gibberish)]] res3; -Eg2 e2; +// duplicate attribute with the same meaning - no error +__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov()]] [[hlsl::is_rov()]] res4; diff --git a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl index 4b002e2d89009..f11a64d33839b 100644 --- a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl @@ -1,32 +1,32 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s - -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} SRV -struct Eg1 { - [[hlsl::resource_class(SRV)]] int i; +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} struct MyBuffer definition +// CHECK: FieldDecl 0x{{[0-9a-f]+}} col:51 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]]':'__hlsl_resource_t' +struct MyBuffer { + __hlsl_resource_t [[hlsl::resource_class(UAV)]] h; }; -Eg1 e1; - -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} line:13:8 referenced struct Eg2 definition -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} UAV -struct Eg2 { - [[hlsl::resource_class(UAV)]] int i; -}; -Eg2 e2; +// CHECK: VarDecl 0x{{[0-9a-f]+}} col:49 res '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]]':'__hlsl_resource_t' +__hlsl_resource_t [[hlsl::resource_class(SRV)]] res; -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} line:20:8 referenced struct Eg3 definition -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} CBuffer -struct Eg3 { - [[hlsl::resource_class(CBuffer)]] int i; -}; -Eg3 e3; +// CHECK: FunctionDecl 0x{{[0-9a-f]+}} line:14:6 f 'void () +// CHECK: VarDecl 0x{{[0-9a-f]+}} col:55 r '__hlsl_resource_t {{\[\[}}hlsl::resource_class(Sampler)]]':'__hlsl_resource_t' +void f() { + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] r; +} -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} line:27:8 referenced struct Eg4 definition -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} Sampler -struct Eg4 { - [[hlsl::resource_class(Sampler)]] int i; +// CHECK: ClassTemplateDecl 0x{{[0-9a-f]+}} line:23:29 MyBuffer2 +// CHECK: TemplateTypeParmDecl 0x{{[0-9a-f]+}} col:19 typename depth 0 index 0 T +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} line:23:29 struct MyBuffer2 definition +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} col:29 implicit struct MyBuffer2 +// CHECK: FieldDecl 0x{{[0-9a-f]+}} col:51 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]]':'__hlsl_resource_t' +template struct MyBuffer2 { + __hlsl_resource_t [[hlsl::resource_class(UAV)]] h; }; -Eg4 e4; -RWBuffer In : register(u1); +// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} line:23:29 struct MyBuffer2 definition implicit_instantiation +// CHECK: TemplateArgument type 'float' +// CHECK: BuiltinType 0x{{[0-9a-f]+}} 'float' +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} col:29 implicit struct MyBuffer2 +// CHECK: FieldDecl 0x{{[0-9a-f]+}} col:51 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]]':'__hlsl_resource_t' +MyBuffer2 myBuffer2; diff --git a/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl index 76bed2f060783..01ff1c007e2b5 100644 --- a/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl @@ -1,22 +1,19 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s -verify +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify -struct Eg1 { -// expected-error@+1{{'resource_class' attribute takes one argument}} - [[hlsl::resource_class()]] int i; -}; +// expected-error@+1{{'resource_class' attribute cannot be applied to a declaration}} +[[hlsl::resource_class(UAV)]] __hlsl_resource_t e0; -Eg1 e1; +// expected-error@+1{{'resource_class' attribute takes one argument}} +__hlsl_resource_t [[hlsl::resource_class()]] e1; -struct Eg2 { // expected-warning@+1{{ResourceClass attribute argument not supported: gibberish}} - [[hlsl::resource_class(gibberish)]] int i; -}; +__hlsl_resource_t [[hlsl::resource_class(gibberish)]] e2; -Eg2 e2; +// expected-warning@+1{{attribute 'resource_class' is already applied with different arguments}} +__hlsl_resource_t [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(UAV)]] e3; -// expected-warning@+1{{'resource_class' attribute only applies to non-static data members}} -struct [[hlsl::resource_class(SRV)]] Eg3 { - int i; -}; +// expected-warning@+1{{attribute 'resource_class' is already applied}} +__hlsl_resource_t [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(SRV)]] e4; -Eg3 e3; +// expected-error@+1{{'resource_class' attribute takes one argument}} +__hlsl_resource_t [[hlsl::resource_class(SRV, "aa")]] e5; diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl index 320d1160e761d..6324a11fc8a2d 100644 --- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl @@ -1,15 +1,16 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s | FileCheck %s // CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <> class RWBuffer definition implicit_instantiation -// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <> implicit referenced h 'float *' -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <> Implicit UAV +// CHECK: -TemplateArgument type 'float' +// CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float' +// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *' // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <> Implicit TypedBuffer RWBuffer Buffer1; -// CHECK: -ClassTemplateDecl 0x{{[0-9a-f]+}} <> implicit RasterizerOrderedBuffer -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} <> implicit class RasterizerOrderedBuffer definition -// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <> implicit h 'element_type *' -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <> Implicit UAV +// CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <> class RasterizerOrderedBuffer definition implicit_instantiation +// CHECK: -TemplateArgument type 'vector' +// CHECK: `-ExtVectorType 0x{{[0-9a-f]+}} 'vector' 4 +// CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float' +// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <> implicit referenced h 'vector {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov()]]':'vector' // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <> Implicit TypedBuffer -// CHECK: -HLSLROVAttr 0x{{[0-9a-f]+}} <> Implicit -RasterizerOrderedBuffer > BufferArray3[4] : register(u4, space1); +RasterizerOrderedBuffer > BufferArray3[4]; diff --git a/clang/test/Preprocessor/init-ppc.c b/clang/test/Preprocessor/init-ppc.c index 3fb642af9d742..1421b102a3dfd 100644 --- a/clang/test/Preprocessor/init-ppc.c +++ b/clang/test/Preprocessor/init-ppc.c @@ -977,3 +977,21 @@ // RUN: %clang_cc1 -E -dM -triple=powerpc-unknown-openbsd -x c++ < /dev/null | FileCheck -match-full-lines -check-prefix PPC-OPENBSD-CXX %s // PPC-OPENBSD-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL + +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-none-none < /dev/null | FileCheck -match-full-lines -check-prefix PPCPWR4-RSQRT %s +// +// PPCPWR4-RSQRT-NOT:#define __RSQRTEF__ 1 +// PPCPWR4-RSQRT-NOT:#define __RSQRTE__ 1 +// +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-none-none -target-feature +frsqrte -target-feature +frsqrtes < /dev/null | FileCheck -match-full-lines -check-prefix PPCPWR5-RSQRT %s +// +// PPCPWR5-RSQRT:#define __RSQRTEF__ 1 +// PPCPWR5-RSQRT:#define __RSQRTE__ 1 + +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-unknown-linux-gnu -target-feature -hard-float < /dev/null | FileCheck -match-full-lines -check-prefix PPC-SOFTFLT %s +// +// PPC-SOFTFLT:#define _SOFT_DOUBLE 1 +// PPC-SOFTFLT:#define _SOFT_FLOAT 1 +// PPC-SOFTFLT:#define __NO_FPRS__ 1 +// PPC-SOFTFLT-NOT:#define __RSQRTE__ 1 +// PPC-SOFTFLT-NOT:#define __RSQRTEF__ 1 diff --git a/clang/test/Preprocessor/init-ppc64.c b/clang/test/Preprocessor/init-ppc64.c index 56164beb913d5..57e2ca31d5d53 100644 --- a/clang/test/Preprocessor/init-ppc64.c +++ b/clang/test/Preprocessor/init-ppc64.c @@ -1110,3 +1110,21 @@ // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-freebsd < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-FREEBSD %s // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64le-unknown-freebsd < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-FREEBSD %s // PPC64-FREEBSD-NOT: #define __LONG_DOUBLE_128__ 1 + +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none < /dev/null | FileCheck -match-full-lines -check-prefix PPC64PWR4-RSQRT %s +// +// PPC64PWR4-RSQRT-NOT:#define __RSQRTEF__ 1 +// PPC64PWR4-RSQRT-NOT:#define __RSQRTE__ 1 +// +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +frsqrte -target-feature +frsqrtes < /dev/null | FileCheck -match-full-lines -check-prefix PPC64PWR5-RSQRT %s +// +// PPC64PWR5-RSQRT:#define __RSQRTEF__ 1 +// PPC64PWR5-RSQRT:#define __RSQRTE__ 1 + +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -target-feature -hard-float -xc /dev/null | FileCheck --check-prefix=PPC64-SOFTFLT %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64le-unknown-linux-gnu -target-feature -hard-float -xc /dev/null | FileCheck --check-prefix=PPC64-SOFTFLT %s +// PPC64-SOFTFLT:#define _SOFT_DOUBLE 1 +// PPC64-SOFTFLT:#define _SOFT_FLOAT 1 +// PPC64-SOFTFLT:#define __NO_FPRS__ 1 +// PPC64-SOFTFLT-NOT:#define __RSQRTE__ 1 +// PPC64-SOFTFLT-NOT:#define __RSQRTEF__ 1 diff --git a/clang/test/Sema/aarch64-neon-bf16-ranges.c b/clang/test/Sema/aarch64-neon-bf16-ranges.c deleted file mode 100644 index 88e6c50c59382..0000000000000 --- a/clang/test/Sema/aarch64-neon-bf16-ranges.c +++ /dev/null @@ -1,49 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify \ -// RUN: -triple aarch64 -target-feature +neon \ -// RUN: -target-feature +bf16 %s - -// REQUIRES: aarch64-registered-target || arm-registered-target - -#include - -int x; - -void test_vcopy_lane_bf16(bfloat16x4_t a, bfloat16x8_t b) { - // 0 <= lane1 <= 3; 0 <= lane2 <= 3 - (void)vcopy_lane_bf16(a, 3, a, 3); - (void)vcopy_lane_bf16(a, 0, a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - (void)vcopy_lane_bf16(a, 1, a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - (void)vcopy_lane_bf16(a, 4, a, 0); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - (void)vcopy_lane_bf16(a, -1, a, 1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - (void)vcopy_lane_bf16(a, 0, a, x); // expected-error-re {{argument {{.*}} must be a constant integer}} - (void)vcopy_lane_bf16(a, x, a, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} - - // 0 <= lane1 <= 7; 0 <= lane2 <= 3 - (void)vcopyq_lane_bf16(b, 7, a, 3); - (void)vcopyq_lane_bf16(b, 0, a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - (void)vcopyq_lane_bf16(b, 1, a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - (void)vcopyq_lane_bf16(b, 8, a, 0); // expected-error {{argument value 8 is outside the valid range [0, 7]}} - (void)vcopyq_lane_bf16(b, -1, a, 1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} - (void)vcopyq_lane_bf16(b, 0, a, x); // expected-error-re {{argument {{.*}} must be a constant integer}} - (void)vcopyq_lane_bf16(b, x, a, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} - - // 0 <= lane1 <= 3; 0 <= lane2 <= 7 - (void)vcopy_laneq_bf16(a, 3, b, 7); - (void)vcopy_laneq_bf16(a, 0, b, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} - (void)vcopy_laneq_bf16(a, 1, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} - (void)vcopy_laneq_bf16(a, 4, b, 0); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - (void)vcopy_laneq_bf16(a, -1, b, 1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - (void)vcopy_laneq_bf16(a, 0, b, x); // expected-error-re {{argument {{.*}} must be a constant integer}} - (void)vcopy_laneq_bf16(a, x, b, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} - - - // 0 <= lane1 <= 7; 0 <= lane2 <= 7 - (void)vcopyq_laneq_bf16(b, 7, b, 7); - (void)vcopyq_laneq_bf16(b, 0, b, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} - (void)vcopyq_laneq_bf16(b, 1, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} - (void)vcopyq_laneq_bf16(b, 8, b, 0); // expected-error {{argument value 8 is outside the valid range [0, 7]}} - (void)vcopyq_laneq_bf16(b, -1, b, 1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} - (void)vcopyq_laneq_bf16(b, 0, b, x); // expected-error-re {{argument {{.*}} must be a constant integer}} - (void)vcopyq_laneq_bf16(b, x, b, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} -} - diff --git a/clang/test/Sema/aarch64-neon-fp16-ranges.c b/clang/test/Sema/aarch64-neon-fp16-ranges.c deleted file mode 100644 index cb273eb56160b..0000000000000 --- a/clang/test/Sema/aarch64-neon-fp16-ranges.c +++ /dev/null @@ -1,66 +0,0 @@ -// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -target-feature +fullfp16 -ffreestanding -fsyntax-only -verify %s -// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +fullfp16 -target-feature +neon -ffreestanding -fsyntax-only -verify %s - -// REQUIRES: aarch64-registered-target || arm-registered-target - -#include -#include - -void test_vcvt_f16_16(int16_t a){ - vcvth_n_f16_s16(a, 1); - vcvth_n_f16_s16(a, 16); - vcvth_n_f16_s16(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_f16_s16(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vcvth_n_f16_u16(a, 1); - vcvth_n_f16_u16(a, 16); - vcvth_n_f16_u16(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_f16_u16(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - -void test_vcvt_f16_32(int32_t a){ - vcvth_n_f16_u32(a, 1); - vcvth_n_f16_u32(a, 16); - vcvth_n_f16_u32(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_f16_u32(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vcvth_n_f16_s32(a, 1); - vcvth_n_f16_s32(a, 16); - vcvth_n_f16_s32(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_f16_s32(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - -void test_vcvt_f16_64(int64_t a){ - vcvth_n_f16_s64(a, 1); - vcvth_n_f16_s64(a, 16); - vcvth_n_f16_s64(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_f16_s64(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - - -void test_vcvt_su_f(float16_t a){ - vcvth_n_s16_f16(a, 1); - vcvth_n_s16_f16(a, 16); - vcvth_n_s16_f16(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_s16_f16(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vcvth_n_s32_f16(a, 1); - vcvth_n_s32_f16(a, 16); - vcvth_n_s32_f16(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_s32_f16(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vcvth_n_s64_f16(a, 1); - vcvth_n_s64_f16(a, 16); - vcvth_n_s64_f16(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_s64_f16(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vcvth_n_u16_f16(a, 1); - vcvth_n_u16_f16(a, 16); - vcvth_n_u16_f16(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_u16_f16(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vcvth_n_u32_f16(a, 1); - vcvth_n_u32_f16(a, 16); - vcvth_n_u32_f16(a, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vcvth_n_u32_f16(a, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/bfloat16.c b/clang/test/Sema/aarch64-neon-immediate-ranges/bfloat16.c new file mode 100644 index 0000000000000..485219a9f8978 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/bfloat16.c @@ -0,0 +1,237 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +bf16 -ffreestanding -fsyntax-only -verify %s + +#include +#include +// REQUIRES: aarch64-registered-target + + +void test_set_all_lanes_to_the_same_value_bf16(bfloat16x8_t arg_b16x8, bfloat16x4_t arg_b16x4) { + vdup_lane_bf16(arg_b16x4, 0); + vdup_lane_bf16(arg_b16x4, 3); + vdup_lane_bf16(arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_bf16(arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_bf16(arg_b16x4, 0); + vdupq_lane_bf16(arg_b16x4, 3); + vdupq_lane_bf16(arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_bf16(arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_bf16(arg_b16x8, 0); + vdup_laneq_bf16(arg_b16x8, 7); + vdup_laneq_bf16(arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_bf16(arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_bf16(arg_b16x8, 0); + vdupq_laneq_bf16(arg_b16x8, 7); + vdupq_laneq_bf16(arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_bf16(arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vduph_lane_bf16(arg_b16x4, 0); + vduph_lane_bf16(arg_b16x4, 3); + vduph_lane_bf16(arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_lane_bf16(arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vduph_laneq_bf16(arg_b16x8, 0); + vduph_laneq_bf16(arg_b16x8, 7); + vduph_laneq_bf16(arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_laneq_bf16(arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_split_vectors_bf16(bfloat16x8_t arg_b16x8, bfloat16x4_t arg_b16x4) { + vget_lane_bf16(arg_b16x4, 0); + vget_lane_bf16(arg_b16x4, 3); + vget_lane_bf16(arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_bf16(arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_bf16(arg_b16x8, 0); + vgetq_lane_bf16(arg_b16x8, 7); + vgetq_lane_bf16(arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_bf16(arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_bf16(bfloat16x8_t arg_b16x8, bfloat16x4_t arg_b16x4, bfloat16_t arg_b16) { + vset_lane_bf16(arg_b16, arg_b16x4, 0); + vset_lane_bf16(arg_b16, arg_b16x4, 3); + vset_lane_bf16(arg_b16, arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_bf16(arg_b16, arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_bf16(arg_b16, arg_b16x8, 0); + vsetq_lane_bf16(arg_b16, arg_b16x8, 7); + vsetq_lane_bf16(arg_b16, arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_bf16(arg_b16, arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_bf16(bfloat16x8_t arg_b16x8, bfloat16x4_t arg_b16x4) { + vcopy_lane_bf16(arg_b16x4, 0, arg_b16x4, 0); + vcopy_lane_bf16(arg_b16x4, 3, arg_b16x4, 0); + vcopy_lane_bf16(arg_b16x4, -1, arg_b16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_bf16(arg_b16x4, 4, arg_b16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_bf16(arg_b16x4, 0, arg_b16x4, 3); + vcopy_lane_bf16(arg_b16x4, 0, arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_bf16(arg_b16x4, 0, arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_bf16(arg_b16x8, 0, arg_b16x4, 0); + vcopyq_lane_bf16(arg_b16x8, 7, arg_b16x4, 0); + vcopyq_lane_bf16(arg_b16x8, -1, arg_b16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_bf16(arg_b16x8, 8, arg_b16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_bf16(arg_b16x8, 0, arg_b16x4, 3); + vcopyq_lane_bf16(arg_b16x8, 0, arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_bf16(arg_b16x8, 0, arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_bf16(arg_b16x4, 0, arg_b16x8, 0); + vcopy_laneq_bf16(arg_b16x4, 3, arg_b16x8, 0); + vcopy_laneq_bf16(arg_b16x4, -1, arg_b16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_bf16(arg_b16x4, 4, arg_b16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_bf16(arg_b16x4, 0, arg_b16x8, 7); + vcopy_laneq_bf16(arg_b16x4, 0, arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_bf16(arg_b16x4, 0, arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_bf16(arg_b16x8, 0, arg_b16x8, 0); + vcopyq_laneq_bf16(arg_b16x8, 7, arg_b16x8, 0); + vcopyq_laneq_bf16(arg_b16x8, -1, arg_b16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_bf16(arg_b16x8, 8, arg_b16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_bf16(arg_b16x8, 0, arg_b16x8, 7); + vcopyq_laneq_bf16(arg_b16x8, 0, arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_bf16(arg_b16x8, 0, arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_load_bf16(bfloat16x4_t arg_b16x4, bfloat16x4x4_t arg_b16x4x4, bfloat16x8x4_t arg_b16x8x4, + bfloat16x4x3_t arg_b16x4x3, bfloat16x8_t arg_b16x8, bfloat16_t* arg_b16_ptr, + bfloat16x8x3_t arg_b16x8x3, bfloat16x4x2_t arg_b16x4x2, bfloat16x8x2_t arg_b16x8x2) { + vld1_lane_bf16(arg_b16_ptr, arg_b16x4, 0); + vld1_lane_bf16(arg_b16_ptr, arg_b16x4, 3); + vld1_lane_bf16(arg_b16_ptr, arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_bf16(arg_b16_ptr, arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_bf16(arg_b16_ptr, arg_b16x8, 0); + vld1q_lane_bf16(arg_b16_ptr, arg_b16x8, 7); + vld1q_lane_bf16(arg_b16_ptr, arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_bf16(arg_b16_ptr, arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_bf16(arg_b16_ptr, arg_b16x4x2, 0); + vld2_lane_bf16(arg_b16_ptr, arg_b16x4x2, 3); + vld2_lane_bf16(arg_b16_ptr, arg_b16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_bf16(arg_b16_ptr, arg_b16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, 0); + vld2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, 7); + vld2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_bf16(arg_b16_ptr, arg_b16x4x3, 0); + vld3_lane_bf16(arg_b16_ptr, arg_b16x4x3, 3); + vld3_lane_bf16(arg_b16_ptr, arg_b16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_bf16(arg_b16_ptr, arg_b16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, 0); + vld3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, 7); + vld3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_bf16(arg_b16_ptr, arg_b16x4x4, 0); + vld4_lane_bf16(arg_b16_ptr, arg_b16x4x4, 3); + vld4_lane_bf16(arg_b16_ptr, arg_b16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_bf16(arg_b16_ptr, arg_b16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, 0); + vld4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, 7); + vld4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_store_bf16(bfloat16x4_t arg_b16x4, bfloat16x4x4_t arg_b16x4x4, bfloat16x8x4_t arg_b16x8x4, + bfloat16x4x3_t arg_b16x4x3, bfloat16x8_t arg_b16x8, bfloat16_t* arg_b16_ptr, + bfloat16x8x3_t arg_b16x8x3, bfloat16x4x2_t arg_b16x4x2, bfloat16x8x2_t arg_b16x8x2) { + vst1_lane_bf16(arg_b16_ptr, arg_b16x4, 0); + vst1_lane_bf16(arg_b16_ptr, arg_b16x4, 3); + vst1_lane_bf16(arg_b16_ptr, arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_bf16(arg_b16_ptr, arg_b16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_bf16(arg_b16_ptr, arg_b16x8, 0); + vst1q_lane_bf16(arg_b16_ptr, arg_b16x8, 7); + vst1q_lane_bf16(arg_b16_ptr, arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_bf16(arg_b16_ptr, arg_b16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_bf16(arg_b16_ptr, arg_b16x4x2, 0); + vst2_lane_bf16(arg_b16_ptr, arg_b16x4x2, 3); + vst2_lane_bf16(arg_b16_ptr, arg_b16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_bf16(arg_b16_ptr, arg_b16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, 0); + vst2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, 7); + vst2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_bf16(arg_b16_ptr, arg_b16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_bf16(arg_b16_ptr, arg_b16x4x3, 0); + vst3_lane_bf16(arg_b16_ptr, arg_b16x4x3, 3); + vst3_lane_bf16(arg_b16_ptr, arg_b16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_bf16(arg_b16_ptr, arg_b16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, 0); + vst3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, 7); + vst3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_bf16(arg_b16_ptr, arg_b16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_bf16(arg_b16_ptr, arg_b16x4x4, 0); + vst4_lane_bf16(arg_b16_ptr, arg_b16x4x4, 3); + vst4_lane_bf16(arg_b16_ptr, arg_b16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_bf16(arg_b16_ptr, arg_b16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, 0); + vst4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, 7); + vst4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_bf16(arg_b16_ptr, arg_b16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_dot_product_f32(bfloat16x8_t arg_b16x8, bfloat16x4_t arg_b16x4, float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vbfdot_lane_f32(arg_f32x2, arg_b16x4, arg_b16x4, 0); + vbfdot_lane_f32(arg_f32x2, arg_b16x4, arg_b16x4, 1); + vbfdot_lane_f32(arg_f32x2, arg_b16x4, arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vbfdot_lane_f32(arg_f32x2, arg_b16x4, arg_b16x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vbfdotq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 0); + vbfdotq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 3); + vbfdotq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vbfdotq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vbfdot_laneq_f32(arg_f32x2, arg_b16x4, arg_b16x8, 0); + vbfdot_laneq_f32(arg_f32x2, arg_b16x4, arg_b16x8, 3); + vbfdot_laneq_f32(arg_f32x2, arg_b16x4, arg_b16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vbfdot_laneq_f32(arg_f32x2, arg_b16x4, arg_b16x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vbfdotq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 0); + vbfdotq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 1); + vbfdotq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vbfdotq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_accumulate_by_scalar_f32(bfloat16x8_t arg_b16x8, bfloat16x4_t arg_b16x4, float32x4_t arg_f32x4) { + vbfmlalbq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 0); + vbfmlalbq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 3); + vbfmlalbq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vbfmlalbq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vbfmlalbq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 0); + vbfmlalbq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 7); + vbfmlalbq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vbfmlalbq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vbfmlaltq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 0); + vbfmlaltq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 3); + vbfmlaltq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vbfmlaltq_lane_f32(arg_f32x4, arg_b16x8, arg_b16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vbfmlaltq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 0); + vbfmlaltq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 7); + vbfmlaltq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vbfmlaltq_laneq_f32(arg_f32x4, arg_b16x8, arg_b16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/conversions.c b/clang/test/Sema/aarch64-neon-immediate-ranges/conversions.c new file mode 100644 index 0000000000000..30ae7f7392422 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/conversions.c @@ -0,0 +1,144 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_conversions_f32(float32_t arg_f32, float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vcvt_n_s32_f32(arg_f32x2, 1); + vcvt_n_s32_f32(arg_f32x2, 32); + vcvt_n_s32_f32(arg_f32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_s32_f32(arg_f32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_s32_f32(arg_f32x4, 1); + vcvtq_n_s32_f32(arg_f32x4, 32); + vcvtq_n_s32_f32(arg_f32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_s32_f32(arg_f32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvt_n_u32_f32(arg_f32x2, 1); + vcvt_n_u32_f32(arg_f32x2, 32); + vcvt_n_u32_f32(arg_f32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_u32_f32(arg_f32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_u32_f32(arg_f32x4, 1); + vcvtq_n_u32_f32(arg_f32x4, 32); + vcvtq_n_u32_f32(arg_f32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_u32_f32(arg_f32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvts_n_s32_f32(arg_f32, 1); + vcvts_n_s32_f32(arg_f32, 32); + vcvts_n_s32_f32(arg_f32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvts_n_s32_f32(arg_f32, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvts_n_u32_f32(arg_f32, 1); + vcvts_n_u32_f32(arg_f32, 32); + vcvts_n_u32_f32(arg_f32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvts_n_u32_f32(arg_f32, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_f64(float64x1_t arg_f64x1, float64x2_t arg_f64x2, float64_t arg_f64) { + vcvt_n_s64_f64(arg_f64x1, 1); + vcvt_n_s64_f64(arg_f64x1, 64); + vcvt_n_s64_f64(arg_f64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_s64_f64(arg_f64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_s64_f64(arg_f64x2, 1); + vcvtq_n_s64_f64(arg_f64x2, 64); + vcvtq_n_s64_f64(arg_f64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_s64_f64(arg_f64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvt_n_u64_f64(arg_f64x1, 1); + vcvt_n_u64_f64(arg_f64x1, 64); + vcvt_n_u64_f64(arg_f64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_u64_f64(arg_f64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_u64_f64(arg_f64x2, 1); + vcvtq_n_u64_f64(arg_f64x2, 64); + vcvtq_n_u64_f64(arg_f64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_u64_f64(arg_f64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtd_n_s64_f64(arg_f64, 1); + vcvtd_n_s64_f64(arg_f64, 64); + vcvtd_n_s64_f64(arg_f64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtd_n_s64_f64(arg_f64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtd_n_u64_f64(arg_f64, 1); + vcvtd_n_u64_f64(arg_f64, 64); + vcvtd_n_u64_f64(arg_f64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtd_n_u64_f64(arg_f64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_s32(int32_t arg_i32, int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vcvt_n_f32_s32(arg_i32x2, 1); + vcvt_n_f32_s32(arg_i32x2, 32); + vcvt_n_f32_s32(arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_f32_s32(arg_i32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_f32_s32(arg_i32x4, 1); + vcvtq_n_f32_s32(arg_i32x4, 32); + vcvtq_n_f32_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_f32_s32(arg_i32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvts_n_f32_s32(arg_i32, 1); + vcvts_n_f32_s32(arg_i32, 32); + vcvts_n_f32_s32(arg_i32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvts_n_f32_s32(arg_i32, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_u32(uint32x4_t arg_u32x4, uint32x2_t arg_u32x2, uint32_t arg_u32) { + vcvt_n_f32_u32(arg_u32x2, 1); + vcvt_n_f32_u32(arg_u32x2, 32); + vcvt_n_f32_u32(arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_f32_u32(arg_u32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_f32_u32(arg_u32x4, 1); + vcvtq_n_f32_u32(arg_u32x4, 32); + vcvtq_n_f32_u32(arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_f32_u32(arg_u32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvts_n_f32_u32(arg_u32, 1); + vcvts_n_f32_u32(arg_u32, 32); + vcvts_n_f32_u32(arg_u32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvts_n_f32_u32(arg_u32, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_s64(int64x2_t arg_i64x2, int64x1_t arg_i64x1, int64_t arg_i64) { + vcvt_n_f64_s64(arg_i64x1, 1); + vcvt_n_f64_s64(arg_i64x1, 64); + vcvt_n_f64_s64(arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_f64_s64(arg_i64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_f64_s64(arg_i64x2, 1); + vcvtq_n_f64_s64(arg_i64x2, 64); + vcvtq_n_f64_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_f64_s64(arg_i64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtd_n_f64_s64(arg_i64, 1); + vcvtd_n_f64_s64(arg_i64, 64); + vcvtd_n_f64_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtd_n_f64_s64(arg_i64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_u64(uint64x2_t arg_u64x2, uint64_t arg_u64, uint64x1_t arg_u64x1) { + vcvt_n_f64_u64(arg_u64x1, 1); + vcvt_n_f64_u64(arg_u64x1, 64); + vcvt_n_f64_u64(arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_f64_u64(arg_u64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_f64_u64(arg_u64x2, 1); + vcvtq_n_f64_u64(arg_u64x2, 64); + vcvtq_n_f64_u64(arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_f64_u64(arg_u64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtd_n_f64_u64(arg_u64, 1); + vcvtd_n_f64_u64(arg_u64, 64); + vcvtd_n_f64_u64(arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtd_n_f64_u64(arg_u64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/copy-vector-lane.c b/clang/test/Sema/aarch64-neon-immediate-ranges/copy-vector-lane.c new file mode 100644 index 0000000000000..aafd36d1ccfe6 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/copy-vector-lane.c @@ -0,0 +1,498 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_copy_vector_lane_s8(int8x16_t arg_i8x16, int8x8_t arg_i8x8) { + vcopy_lane_s8(arg_i8x8, 0, arg_i8x8, 0); + + vcopy_lane_s8(arg_i8x8, 7, arg_i8x8, 0); + vcopy_lane_s8(arg_i8x8, -1, arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s8(arg_i8x8, 8, arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_s8(arg_i8x8, 0, arg_i8x8, 7); + vcopy_lane_s8(arg_i8x8, 0, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s8(arg_i8x8, 0, arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s8(arg_i8x16, 0, arg_i8x8, 0); + vcopyq_lane_s8(arg_i8x16, 15, arg_i8x8, 0); + vcopyq_lane_s8(arg_i8x16, -1, arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s8(arg_i8x16, 16, arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s8(arg_i8x16, 0, arg_i8x8, 7); + vcopyq_lane_s8(arg_i8x16, 0, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s8(arg_i8x16, 0, arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s8(arg_i8x8, 0, arg_i8x16, 0); + vcopy_laneq_s8(arg_i8x8, 7, arg_i8x16, 0); + vcopy_laneq_s8(arg_i8x8, -1, arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s8(arg_i8x8, 8, arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s8(arg_i8x8, 0, arg_i8x16, 15); + vcopy_laneq_s8(arg_i8x8, 0, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s8(arg_i8x8, 0, arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s8(arg_i8x16, 0, arg_i8x16, 0); + vcopyq_laneq_s8(arg_i8x16, 15, arg_i8x16, 0); + vcopyq_laneq_s8(arg_i8x16, -1, arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s8(arg_i8x16, 16, arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s8(arg_i8x16, 0, arg_i8x16, 15); + vcopyq_laneq_s8(arg_i8x16, 0, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s8(arg_i8x16, 0, arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vcopy_lane_s16(arg_i16x4, 0, arg_i16x4, 0); + vcopy_lane_s16(arg_i16x4, 3, arg_i16x4, 0); + vcopy_lane_s16(arg_i16x4, -1, arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s16(arg_i16x4, 4, arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_s16(arg_i16x4, 0, arg_i16x4, 3); + vcopy_lane_s16(arg_i16x4, 0, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s16(arg_i16x4, 0, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s16(arg_i16x8, 0, arg_i16x4, 0); + vcopyq_lane_s16(arg_i16x8, 7, arg_i16x4, 0); + vcopyq_lane_s16(arg_i16x8, -1, arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s16(arg_i16x8, 8, arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s16(arg_i16x8, 0, arg_i16x4, 3); + vcopyq_lane_s16(arg_i16x8, 0, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s16(arg_i16x8, 0, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s16(arg_i16x4, 0, arg_i16x8, 0); + vcopy_laneq_s16(arg_i16x4, 3, arg_i16x8, 0); + vcopy_laneq_s16(arg_i16x4, -1, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s16(arg_i16x4, 4, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s16(arg_i16x4, 0, arg_i16x8, 7); + vcopy_laneq_s16(arg_i16x4, 0, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s16(arg_i16x4, 0, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s16(arg_i16x8, 0, arg_i16x8, 0); + vcopyq_laneq_s16(arg_i16x8, 7, arg_i16x8, 0); + vcopyq_laneq_s16(arg_i16x8, -1, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s16(arg_i16x8, 8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s16(arg_i16x8, 0, arg_i16x8, 7); + vcopyq_laneq_s16(arg_i16x8, 0, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s16(arg_i16x8, 0, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vcopy_lane_s32(arg_i32x2, 0, arg_i32x2, 0); + vcopy_lane_s32(arg_i32x2, 1, arg_i32x2, 0); + vcopy_lane_s32(arg_i32x2, -1, arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s32(arg_i32x2, 2, arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_s32(arg_i32x2, 0, arg_i32x2, 1); + vcopy_lane_s32(arg_i32x2, 0, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s32(arg_i32x2, 0, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s32(arg_i32x4, 0, arg_i32x2, 0); + vcopyq_lane_s32(arg_i32x4, 3, arg_i32x2, 0); + vcopyq_lane_s32(arg_i32x4, -1, arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s32(arg_i32x4, 4, arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s32(arg_i32x4, 0, arg_i32x2, 1); + vcopyq_lane_s32(arg_i32x4, 0, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s32(arg_i32x4, 0, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s32(arg_i32x2, 0, arg_i32x4, 0); + vcopy_laneq_s32(arg_i32x2, 1, arg_i32x4, 0); + vcopy_laneq_s32(arg_i32x2, -1, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s32(arg_i32x2, 2, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s32(arg_i32x2, 0, arg_i32x4, 3); + vcopy_laneq_s32(arg_i32x2, 0, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s32(arg_i32x2, 0, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s32(arg_i32x4, 0, arg_i32x4, 0); + vcopyq_laneq_s32(arg_i32x4, 3, arg_i32x4, 0); + vcopyq_laneq_s32(arg_i32x4, -1, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s32(arg_i32x4, 4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s32(arg_i32x4, 0, arg_i32x4, 3); + vcopyq_laneq_s32(arg_i32x4, 0, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s32(arg_i32x4, 0, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_s64(int64x1_t arg_i64x1, int64x2_t arg_i64x2) { + vcopy_lane_s64(arg_i64x1, 0, arg_i64x1, 0); + vcopy_lane_s64(arg_i64x1, -1, arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s64(arg_i64x1, 1, arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s64(arg_i64x1, 0, arg_i64x1, 0); + vcopy_lane_s64(arg_i64x1, 0, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_s64(arg_i64x1, 0, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s64(arg_i64x2, 0, arg_i64x1, 0); + vcopyq_lane_s64(arg_i64x2, 1, arg_i64x1, 0); + vcopyq_lane_s64(arg_i64x2, -1, arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s64(arg_i64x2, 2, arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_s64(arg_i64x2, 0, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_s64(arg_i64x2, 0, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s64(arg_i64x1, 0, arg_i64x2, 0); + vcopy_laneq_s64(arg_i64x1, -1, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s64(arg_i64x1, 1, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_s64(arg_i64x1, 0, arg_i64x2, 1); + vcopy_laneq_s64(arg_i64x1, 0, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_s64(arg_i64x1, 0, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s64(arg_i64x2, 0, arg_i64x2, 0); + vcopyq_laneq_s64(arg_i64x2, 1, arg_i64x2, 0); + vcopyq_laneq_s64(arg_i64x2, -1, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s64(arg_i64x2, 2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_s64(arg_i64x2, 0, arg_i64x2, 1); + vcopyq_laneq_s64(arg_i64x2, 0, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_s64(arg_i64x2, 0, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vcopy_lane_u8(arg_u8x8, 0, arg_u8x8, 0); + vcopy_lane_u8(arg_u8x8, 7, arg_u8x8, 0); + vcopy_lane_u8(arg_u8x8, -1, arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u8(arg_u8x8, 8, arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_u8(arg_u8x8, 0, arg_u8x8, 7); + vcopy_lane_u8(arg_u8x8, 0, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u8(arg_u8x8, 0, arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u8(arg_u8x16, 0, arg_u8x8, 0); + vcopyq_lane_u8(arg_u8x16, 15, arg_u8x8, 0); + vcopyq_lane_u8(arg_u8x16, -1, arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u8(arg_u8x16, 16, arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u8(arg_u8x16, 0, arg_u8x8, 7); + vcopyq_lane_u8(arg_u8x16, 0, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u8(arg_u8x16, 0, arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u8(arg_u8x8, 0, arg_u8x16, 0); + vcopy_laneq_u8(arg_u8x8, 7, arg_u8x16, 0); + vcopy_laneq_u8(arg_u8x8, -1, arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u8(arg_u8x8, 8, arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u8(arg_u8x8, 0, arg_u8x16, 15); + vcopy_laneq_u8(arg_u8x8, 0, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u8(arg_u8x8, 0, arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u8(arg_u8x16, 0, arg_u8x16, 0); + vcopyq_laneq_u8(arg_u8x16, 15, arg_u8x16, 0); + vcopyq_laneq_u8(arg_u8x16, -1, arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u8(arg_u8x16, 16, arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u8(arg_u8x16, 0, arg_u8x16, 15); + vcopyq_laneq_u8(arg_u8x16, 0, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u8(arg_u8x16, 0, arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_u16(uint16x4_t arg_u16x4, uint16x8_t arg_u16x8) { + vcopy_lane_u16(arg_u16x4, 0, arg_u16x4, 0); + vcopy_lane_u16(arg_u16x4, 3, arg_u16x4, 0); + vcopy_lane_u16(arg_u16x4, -1, arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u16(arg_u16x4, 4, arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_u16(arg_u16x4, 0, arg_u16x4, 3); + vcopy_lane_u16(arg_u16x4, 0, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u16(arg_u16x4, 0, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u16(arg_u16x8, 0, arg_u16x4, 0); + vcopyq_lane_u16(arg_u16x8, 7, arg_u16x4, 0); + vcopyq_lane_u16(arg_u16x8, -1, arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u16(arg_u16x8, 8, arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u16(arg_u16x8, 0, arg_u16x4, 3); + vcopyq_lane_u16(arg_u16x8, 0, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u16(arg_u16x8, 0, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u16(arg_u16x4, 0, arg_u16x8, 0); + vcopy_laneq_u16(arg_u16x4, 3, arg_u16x8, 0); + vcopy_laneq_u16(arg_u16x4, -1, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u16(arg_u16x4, 4, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u16(arg_u16x4, 0, arg_u16x8, 7); + vcopy_laneq_u16(arg_u16x4, 0, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u16(arg_u16x4, 0, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u16(arg_u16x8, 0, arg_u16x8, 0); + vcopyq_laneq_u16(arg_u16x8, 7, arg_u16x8, 0); + vcopyq_laneq_u16(arg_u16x8, -1, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u16(arg_u16x8, 8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u16(arg_u16x8, 0, arg_u16x8, 7); + vcopyq_laneq_u16(arg_u16x8, 0, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u16(arg_u16x8, 0, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vcopy_lane_u32(arg_u32x2, 0, arg_u32x2, 0); + vcopy_lane_u32(arg_u32x2, 1, arg_u32x2, 0); + vcopy_lane_u32(arg_u32x2, -1, arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u32(arg_u32x2, 2, arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_u32(arg_u32x2, 0, arg_u32x2, 1); + vcopy_lane_u32(arg_u32x2, 0, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u32(arg_u32x2, 0, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u32(arg_u32x4, 0, arg_u32x2, 0); + vcopyq_lane_u32(arg_u32x4, 3, arg_u32x2, 0); + vcopyq_lane_u32(arg_u32x4, -1, arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u32(arg_u32x4, 4, arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u32(arg_u32x4, 0, arg_u32x2, 1); + vcopyq_lane_u32(arg_u32x4, 0, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u32(arg_u32x4, 0, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u32(arg_u32x2, 0, arg_u32x4, 0); + vcopy_laneq_u32(arg_u32x2, 1, arg_u32x4, 0); + vcopy_laneq_u32(arg_u32x2, -1, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u32(arg_u32x2, 2, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u32(arg_u32x2, 0, arg_u32x4, 3); + vcopy_laneq_u32(arg_u32x2, 0, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u32(arg_u32x2, 0, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u32(arg_u32x4, 0, arg_u32x4, 0); + vcopyq_laneq_u32(arg_u32x4, 3, arg_u32x4, 0); + vcopyq_laneq_u32(arg_u32x4, -1, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u32(arg_u32x4, 4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u32(arg_u32x4, 0, arg_u32x4, 3); + vcopyq_laneq_u32(arg_u32x4, 0, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u32(arg_u32x4, 0, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_u64(uint64x2_t arg_u64x2, uint64x1_t arg_u64x1) { + vcopy_lane_u64(arg_u64x1, 0, arg_u64x1, 0); + vcopy_lane_u64(arg_u64x1, -1, arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u64(arg_u64x1, 1, arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_u64(arg_u64x1, 0, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_u64(arg_u64x1, 0, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u64(arg_u64x2, 0, arg_u64x1, 0); + vcopyq_lane_u64(arg_u64x2, 1, arg_u64x1, 0); + vcopyq_lane_u64(arg_u64x2, -1, arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u64(arg_u64x2, 2, arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_u64(arg_u64x2, 0, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_u64(arg_u64x2, 0, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u64(arg_u64x1, 0, arg_u64x2, 0); + vcopy_laneq_u64(arg_u64x1, -1, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u64(arg_u64x1, 1, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_u64(arg_u64x1, 0, arg_u64x2, 1); + vcopy_laneq_u64(arg_u64x1, 0, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_u64(arg_u64x1, 0, arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u64(arg_u64x2, 0, arg_u64x2, 0); + vcopyq_laneq_u64(arg_u64x2, 1, arg_u64x2, 0); + vcopyq_laneq_u64(arg_u64x2, -1, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u64(arg_u64x2, 2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_u64(arg_u64x2, 0, arg_u64x2, 1); + vcopyq_laneq_u64(arg_u64x2, 0, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_u64(arg_u64x2, 0, arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_p64(poly64x1_t arg_p64x1, poly64x2_t arg_p64x2) { + vcopy_lane_p64(arg_p64x1, 0, arg_p64x1, 0); + vcopy_lane_p64(arg_p64x1, -1, arg_p64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_p64(arg_p64x1, 1, arg_p64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_p64(arg_p64x1, 0, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_p64(arg_p64x1, 0, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_p64(arg_p64x2, 0, arg_p64x1, 0); + vcopyq_lane_p64(arg_p64x2, 1, arg_p64x1, 0); + vcopyq_lane_p64(arg_p64x2, -1, arg_p64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_p64(arg_p64x2, 2, arg_p64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_p64(arg_p64x2, 0, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_p64(arg_p64x2, 0, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_p64(arg_p64x1, 0, arg_p64x2, 0); + vcopy_laneq_p64(arg_p64x1, -1, arg_p64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_p64(arg_p64x1, 1, arg_p64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_p64(arg_p64x1, 0, arg_p64x2, 1); + vcopy_laneq_p64(arg_p64x1, 0, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_p64(arg_p64x1, 0, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_p64(arg_p64x2, 0, arg_p64x2, 0); + vcopyq_laneq_p64(arg_p64x2, 1, arg_p64x2, 0); + vcopyq_laneq_p64(arg_p64x2, -1, arg_p64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_p64(arg_p64x2, 2, arg_p64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_p64(arg_p64x2, 0, arg_p64x2, 1); + vcopyq_laneq_p64(arg_p64x2, 0, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_p64(arg_p64x2, 0, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_f32(float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vcopy_lane_f32(arg_f32x2, 0, arg_f32x2, 0); + vcopy_lane_f32(arg_f32x2, 1, arg_f32x2, 0); + vcopy_lane_f32(arg_f32x2, -1, arg_f32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_f32(arg_f32x2, 2, arg_f32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_f32(arg_f32x2, 0, arg_f32x2, 1); + vcopy_lane_f32(arg_f32x2, 0, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_f32(arg_f32x2, 0, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_f32(arg_f32x4, 0, arg_f32x2, 0); + vcopyq_lane_f32(arg_f32x4, 3, arg_f32x2, 0); + vcopyq_lane_f32(arg_f32x4, -1, arg_f32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_f32(arg_f32x4, 4, arg_f32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_f32(arg_f32x4, 0, arg_f32x2, 1); + vcopyq_lane_f32(arg_f32x4, 0, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_f32(arg_f32x4, 0, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_f32(arg_f32x2, 0, arg_f32x4, 0); + vcopy_laneq_f32(arg_f32x2, 1, arg_f32x4, 0); + vcopy_laneq_f32(arg_f32x2, -1, arg_f32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_f32(arg_f32x2, 2, arg_f32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_f32(arg_f32x2, 0, arg_f32x4, 3); + vcopy_laneq_f32(arg_f32x2, 0, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_f32(arg_f32x2, 0, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_f32(arg_f32x4, 0, arg_f32x4, 0); + vcopyq_laneq_f32(arg_f32x4, 3, arg_f32x4, 0); + vcopyq_laneq_f32(arg_f32x4, -1, arg_f32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_f32(arg_f32x4, 4, arg_f32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_f32(arg_f32x4, 0, arg_f32x4, 3); + vcopyq_laneq_f32(arg_f32x4, 0, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_f32(arg_f32x4, 0, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_f64(float64x2_t arg_f64x2, float64x1_t arg_f64x1) { + vcopy_lane_f64(arg_f64x1, 0, arg_f64x1, 0); + vcopy_lane_f64(arg_f64x1, -1, arg_f64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_f64(arg_f64x1, 1, arg_f64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_f64(arg_f64x1, 0, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_f64(arg_f64x1, 0, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_f64(arg_f64x2, 0, arg_f64x1, 0); + vcopyq_lane_f64(arg_f64x2, 1, arg_f64x1, 0); + vcopyq_lane_f64(arg_f64x2, -1, arg_f64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_f64(arg_f64x2, 2, arg_f64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_f64(arg_f64x2, 0, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_f64(arg_f64x2, 0, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_f64(arg_f64x1, 0, arg_f64x2, 0); + vcopy_laneq_f64(arg_f64x1, -1, arg_f64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_f64(arg_f64x1, 1, arg_f64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_f64(arg_f64x1, 0, arg_f64x2, 1); + vcopy_laneq_f64(arg_f64x1, 0, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_f64(arg_f64x1, 0, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_f64(arg_f64x2, 0, arg_f64x2, 0); + vcopyq_laneq_f64(arg_f64x2, 1, arg_f64x2, 0); + vcopyq_laneq_f64(arg_f64x2, -1, arg_f64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_f64(arg_f64x2, 2, arg_f64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_f64(arg_f64x2, 0, arg_f64x2, 1); + vcopyq_laneq_f64(arg_f64x2, 0, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_f64(arg_f64x2, 0, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_p8(poly8x16_t arg_p8x16, poly8x8_t arg_p8x8) { + vcopy_lane_p8(arg_p8x8, 0, arg_p8x8, 0); + vcopy_lane_p8(arg_p8x8, 7, arg_p8x8, 0); + vcopy_lane_p8(arg_p8x8, -1, arg_p8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_p8(arg_p8x8, 8, arg_p8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_p8(arg_p8x8, 0, arg_p8x8, 7); + vcopy_lane_p8(arg_p8x8, 0, arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_p8(arg_p8x8, 0, arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_p8(arg_p8x16, 0, arg_p8x8, 0); + vcopyq_lane_p8(arg_p8x16, 15, arg_p8x8, 0); + vcopyq_lane_p8(arg_p8x16, -1, arg_p8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_p8(arg_p8x16, 16, arg_p8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_p8(arg_p8x16, 0, arg_p8x8, 7); + vcopyq_lane_p8(arg_p8x16, 0, arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_p8(arg_p8x16, 0, arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_p8(arg_p8x8, 0, arg_p8x16, 0); + vcopy_laneq_p8(arg_p8x8, 7, arg_p8x16, 0); + vcopy_laneq_p8(arg_p8x8, -1, arg_p8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_p8(arg_p8x8, 8, arg_p8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_p8(arg_p8x8, 0, arg_p8x16, 15); + vcopy_laneq_p8(arg_p8x8, 0, arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_p8(arg_p8x8, 0, arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_p8(arg_p8x16, 0, arg_p8x16, 0); + vcopyq_laneq_p8(arg_p8x16, 15, arg_p8x16, 0); + vcopyq_laneq_p8(arg_p8x16, -1, arg_p8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_p8(arg_p8x16, 16, arg_p8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_p8(arg_p8x16, 0, arg_p8x16, 15); + vcopyq_laneq_p8(arg_p8x16, 0, arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_p8(arg_p8x16, 0, arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_copy_vector_lane_p16(poly16x8_t arg_p16x8, poly16x4_t arg_p16x4) { + vcopy_lane_p16(arg_p16x4, 0, arg_p16x4, 0); + vcopy_lane_p16(arg_p16x4, 3, arg_p16x4, 0); + vcopy_lane_p16(arg_p16x4, -1, arg_p16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_p16(arg_p16x4, 4, arg_p16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_lane_p16(arg_p16x4, 0, arg_p16x4, 3); + vcopy_lane_p16(arg_p16x4, 0, arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_lane_p16(arg_p16x4, 0, arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_p16(arg_p16x8, 0, arg_p16x4, 0); + vcopyq_lane_p16(arg_p16x8, 7, arg_p16x4, 0); + vcopyq_lane_p16(arg_p16x8, -1, arg_p16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_p16(arg_p16x8, 8, arg_p16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_lane_p16(arg_p16x8, 0, arg_p16x4, 3); + vcopyq_lane_p16(arg_p16x8, 0, arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_lane_p16(arg_p16x8, 0, arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_p16(arg_p16x4, 0, arg_p16x8, 0); + vcopy_laneq_p16(arg_p16x4, 3, arg_p16x8, 0); + vcopy_laneq_p16(arg_p16x4, -1, arg_p16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_p16(arg_p16x4, 4, arg_p16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopy_laneq_p16(arg_p16x4, 0, arg_p16x8, 7); + vcopy_laneq_p16(arg_p16x4, 0, arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopy_laneq_p16(arg_p16x4, 0, arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_p16(arg_p16x8, 0, arg_p16x8, 0); + vcopyq_laneq_p16(arg_p16x8, 7, arg_p16x8, 0); + vcopyq_laneq_p16(arg_p16x8, -1, arg_p16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_p16(arg_p16x8, 8, arg_p16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcopyq_laneq_p16(arg_p16x8, 0, arg_p16x8, 7); + vcopyq_laneq_p16(arg_p16x8, 0, arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcopyq_laneq_p16(arg_p16x8, 0, arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/dotprod.c b/clang/test/Sema/aarch64-neon-immediate-ranges/dotprod.c new file mode 100644 index 0000000000000..11f2c660a8ff2 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/dotprod.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +v8.2a -target-feature +dotprod -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + +void test_dot_product_u32(uint8x8_t arg_u8x8, uint32x2_t arg_u32x2, uint8x16_t arg_u8x16, uint32x4_t arg_u32x4) { + vdot_lane_u32(arg_u32x2, arg_u8x8, arg_u8x8, 0); + vdot_lane_u32(arg_u32x2, arg_u8x8, arg_u8x8, 1); + vdot_lane_u32(arg_u32x2, arg_u8x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdot_lane_u32(arg_u32x2, arg_u8x8, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdotq_laneq_u32(arg_u32x4, arg_u8x16, arg_u8x16, 0); + vdotq_laneq_u32(arg_u32x4, arg_u8x16, arg_u8x16, 3); + vdotq_laneq_u32(arg_u32x4, arg_u8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdotq_laneq_u32(arg_u32x4, arg_u8x16, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdot_laneq_u32(arg_u32x2, arg_u8x8, arg_u8x16, 0); + vdot_laneq_u32(arg_u32x2, arg_u8x8, arg_u8x16, 3); + vdot_laneq_u32(arg_u32x2, arg_u8x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdot_laneq_u32(arg_u32x2, arg_u8x8, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdotq_lane_u32(arg_u32x4, arg_u8x16, arg_u8x8, 0); + vdotq_lane_u32(arg_u32x4, arg_u8x16, arg_u8x8, 1); + vdotq_lane_u32(arg_u32x4, arg_u8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdotq_lane_u32(arg_u32x4, arg_u8x16, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_dot_product_s32(int32x2_t arg_i32x2, int8x16_t arg_i8x16, int8x8_t arg_i8x8, int32x4_t arg_i32x4) { + vdot_lane_s32(arg_i32x2, arg_i8x8, arg_i8x8, 0); + vdot_lane_s32(arg_i32x2, arg_i8x8, arg_i8x8, 1); + vdot_lane_s32(arg_i32x2, arg_i8x8, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdot_lane_s32(arg_i32x2, arg_i8x8, arg_i8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdotq_laneq_s32(arg_i32x4, arg_i8x16, arg_i8x16, 0); + vdotq_laneq_s32(arg_i32x4, arg_i8x16, arg_i8x16, 3); + vdotq_laneq_s32(arg_i32x4, arg_i8x16, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdotq_laneq_s32(arg_i32x4, arg_i8x16, arg_i8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdot_laneq_s32(arg_i32x2, arg_i8x8, arg_i8x16, 0); + vdot_laneq_s32(arg_i32x2, arg_i8x8, arg_i8x16, 3); + vdot_laneq_s32(arg_i32x2, arg_i8x8, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdot_laneq_s32(arg_i32x2, arg_i8x8, arg_i8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdotq_lane_s32(arg_i32x4, arg_i8x16, arg_i8x8, 0); + vdotq_lane_s32(arg_i32x4, arg_i8x16, arg_i8x8, 1); + vdotq_lane_s32(arg_i32x4, arg_i8x16, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdotq_lane_s32(arg_i32x4, arg_i8x16, arg_i8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/extract-elt-from-vector.c b/clang/test/Sema/aarch64-neon-immediate-ranges/extract-elt-from-vector.c new file mode 100644 index 0000000000000..5738f5ad27f3e --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/extract-elt-from-vector.c @@ -0,0 +1,301 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_extract_one_element_from_vector_s8(int8x16_t arg_i8x16, int8x8_t arg_i8x8) { + vdupb_lane_s8(arg_i8x8, 0); + vdupb_lane_s8(arg_i8x8, 7); + vdupb_lane_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupb_lane_s8(arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupb_laneq_s8(arg_i8x16, 0); + vdupb_laneq_s8(arg_i8x16, 15); + vdupb_laneq_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupb_laneq_s8(arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_s8(arg_i8x8, 0); + vget_lane_s8(arg_i8x8, 7); + vget_lane_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_s8(arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_s8(arg_i8x16, 0); + vgetq_lane_s8(arg_i8x16, 15); + vgetq_lane_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_s8(arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vduph_lane_s16(arg_i16x4, 0); + vduph_lane_s16(arg_i16x4, 3); + vduph_lane_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_lane_s16(arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vduph_laneq_s16(arg_i16x8, 0); + vduph_laneq_s16(arg_i16x8, 7); + vduph_laneq_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_laneq_s16(arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_s16(arg_i16x4, 0); + vget_lane_s16(arg_i16x4, 3); + vget_lane_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_s16(arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_s16(arg_i16x8, 0); + vgetq_lane_s16(arg_i16x8, 7); + vgetq_lane_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_s16(arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_s32(int32x4_t arg_i32x4, int32x2_t arg_i32x2) { + vdups_lane_s32(arg_i32x2, 0); + vdups_lane_s32(arg_i32x2, 1); + vdups_lane_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdups_lane_s32(arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdups_laneq_s32(arg_i32x4, 0); + vdups_laneq_s32(arg_i32x4, 3); + vdups_laneq_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdups_laneq_s32(arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_s32(arg_i32x2, 0); + vget_lane_s32(arg_i32x2, 1); + vget_lane_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_s32(arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_s32(arg_i32x4, 0); + vgetq_lane_s32(arg_i32x4, 3); + vgetq_lane_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_s32(arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_s64(int64x2_t arg_i64x2, int64x1_t arg_i64x1) { + vdupd_lane_s64(arg_i64x1, 0); + vdupd_lane_s64(arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupd_lane_s64(arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupd_laneq_s64(arg_i64x2, 0); + vdupd_laneq_s64(arg_i64x2, 1); + vdupd_laneq_s64(arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupd_laneq_s64(arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_s64(arg_i64x1, 0); + vget_lane_s64(arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_s64(arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_s64(arg_i64x2, 0); + vgetq_lane_s64(arg_i64x2, 1); + vgetq_lane_s64(arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_s64(arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vdupb_lane_u8(arg_u8x8, 0); + vdupb_lane_u8(arg_u8x8, 7); + vdupb_lane_u8(arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupb_lane_u8(arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupb_laneq_u8(arg_u8x16, 0); + vdupb_laneq_u8(arg_u8x16, 15); + vdupb_laneq_u8(arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupb_laneq_u8(arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_u8(arg_u8x8, 0); + vget_lane_u8(arg_u8x8, 7); + vget_lane_u8(arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_u8(arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_u8(arg_u8x16, 0); + vgetq_lane_u8(arg_u8x16, 15); + vgetq_lane_u8(arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_u8(arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vduph_lane_u16(arg_u16x4, 0); + vduph_lane_u16(arg_u16x4, 3); + vduph_lane_u16(arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_lane_u16(arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vduph_laneq_u16(arg_u16x8, 0); + vduph_laneq_u16(arg_u16x8, 7); + vduph_laneq_u16(arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_laneq_u16(arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_u16(arg_u16x4, 0); + vget_lane_u16(arg_u16x4, 3); + vget_lane_u16(arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_u16(arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_u16(arg_u16x8, 0); + vgetq_lane_u16(arg_u16x8, 7); + vgetq_lane_u16(arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_u16(arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vdups_lane_u32(arg_u32x2, 0); + vdups_lane_u32(arg_u32x2, 1); + vdups_lane_u32(arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdups_lane_u32(arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdups_laneq_u32(arg_u32x4, 0); + vdups_laneq_u32(arg_u32x4, 3); + vdups_laneq_u32(arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdups_laneq_u32(arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_u32(arg_u32x2, 0); + vget_lane_u32(arg_u32x2, 1); + vget_lane_u32(arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_u32(arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_u32(arg_u32x4, 0); + vgetq_lane_u32(arg_u32x4, 3); + vgetq_lane_u32(arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_u32(arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_u64(uint64x1_t arg_u64x1, uint64x2_t arg_u64x2) { + vdupd_lane_u64(arg_u64x1, 0); + vdupd_lane_u64(arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupd_lane_u64(arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupd_laneq_u64(arg_u64x2, 0); + vdupd_laneq_u64(arg_u64x2, 1); + vdupd_laneq_u64(arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupd_laneq_u64(arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_u64(arg_u64x1, 0); + vget_lane_u64(arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_u64(arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_u64(arg_u64x2, 0); + vgetq_lane_u64(arg_u64x2, 1); + vgetq_lane_u64(arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_u64(arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_f32(float32x4_t arg_f32x4, float32x2_t arg_f32x2) { + vdups_lane_f32(arg_f32x2, 0); + vdups_lane_f32(arg_f32x2, 1); + vdups_lane_f32(arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdups_lane_f32(arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdups_laneq_f32(arg_f32x4, 0); + vdups_laneq_f32(arg_f32x4, 3); + vdups_laneq_f32(arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdups_laneq_f32(arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_f32(arg_f32x2, 0); + vget_lane_f32(arg_f32x2, 1); + vget_lane_f32(arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_f32(arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_f32(arg_f32x4, 0); + vgetq_lane_f32(arg_f32x4, 3); + vgetq_lane_f32(arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_f32(arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_f64(float64x2_t arg_f64x2, float64x1_t arg_f64x1) { + vdupd_lane_f64(arg_f64x1, 0); + vdupd_lane_f64(arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupd_lane_f64(arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupd_laneq_f64(arg_f64x2, 0); + vdupd_laneq_f64(arg_f64x2, 1); + vdupd_laneq_f64(arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupd_laneq_f64(arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_f64(arg_f64x1, 0); + vget_lane_f64(arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_f64(arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_f64(arg_f64x2, 0); + vgetq_lane_f64(arg_f64x2, 1); + vgetq_lane_f64(arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_f64(arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_p8(poly8x16_t arg_p8x16, poly8x8_t arg_p8x8) { + vdupb_lane_p8(arg_p8x8, 0); + vdupb_lane_p8(arg_p8x8, 7); + vdupb_lane_p8(arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupb_lane_p8(arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupb_laneq_p8(arg_p8x16, 0); + vdupb_laneq_p8(arg_p8x16, 15); + vdupb_laneq_p8(arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupb_laneq_p8(arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_p8(arg_p8x8, 0); + vget_lane_p8(arg_p8x8, 7); + vget_lane_p8(arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_p8(arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_p8(arg_p8x16, 0); + vgetq_lane_p8(arg_p8x16, 15); + vgetq_lane_p8(arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_p8(arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_p16(poly16x4_t arg_p16x4, poly16x8_t arg_p16x8) { + vduph_lane_p16(arg_p16x4, 0); + vduph_lane_p16(arg_p16x4, 3); + vduph_lane_p16(arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_lane_p16(arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vduph_laneq_p16(arg_p16x8, 0); + vduph_laneq_p16(arg_p16x8, 7); + vduph_laneq_p16(arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vduph_laneq_p16(arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vget_lane_p16(arg_p16x4, 0); + vget_lane_p16(arg_p16x4, 3); + vget_lane_p16(arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_p16(arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_p16(arg_p16x8, 0); + vgetq_lane_p16(arg_p16x8, 7); + vgetq_lane_p16(arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_p16(arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_p64(poly64x2_t arg_p64x2, poly64x1_t arg_p64x1) { + vget_lane_p64(arg_p64x1, 0); + vget_lane_p64(arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_p64(arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_p64(arg_p64x2, 0); + vgetq_lane_p64(arg_p64x2, 1); + vgetq_lane_p64(arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_p64(arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_one_element_from_vector_f16(float16x8_t arg_f16x8, float16x4_t arg_f16x4) { + vget_lane_f16(arg_f16x4, 0); + vget_lane_f16(arg_f16x4, 3); + vget_lane_f16(arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vget_lane_f16(arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vgetq_lane_f16(arg_f16x8, 0); + vgetq_lane_f16(arg_f16x8, 7); + vgetq_lane_f16(arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vgetq_lane_f16(arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/extract-vector-from-vectors.c b/clang/test/Sema/aarch64-neon-immediate-ranges/extract-vector-from-vectors.c new file mode 100644 index 0000000000000..0453e56401a65 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/extract-vector-from-vectors.c @@ -0,0 +1,170 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + +void test_extract_vector_from_a_pair_of_vectors_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vext_s8(arg_i8x8, arg_i8x8, 0); + vext_s8(arg_i8x8, arg_i8x8, 7); + vext_s8(arg_i8x8, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_s8(arg_i8x8, arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_s8(arg_i8x16, arg_i8x16, 0); + vextq_s8(arg_i8x16, arg_i8x16, 15); + vextq_s8(arg_i8x16, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_s8(arg_i8x16, arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_s16(int16x8_t arg_i16x8, int16x4_t arg_i16x4) { + vext_s16(arg_i16x4, arg_i16x4, 0); + vext_s16(arg_i16x4, arg_i16x4, 3); + vext_s16(arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_s16(arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_s16(arg_i16x8, arg_i16x8, 0); + vextq_s16(arg_i16x8, arg_i16x8, 7); + vextq_s16(arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_s16(arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vext_s32(arg_i32x2, arg_i32x2, 0); + vext_s32(arg_i32x2, arg_i32x2, 1); + vext_s32(arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_s32(arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_s32(arg_i32x4, arg_i32x4, 0); + vextq_s32(arg_i32x4, arg_i32x4, 3); + vextq_s32(arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_s32(arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_s64(int64x2_t arg_i64x2, int64x1_t arg_i64x1) { + vext_s64(arg_i64x1, arg_i64x1, 0); + vext_s64(arg_i64x1, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_s64(arg_i64x1, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_s64(arg_i64x2, arg_i64x2, 0); + vextq_s64(arg_i64x2, arg_i64x2, 1); + vextq_s64(arg_i64x2, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_s64(arg_i64x2, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vext_u8(arg_u8x8, arg_u8x8, 0); + vext_u8(arg_u8x8, arg_u8x8, 7); + vext_u8(arg_u8x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_u8(arg_u8x8, arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_u8(arg_u8x16, arg_u8x16, 0); + vextq_u8(arg_u8x16, arg_u8x16, 15); + vextq_u8(arg_u8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_u8(arg_u8x16, arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_u16(uint16x4_t arg_u16x4, uint16x8_t arg_u16x8) { + vext_u16(arg_u16x4, arg_u16x4, 0); + vext_u16(arg_u16x4, arg_u16x4, 3); + vext_u16(arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_u16(arg_u16x4, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_u16(arg_u16x8, arg_u16x8, 0); + vextq_u16(arg_u16x8, arg_u16x8, 7); + vextq_u16(arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_u16(arg_u16x8, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vext_u32(arg_u32x2, arg_u32x2, 0); + vext_u32(arg_u32x2, arg_u32x2, 1); + vext_u32(arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_u32(arg_u32x2, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_u32(arg_u32x4, arg_u32x4, 0); + vextq_u32(arg_u32x4, arg_u32x4, 3); + vextq_u32(arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_u32(arg_u32x4, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_u64(uint64x1_t arg_u64x1, uint64x2_t arg_u64x2) { + vext_u64(arg_u64x1, arg_u64x1, 0); + vext_u64(arg_u64x1, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_u64(arg_u64x1, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_u64(arg_u64x2, arg_u64x2, 0); + vextq_u64(arg_u64x2, arg_u64x2, 1); + vextq_u64(arg_u64x2, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_u64(arg_u64x2, arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_p64(poly64x2_t arg_p64x2, poly64x1_t arg_p64x1) { + vext_p64(arg_p64x1, arg_p64x1, 0); + vext_p64(arg_p64x1, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_p64(arg_p64x1, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_p64(arg_p64x2, arg_p64x2, 0); + vextq_p64(arg_p64x2, arg_p64x2, 1); + vextq_p64(arg_p64x2, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_p64(arg_p64x2, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_f32(float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vext_f32(arg_f32x2, arg_f32x2, 0); + vext_f32(arg_f32x2, arg_f32x2, 1); + vext_f32(arg_f32x2, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_f32(arg_f32x2, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_f32(arg_f32x4, arg_f32x4, 0); + vextq_f32(arg_f32x4, arg_f32x4, 3); + vextq_f32(arg_f32x4, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_f32(arg_f32x4, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_f64(float64x2_t arg_f64x2, float64x1_t arg_f64x1) { + vext_f64(arg_f64x1, arg_f64x1, 0); + vext_f64(arg_f64x1, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_f64(arg_f64x1, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_f64(arg_f64x2, arg_f64x2, 0); + vextq_f64(arg_f64x2, arg_f64x2, 1); + vextq_f64(arg_f64x2, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_f64(arg_f64x2, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_p8(poly8x8_t arg_p8x8, poly8x16_t arg_p8x16) { + vext_p8(arg_p8x8, arg_p8x8, 0); + vext_p8(arg_p8x8, arg_p8x8, 7); + vext_p8(arg_p8x8, arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_p8(arg_p8x8, arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_p8(arg_p8x16, arg_p8x16, 0); + vextq_p8(arg_p8x16, arg_p8x16, 15); + vextq_p8(arg_p8x16, arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_p8(arg_p8x16, arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_extract_vector_from_a_pair_of_vectors_p16(poly16x8_t arg_p16x8, poly16x4_t arg_p16x4) { + vext_p16(arg_p16x4, arg_p16x4, 0); + vext_p16(arg_p16x4, arg_p16x4, 3); + vext_p16(arg_p16x4, arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vext_p16(arg_p16x4, arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vextq_p16(arg_p16x8, arg_p16x8, 0); + vextq_p16(arg_p16x8, arg_p16x8, 7); + vextq_p16(arg_p16x8, arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vextq_p16(arg_p16x8, arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-scalar.c b/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-scalar.c new file mode 100644 index 0000000000000..3a90b445f358d --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-scalar.c @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +v8.2a -ffreestanding -fsyntax-only -verify %s + +#include +#include +// REQUIRES: aarch64-registered-target + +void test_conversions_s16(int16_t arg_i16) { + vcvth_n_f16_s16(arg_i16, 1); + vcvth_n_f16_s16(arg_i16, 16); + vcvth_n_f16_s16(arg_i16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_f16_s16(arg_i16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_conversions_s32(int32_t arg_i32) { + vcvth_n_f16_s32(arg_i32, 1); + vcvth_n_f16_s32(arg_i32, 16); + vcvth_n_f16_s32(arg_i32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_f16_s32(arg_i32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_conversions_s64(int64_t arg_i64) { + vcvth_n_f16_s64(arg_i64, 1); + vcvth_n_f16_s64(arg_i64, 16); + vcvth_n_f16_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_f16_s64(arg_i64, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_conversions_u16(uint16_t arg_u16) { + vcvth_n_f16_u16(arg_u16, 1); + vcvth_n_f16_u16(arg_u16, 16); + vcvth_n_f16_u16(arg_u16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_f16_u16(arg_u16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_conversions_u32(uint32_t arg_u32) { + vcvth_n_f16_u32(arg_u32, 1); + vcvth_n_f16_u32(arg_u32, 16); + vcvth_n_f16_u32(arg_u32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_f16_u32(arg_u32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_conversions_u64(uint64_t arg_u64) { + vcvth_n_f16_u64(arg_u64, 1); + vcvth_n_f16_u64(arg_u64, 16); + vcvth_n_f16_u64(arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_f16_u64(arg_u64, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_conversions_f16(float16_t arg_f16) { + vcvth_n_s16_f16(arg_f16, 1); + vcvth_n_s16_f16(arg_f16, 16); + vcvth_n_s16_f16(arg_f16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_s16_f16(arg_f16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvth_n_s32_f16(arg_f16, 1); + vcvth_n_s32_f16(arg_f16, 16); + vcvth_n_s32_f16(arg_f16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_s32_f16(arg_f16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvth_n_s64_f16(arg_f16, 1); + vcvth_n_s64_f16(arg_f16, 16); + vcvth_n_s64_f16(arg_f16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_s64_f16(arg_f16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvth_n_u16_f16(arg_f16, 1); + vcvth_n_u16_f16(arg_f16, 16); + vcvth_n_u16_f16(arg_f16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_u16_f16(arg_f16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvth_n_u32_f16(arg_f16, 1); + vcvth_n_u32_f16(arg_f16, 16); + vcvth_n_u32_f16(arg_f16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_u32_f16(arg_f16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvth_n_u64_f16(arg_f16, 1); + vcvth_n_u64_f16(arg_f16, 16); + vcvth_n_u64_f16(arg_f16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvth_n_u64_f16(arg_f16, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-v84.c b/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-v84.c new file mode 100644 index 0000000000000..d31cf321d7619 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-v84.c @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +v8.4a -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_fused_multiply_accumulate_f16(float32x2_t arg_f32x2, float32x4_t arg_f32x4, float16x4_t arg_f16x4, float16x8_t arg_f16x8) { + vfmlal_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, 0); + vfmlal_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, 3); + vfmlal_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlal_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlal_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, 0); + vfmlal_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, 7); + vfmlal_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlal_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlalq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, 0); + vfmlalq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, 3); + vfmlalq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlalq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlalq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, 0); + vfmlalq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, 7); + vfmlalq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlalq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlsl_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, 0); + vfmlsl_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, 3); + vfmlsl_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlsl_lane_low_f16(arg_f32x2, arg_f16x4, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlsl_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, 0); + vfmlsl_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, 7); + vfmlsl_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlsl_laneq_low_f16(arg_f32x2, arg_f16x4, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlslq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, 0); + vfmlslq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, 3); + vfmlslq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlslq_lane_low_f16(arg_f32x4, arg_f16x8, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlslq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, 0); + vfmlslq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, 7); + vfmlslq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlslq_laneq_low_f16(arg_f32x4, arg_f16x8, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlal_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, 0); + vfmlal_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, 3); + vfmlal_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlal_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlsl_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, 0); + vfmlsl_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, 3); + vfmlsl_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlsl_lane_high_f16(arg_f32x2, arg_f16x4, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlalq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, 0); + vfmlalq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, 3); + vfmlalq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlalq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlslq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, 0); + vfmlslq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, 3); + vfmlslq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlslq_lane_high_f16(arg_f32x4, arg_f16x8, arg_f16x4, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlal_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, 0); + vfmlal_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, 7); + vfmlal_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlal_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlsl_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, 0); + vfmlsl_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, 7); + vfmlsl_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlsl_laneq_high_f16(arg_f32x2, arg_f16x4, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlalq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, 0); + vfmlalq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, 7); + vfmlalq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlalq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vfmlslq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, 0); + vfmlslq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, 7); + vfmlslq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vfmlslq_laneq_high_f16(arg_f32x4, arg_f16x8, arg_f16x8, 8); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-vector.c b/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-vector.c new file mode 100644 index 0000000000000..6460018b74408 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/fp16-vector.c @@ -0,0 +1,181 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +v8.2a -ffreestanding -fsyntax-only -verify %s + +#include +#include +// REQUIRES: aarch64-registered-target + +// vcvtq_n_f16_u16 is tested under clang/test/Sema/arm-mve-immediates.c + +void test_multiplication_f16(float16_t arg_f16, float16x8_t arg_f16x8, float16x4_t arg_f16x4) { + vmul_lane_f16(arg_f16x4, arg_f16x4, 0); + vmul_lane_f16(arg_f16x4, arg_f16x4, 3); + vmul_lane_f16(arg_f16x4, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_lane_f16(arg_f16x4, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_lane_f16(arg_f16x8, arg_f16x4, 0); + vmulq_lane_f16(arg_f16x8, arg_f16x4, 3); + vmulq_lane_f16(arg_f16x8, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_lane_f16(arg_f16x8, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmul_laneq_f16(arg_f16x4, arg_f16x8, 0); + vmul_laneq_f16(arg_f16x4, arg_f16x8, 7); + vmul_laneq_f16(arg_f16x4, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_laneq_f16(arg_f16x4, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_laneq_f16(arg_f16x8, arg_f16x8, 0); + vmulq_laneq_f16(arg_f16x8, arg_f16x8, 7); + vmulq_laneq_f16(arg_f16x8, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_laneq_f16(arg_f16x8, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulh_lane_f16(arg_f16, arg_f16x4, 0); + vmulh_lane_f16(arg_f16, arg_f16x4, 3); + vmulh_lane_f16(arg_f16, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulh_lane_f16(arg_f16, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulh_laneq_f16(arg_f16, arg_f16x8, 0); + vmulh_laneq_f16(arg_f16, arg_f16x8, 7); + vmulh_laneq_f16(arg_f16, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulh_laneq_f16(arg_f16, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_multiply_extended_f16(float16_t arg_f16, float16x8_t arg_f16x8, float16x4_t arg_f16x4) { + vmulx_lane_f16(arg_f16x4, arg_f16x4, 0); + vmulx_lane_f16(arg_f16x4, arg_f16x4, 3); + vmulx_lane_f16(arg_f16x4, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulx_lane_f16(arg_f16x4, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxq_lane_f16(arg_f16x8, arg_f16x4, 0); + vmulxq_lane_f16(arg_f16x8, arg_f16x4, 3); + vmulxq_lane_f16(arg_f16x8, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxq_lane_f16(arg_f16x8, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulx_laneq_f16(arg_f16x4, arg_f16x8, 0); + vmulx_laneq_f16(arg_f16x4, arg_f16x8, 7); + vmulx_laneq_f16(arg_f16x4, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulx_laneq_f16(arg_f16x4, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxq_laneq_f16(arg_f16x8, arg_f16x8, 0); + vmulxq_laneq_f16(arg_f16x8, arg_f16x8, 7); + vmulxq_laneq_f16(arg_f16x8, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxq_laneq_f16(arg_f16x8, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxh_lane_f16(arg_f16, arg_f16x4, 0); + vmulxh_lane_f16(arg_f16, arg_f16x4, 3); + vmulxh_lane_f16(arg_f16, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxh_lane_f16(arg_f16, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxh_laneq_f16(arg_f16, arg_f16x8, 0); + vmulxh_laneq_f16(arg_f16, arg_f16x8, 7); + vmulxh_laneq_f16(arg_f16, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxh_laneq_f16(arg_f16, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_fused_multiply_accumulate_f16(float16_t arg_f16, float16x8_t arg_f16x8, float16x4_t arg_f16x4) { + vfma_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, 0); + vfma_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, 3); + vfma_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfma_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmaq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, 0); + vfmaq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, 3); + vfmaq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmaq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfma_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, 0); + vfma_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, 7); + vfma_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfma_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmaq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, 0); + vfmaq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, 7); + vfmaq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmaq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmah_lane_f16(arg_f16, arg_f16, arg_f16x4, 0); + vfmah_lane_f16(arg_f16, arg_f16, arg_f16x4, 3); + vfmah_lane_f16(arg_f16, arg_f16, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmah_lane_f16(arg_f16, arg_f16, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmah_laneq_f16(arg_f16, arg_f16, arg_f16x8, 0); + vfmah_laneq_f16(arg_f16, arg_f16, arg_f16x8, 7); + vfmah_laneq_f16(arg_f16, arg_f16, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmah_laneq_f16(arg_f16, arg_f16, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfms_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, 0); + vfms_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, 3); + vfms_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfms_lane_f16(arg_f16x4, arg_f16x4, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, 0); + vfmsq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, 3); + vfmsq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsq_lane_f16(arg_f16x8, arg_f16x8, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfms_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, 0); + vfms_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, 7); + vfms_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfms_laneq_f16(arg_f16x4, arg_f16x4, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, 0); + vfmsq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, 7); + vfmsq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsq_laneq_f16(arg_f16x8, arg_f16x8, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsh_lane_f16(arg_f16, arg_f16, arg_f16x4, 0); + vfmsh_lane_f16(arg_f16, arg_f16, arg_f16x4, 3); + vfmsh_lane_f16(arg_f16, arg_f16, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsh_lane_f16(arg_f16, arg_f16, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsh_laneq_f16(arg_f16, arg_f16, arg_f16x8, 0); + vfmsh_laneq_f16(arg_f16, arg_f16, arg_f16x8, 7); + vfmsh_laneq_f16(arg_f16, arg_f16, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsh_laneq_f16(arg_f16, arg_f16, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_s16(int16x8_t arg_i16x8, int16x4_t arg_i16x4) { + vcvt_n_f16_s16(arg_i16x4, 1); + vcvt_n_f16_s16(arg_i16x4, 16); + vcvt_n_f16_s16(arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_f16_s16(arg_i16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_f16_s16(arg_i16x8, 1); + vcvtq_n_f16_s16(arg_i16x8, 16); + vcvtq_n_f16_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_f16_s16(arg_i16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vcvt_n_f16_u16(arg_u16x4, 1); + vcvt_n_f16_u16(arg_u16x4, 16); + vcvt_n_f16_u16(arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_f16_u16(arg_u16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_conversions_f16(float16x8_t arg_f16x8, float16x4_t arg_f16x4) { + vcvt_n_s16_f16(arg_f16x4, 1); + vcvt_n_s16_f16(arg_f16x4, 16); + vcvt_n_s16_f16(arg_f16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_s16_f16(arg_f16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_s16_f16(arg_f16x8, 1); + vcvtq_n_s16_f16(arg_f16x8, 16); + vcvtq_n_s16_f16(arg_f16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_s16_f16(arg_f16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvt_n_u16_f16(arg_f16x4, 1); + vcvt_n_u16_f16(arg_f16x4, 16); + vcvt_n_u16_f16(arg_f16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvt_n_u16_f16(arg_f16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vcvtq_n_u16_f16(arg_f16x8, 1); + vcvtq_n_u16_f16(arg_f16x8, 16); + vcvtq_n_u16_f16(arg_f16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcvtq_n_u16_f16(arg_f16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/fused-multiply-accumulate.c b/clang/test/Sema/aarch64-neon-immediate-ranges/fused-multiply-accumulate.c new file mode 100644 index 0000000000000..c65a2e6e65332 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/fused-multiply-accumulate.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_fused_multiply_accumulate_f32(float32x2_t arg_f32x2, float32_t arg_f32, float32x4_t arg_f32x4) { + vfma_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 0); + vfma_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 1); + vfma_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfma_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 0); + vfmaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 1); + vfmaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmas_lane_f32(arg_f32, arg_f32, arg_f32x2, 0); + vfmas_lane_f32(arg_f32, arg_f32, arg_f32x2, 1); + vfmas_lane_f32(arg_f32, arg_f32, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmas_lane_f32(arg_f32, arg_f32, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfma_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 0); + vfma_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 3); + vfma_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfma_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 0); + vfmaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 3); + vfmaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmas_laneq_f32(arg_f32, arg_f32, arg_f32x4, 0); + vfmas_laneq_f32(arg_f32, arg_f32, arg_f32x4, 3); + vfmas_laneq_f32(arg_f32, arg_f32, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmas_laneq_f32(arg_f32, arg_f32, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfms_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 0); + vfms_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 1); + vfms_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfms_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 0); + vfmsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 1); + vfmsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmss_lane_f32(arg_f32, arg_f32, arg_f32x2, 0); + vfmss_lane_f32(arg_f32, arg_f32, arg_f32x2, 1); + vfmss_lane_f32(arg_f32, arg_f32, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmss_lane_f32(arg_f32, arg_f32, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfms_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 0); + vfms_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 3); + vfms_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfms_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 0); + vfmsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 3); + vfmsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmss_laneq_f32(arg_f32, arg_f32, arg_f32x4, 0); + vfmss_laneq_f32(arg_f32, arg_f32, arg_f32x4, 3); + vfmss_laneq_f32(arg_f32, arg_f32, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmss_laneq_f32(arg_f32, arg_f32, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_fused_multiply_accumulate_f64(float64x2_t arg_f64x2, float64_t arg_f64, float64x1_t arg_f64x1) { + vfma_lane_f64(arg_f64x1, arg_f64x1, arg_f64x1, 0); + vfma_lane_f64(arg_f64x1, arg_f64x1, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfma_lane_f64(arg_f64x1, arg_f64x1, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmaq_lane_f64(arg_f64x2, arg_f64x2, arg_f64x1, 0); + vfmaq_lane_f64(arg_f64x2, arg_f64x2, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmaq_lane_f64(arg_f64x2, arg_f64x2, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmad_lane_f64(arg_f64, arg_f64, arg_f64x1, 0); + vfmad_lane_f64(arg_f64, arg_f64, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmad_lane_f64(arg_f64, arg_f64, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfma_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, 0); + vfma_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, 1); + vfma_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfma_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmaq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, 0); + vfmaq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, 1); + vfmaq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmaq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmad_laneq_f64(arg_f64, arg_f64, arg_f64x2, 0); + vfmad_laneq_f64(arg_f64, arg_f64, arg_f64x2, 1); + vfmad_laneq_f64(arg_f64, arg_f64, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmad_laneq_f64(arg_f64, arg_f64, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfms_lane_f64(arg_f64x1, arg_f64x1, arg_f64x1, 0); + vfms_lane_f64(arg_f64x1, arg_f64x1, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfms_lane_f64(arg_f64x1, arg_f64x1, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsq_lane_f64(arg_f64x2, arg_f64x2, arg_f64x1, 0); + vfmsq_lane_f64(arg_f64x2, arg_f64x2, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsq_lane_f64(arg_f64x2, arg_f64x2, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsd_lane_f64(arg_f64, arg_f64, arg_f64x1, 0); + vfmsd_lane_f64(arg_f64, arg_f64, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsd_lane_f64(arg_f64, arg_f64, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfms_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, 0); + vfms_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, 1); + vfms_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfms_laneq_f64(arg_f64x1, arg_f64x1, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, 0); + vfmsq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, 1); + vfmsq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsq_laneq_f64(arg_f64x2, arg_f64x2, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vfmsd_laneq_f64(arg_f64, arg_f64, arg_f64x2, 0); + vfmsd_laneq_f64(arg_f64, arg_f64, arg_f64x2, 1); + vfmsd_laneq_f64(arg_f64, arg_f64, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vfmsd_laneq_f64(arg_f64, arg_f64, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/luti.c b/clang/test/Sema/aarch64-neon-immediate-ranges/luti.c new file mode 100644 index 0000000000000..bed8cbc1481dd --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/luti.c @@ -0,0 +1,283 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +lut -target-feature +bf16 -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + +// 2-bit indices + +void test_lookup_read_2bit_u8(uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vluti2_lane_u8(arg_u8x8, arg_u8x8, 0); + vluti2_lane_u8(arg_u8x8, arg_u8x8, 1); + vluti2_lane_u8(arg_u8x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_u8(arg_u8x8, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_u8(arg_u8x8, arg_u8x16, 0); + vluti2_laneq_u8(arg_u8x8, arg_u8x16, 3); + vluti2_laneq_u8(arg_u8x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_u8(arg_u8x8, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_u8(arg_u8x16, arg_u8x8, 0); + vluti2q_lane_u8(arg_u8x16, arg_u8x8, 1); + vluti2q_lane_u8(arg_u8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_u8(arg_u8x16, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_u8(arg_u8x16, arg_u8x16, 0); + vluti2q_laneq_u8(arg_u8x16, arg_u8x16, 3); + vluti2q_laneq_u8(arg_u8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_u8(arg_u8x16, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_2bit_s8(int8x8_t arg_i8x8, uint8x16_t arg_u8x16, uint8x8_t arg_u8x8, int8x16_t arg_i8x16) { + vluti2_lane_s8(arg_i8x8, arg_u8x8, 0); + vluti2_lane_s8(arg_i8x8, arg_u8x8, 1); + vluti2_lane_s8(arg_i8x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_s8(arg_i8x8, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_s8(arg_i8x8, arg_u8x16, 0); + vluti2_laneq_s8(arg_i8x8, arg_u8x16, 3); + vluti2_laneq_s8(arg_i8x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_s8(arg_i8x8, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_s8(arg_i8x16, arg_u8x8, 0); + vluti2q_lane_s8(arg_i8x16, arg_u8x8, 1); + vluti2q_lane_s8(arg_i8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_s8(arg_i8x16, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_s8(arg_i8x16, arg_u8x16, 0); + vluti2q_laneq_s8(arg_i8x16, arg_u8x16, 3); + vluti2q_laneq_s8(arg_i8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_s8(arg_i8x16, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_2bit_p8(poly8x16_t arg_p8x16, poly8x8_t arg_p8x8, uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vluti2_lane_p8(arg_p8x8, arg_u8x8, 0); + vluti2_lane_p8(arg_p8x8, arg_u8x8, 1); + vluti2_lane_p8(arg_p8x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_p8(arg_p8x8, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_p8(arg_p8x8, arg_u8x16, 0); + vluti2_laneq_p8(arg_p8x8, arg_u8x16, 3); + vluti2_laneq_p8(arg_p8x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_p8(arg_p8x8, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_p8(arg_p8x16, arg_u8x8, 0); + vluti2q_lane_p8(arg_p8x16, arg_u8x8, 1); + vluti2q_lane_p8(arg_p8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_p8(arg_p8x16, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_p8(arg_p8x16, arg_u8x16, 0); + vluti2q_laneq_p8(arg_p8x16, arg_u8x16, 3); + vluti2q_laneq_p8(arg_p8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_p8(arg_p8x16, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_2bit_u16(uint16x4_t arg_u16x4, uint8x16_t arg_u8x16, uint8x8_t arg_u8x8, uint16x8_t arg_u16x8) { + vluti2_lane_u16(arg_u16x4, arg_u8x8, 0); + vluti2_lane_u16(arg_u16x4, arg_u8x8, 3); + vluti2_lane_u16(arg_u16x4, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_u16(arg_u16x4, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_u16(arg_u16x4, arg_u8x16, 0); + vluti2_laneq_u16(arg_u16x4, arg_u8x16, 7); + vluti2_laneq_u16(arg_u16x4, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_u16(arg_u16x4, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_u16(arg_u16x8, arg_u8x8, 0); + vluti2q_lane_u16(arg_u16x8, arg_u8x8, 3); + vluti2q_lane_u16(arg_u16x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_u16(arg_u16x8, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_u16(arg_u16x8, arg_u8x16, 0); + vluti2q_laneq_u16(arg_u16x8, arg_u8x16, 7); + vluti2q_laneq_u16(arg_u16x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_u16(arg_u16x8, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_2bit_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8, uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vluti2_lane_s16(arg_i16x4, arg_u8x8, 0); + vluti2_lane_s16(arg_i16x4, arg_u8x8, 3); + vluti2_lane_s16(arg_i16x4, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_s16(arg_i16x4, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_s16(arg_i16x4, arg_u8x16, 0); + vluti2_laneq_s16(arg_i16x4, arg_u8x16, 7); + vluti2_laneq_s16(arg_i16x4, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_s16(arg_i16x4, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_s16(arg_i16x8, arg_u8x8, 0); + vluti2q_lane_s16(arg_i16x8, arg_u8x8, 3); + vluti2q_lane_s16(arg_i16x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_s16(arg_i16x8, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_s16(arg_i16x8, arg_u8x16, 0); + vluti2q_laneq_s16(arg_i16x8, arg_u8x16, 7); + vluti2q_laneq_s16(arg_i16x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_s16(arg_i16x8, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_2bit_f16(float16x8_t arg_f16x8, uint8x16_t arg_u8x16, float16x4_t arg_f16x4, uint8x8_t arg_u8x8) { + vluti2_lane_f16(arg_f16x4, arg_u8x8, 0); + vluti2_lane_f16(arg_f16x4, arg_u8x8, 3); + vluti2_lane_f16(arg_f16x4, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_f16(arg_f16x4, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_f16(arg_f16x4, arg_u8x16, 0); + vluti2_laneq_f16(arg_f16x4, arg_u8x16, 7); + vluti2_laneq_f16(arg_f16x4, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_f16(arg_f16x4, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_f16(arg_f16x8, arg_u8x8, 0); + vluti2q_lane_f16(arg_f16x8, arg_u8x8, 3); + vluti2q_lane_f16(arg_f16x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_f16(arg_f16x8, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_f16(arg_f16x8, arg_u8x16, 0); + vluti2q_laneq_f16(arg_f16x8, arg_u8x16, 7); + vluti2q_laneq_f16(arg_f16x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_f16(arg_f16x8, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_2bit_bf16(bfloat16x4_t arg_b16x4, bfloat16x8_t arg_b16x8, uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vluti2_lane_bf16(arg_b16x4, arg_u8x8, 0); + vluti2_lane_bf16(arg_b16x4, arg_u8x8, 3); + vluti2_lane_bf16(arg_b16x4, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_bf16(arg_b16x4, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_bf16(arg_b16x4, arg_u8x16, 0); + vluti2_laneq_bf16(arg_b16x4, arg_u8x16, 7); + vluti2_laneq_bf16(arg_b16x4, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_bf16(arg_b16x4, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_bf16(arg_b16x8, arg_u8x8, 0); + vluti2q_lane_bf16(arg_b16x8, arg_u8x8, 3); + vluti2q_lane_bf16(arg_b16x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_bf16(arg_b16x8, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_bf16(arg_b16x8, arg_u8x16, 0); + vluti2q_laneq_bf16(arg_b16x8, arg_u8x16, 7); + vluti2q_laneq_bf16(arg_b16x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_bf16(arg_b16x8, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_2bit_p16(poly16x4_t arg_p16x4, poly16x8_t arg_p16x8, uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vluti2_lane_p16(arg_p16x4, arg_u8x8, 0); + vluti2_lane_p16(arg_p16x4, arg_u8x8, 3); + vluti2_lane_p16(arg_p16x4, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_lane_p16(arg_p16x4, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2_laneq_p16(arg_p16x4, arg_u8x16, 0); + vluti2_laneq_p16(arg_p16x4, arg_u8x16, 7); + vluti2_laneq_p16(arg_p16x4, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2_laneq_p16(arg_p16x4, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_lane_p16(arg_p16x8, arg_u8x8, 0); + vluti2q_lane_p16(arg_p16x8, arg_u8x8, 3); + vluti2q_lane_p16(arg_p16x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_lane_p16(arg_p16x8, arg_u8x8, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti2q_laneq_p16(arg_p16x8, arg_u8x16, 0); + vluti2q_laneq_p16(arg_p16x8, arg_u8x16, 7); + vluti2q_laneq_p16(arg_p16x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti2q_laneq_p16(arg_p16x8, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +// 4-bit indices + +void test_lookup_read_4bit_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vluti4q_lane_u8(arg_u8x16, arg_u8x8, 0); + vluti4q_lane_u8(arg_u8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_u8(arg_u8x16, arg_u8x8, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_u8(arg_u8x16, arg_u8x16, 0); + vluti4q_laneq_u8(arg_u8x16, arg_u8x16, 1); + vluti4q_laneq_u8(arg_u8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_u8(arg_u8x16, arg_u8x16, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_4bit_s8(int8x16_t arg_i8x16, uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vluti4q_lane_s8(arg_i8x16, arg_u8x8, 0); + vluti4q_lane_s8(arg_i8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_s8(arg_i8x16, arg_u8x8, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_s8(arg_i8x16, arg_u8x16, 0); + vluti4q_laneq_s8(arg_i8x16, arg_u8x16, 1); + vluti4q_laneq_s8(arg_i8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_s8(arg_i8x16, arg_u8x16, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_4bit_p8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16, poly8x16_t arg_p8x16) { + vluti4q_lane_p8(arg_p8x16, arg_u8x8, 0); + vluti4q_lane_p8(arg_p8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_p8(arg_p8x16, arg_u8x8, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_p8(arg_p8x16, arg_u8x16, 0); + vluti4q_laneq_p8(arg_p8x16, arg_u8x16, 1); + vluti4q_laneq_p8(arg_p8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_p8(arg_p8x16, arg_u8x16, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_lookup_read_4bit_x2(int16x8x2_t arg_i16x8x2, uint8x8_t arg_u8x8, float16x8x2_t arg_f16x8x2, uint8x16_t arg_u8x16, poly16x8x2_t arg_p16x8x2, uint16x8x2_t arg_u16x8x2, bfloat16x8x2_t arg_b16x8x2) { + vluti4q_lane_u16_x2(arg_u16x8x2, arg_u8x8, 0); + vluti4q_lane_u16_x2(arg_u16x8x2, arg_u8x8, 1); + vluti4q_lane_u16_x2(arg_u16x8x2, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_u16_x2(arg_u16x8x2, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_u16_x2(arg_u16x8x2, arg_u8x16, 0); + vluti4q_laneq_u16_x2(arg_u16x8x2, arg_u8x16, 3); + vluti4q_laneq_u16_x2(arg_u16x8x2, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_u16_x2(arg_u16x8x2, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_lane_s16_x2(arg_i16x8x2, arg_u8x8, 0); + vluti4q_lane_s16_x2(arg_i16x8x2, arg_u8x8, 1); + vluti4q_lane_s16_x2(arg_i16x8x2, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_s16_x2(arg_i16x8x2, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_s16_x2(arg_i16x8x2, arg_u8x16, 0); + vluti4q_laneq_s16_x2(arg_i16x8x2, arg_u8x16, 3); + vluti4q_laneq_s16_x2(arg_i16x8x2, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_s16_x2(arg_i16x8x2, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_lane_f16_x2(arg_f16x8x2, arg_u8x8, 0); + vluti4q_lane_f16_x2(arg_f16x8x2, arg_u8x8, 1); + vluti4q_lane_f16_x2(arg_f16x8x2, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_f16_x2(arg_f16x8x2, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_f16_x2(arg_f16x8x2, arg_u8x16, 0); + vluti4q_laneq_f16_x2(arg_f16x8x2, arg_u8x16, 3); + vluti4q_laneq_f16_x2(arg_f16x8x2, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_f16_x2(arg_f16x8x2, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_lane_bf16_x2(arg_b16x8x2, arg_u8x8, 0); + vluti4q_lane_bf16_x2(arg_b16x8x2, arg_u8x8, 1); + vluti4q_lane_bf16_x2(arg_b16x8x2, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_bf16_x2(arg_b16x8x2, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_bf16_x2(arg_b16x8x2, arg_u8x16, 0); + vluti4q_laneq_bf16_x2(arg_b16x8x2, arg_u8x16, 3); + vluti4q_laneq_bf16_x2(arg_b16x8x2, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_bf16_x2(arg_b16x8x2, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_lane_p16_x2(arg_p16x8x2, arg_u8x8, 0); + vluti4q_lane_p16_x2(arg_p16x8x2, arg_u8x8, 1); + vluti4q_lane_p16_x2(arg_p16x8x2, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_lane_p16_x2(arg_p16x8x2, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vluti4q_laneq_p16_x2(arg_p16x8x2, arg_u8x16, 0); + vluti4q_laneq_p16_x2(arg_p16x8x2, arg_u8x16, 3); + vluti4q_laneq_p16_x2(arg_p16x8x2, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vluti4q_laneq_p16_x2(arg_p16x8x2, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/matrix-multiplication.c b/clang/test/Sema/aarch64-neon-immediate-ranges/matrix-multiplication.c new file mode 100644 index 0000000000000..dd501b84bae47 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/matrix-multiplication.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +v8.6a -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_dot_product_s32(int8x8_t arg_i8x8, int32x2_t arg_i32x2, uint8x16_t arg_u8x16, uint8x8_t arg_u8x8, + int32x4_t arg_i32x4, int8x16_t arg_i8x16) { + vusdot_lane_s32(arg_i32x2, arg_u8x8, arg_i8x8, 0); + vusdot_lane_s32(arg_i32x2, arg_u8x8, arg_i8x8, 1); + vusdot_lane_s32(arg_i32x2, arg_u8x8, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vusdot_lane_s32(arg_i32x2, arg_u8x8, arg_i8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsudot_lane_s32(arg_i32x2, arg_i8x8, arg_u8x8, 0); + vsudot_lane_s32(arg_i32x2, arg_i8x8, arg_u8x8, 1); + vsudot_lane_s32(arg_i32x2, arg_i8x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsudot_lane_s32(arg_i32x2, arg_i8x8, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vusdot_laneq_s32(arg_i32x2, arg_u8x8, arg_i8x16, 0); + vusdot_laneq_s32(arg_i32x2, arg_u8x8, arg_i8x16, 3); + vusdot_laneq_s32(arg_i32x2, arg_u8x8, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vusdot_laneq_s32(arg_i32x2, arg_u8x8, arg_i8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsudot_laneq_s32(arg_i32x2, arg_i8x8, arg_u8x16, 0); + vsudot_laneq_s32(arg_i32x2, arg_i8x8, arg_u8x16, 3); + vsudot_laneq_s32(arg_i32x2, arg_i8x8, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsudot_laneq_s32(arg_i32x2, arg_i8x8, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vusdotq_lane_s32(arg_i32x4, arg_u8x16, arg_i8x8, 0); + vusdotq_lane_s32(arg_i32x4, arg_u8x16, arg_i8x8, 1); + vusdotq_lane_s32(arg_i32x4, arg_u8x16, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vusdotq_lane_s32(arg_i32x4, arg_u8x16, arg_i8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsudotq_lane_s32(arg_i32x4, arg_i8x16, arg_u8x8, 0); + vsudotq_lane_s32(arg_i32x4, arg_i8x16, arg_u8x8, 1); + vsudotq_lane_s32(arg_i32x4, arg_i8x16, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsudotq_lane_s32(arg_i32x4, arg_i8x16, arg_u8x8, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vusdotq_laneq_s32(arg_i32x4, arg_u8x16, arg_i8x16, 0); + vusdotq_laneq_s32(arg_i32x4, arg_u8x16, arg_i8x16, 3); + vusdotq_laneq_s32(arg_i32x4, arg_u8x16, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vusdotq_laneq_s32(arg_i32x4, arg_u8x16, arg_i8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsudotq_laneq_s32(arg_i32x4, arg_i8x16, arg_u8x16, 0); + vsudotq_laneq_s32(arg_i32x4, arg_i8x16, arg_u8x16, 3); + vsudotq_laneq_s32(arg_i32x4, arg_i8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsudotq_laneq_s32(arg_i32x4, arg_i8x16, arg_u8x16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/multiply-extended.c b/clang/test/Sema/aarch64-neon-immediate-ranges/multiply-extended.c new file mode 100644 index 0000000000000..8c679e7e6a7d9 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/multiply-extended.c @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_multiply_extended_f32(float32_t arg_f32, float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vmulx_lane_f32(arg_f32x2, arg_f32x2, 0); + vmulx_lane_f32(arg_f32x2, arg_f32x2, 1); + vmulx_lane_f32(arg_f32x2, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulx_lane_f32(arg_f32x2, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxq_lane_f32(arg_f32x4, arg_f32x2, 0); + vmulxq_lane_f32(arg_f32x4, arg_f32x2, 1); + vmulxq_lane_f32(arg_f32x4, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxq_lane_f32(arg_f32x4, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxs_lane_f32(arg_f32, arg_f32x2, 0); + vmulxs_lane_f32(arg_f32, arg_f32x2, 1); + vmulxs_lane_f32(arg_f32, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxs_lane_f32(arg_f32, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulx_laneq_f32(arg_f32x2, arg_f32x4, 0); + vmulx_laneq_f32(arg_f32x2, arg_f32x4, 3); + vmulx_laneq_f32(arg_f32x2, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulx_laneq_f32(arg_f32x2, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxq_laneq_f32(arg_f32x4, arg_f32x4, 0); + vmulxq_laneq_f32(arg_f32x4, arg_f32x4, 3); + vmulxq_laneq_f32(arg_f32x4, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxq_laneq_f32(arg_f32x4, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxs_laneq_f32(arg_f32, arg_f32x4, 0); + vmulxs_laneq_f32(arg_f32, arg_f32x4, 3); + vmulxs_laneq_f32(arg_f32, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxs_laneq_f32(arg_f32, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_multiply_extended_f64(float64_t arg_f64, float64x2_t arg_f64x2, float64x1_t arg_f64x1) { + vmulx_lane_f64(arg_f64x1, arg_f64x1, 0); + vmulx_lane_f64(arg_f64x1, arg_f64x1, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vmulx_lane_f64(arg_f64x1, arg_f64x1, 1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + + vmulxq_lane_f64(arg_f64x2, arg_f64x1, 0); + vmulxq_lane_f64(arg_f64x2, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxq_lane_f64(arg_f64x2, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxd_lane_f64(arg_f64, arg_f64x1, 0); + vmulxd_lane_f64(arg_f64, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxd_lane_f64(arg_f64, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulx_laneq_f64(arg_f64x1, arg_f64x2, 0); + vmulx_laneq_f64(arg_f64x1, arg_f64x2, 1); + vmulx_laneq_f64(arg_f64x1, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulx_laneq_f64(arg_f64x1, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxq_laneq_f64(arg_f64x2, arg_f64x2, 0); + vmulxq_laneq_f64(arg_f64x2, arg_f64x2, 1); + vmulxq_laneq_f64(arg_f64x2, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxq_laneq_f64(arg_f64x2, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulxd_laneq_f64(arg_f64, arg_f64x2, 0); + vmulxd_laneq_f64(arg_f64, arg_f64x2, 1); + vmulxd_laneq_f64(arg_f64, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulxd_laneq_f64(arg_f64, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/saturating-multiply-accumulate.c b/clang/test/Sema/aarch64-neon-immediate-ranges/saturating-multiply-accumulate.c new file mode 100644 index 0000000000000..854d6171a914c --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/saturating-multiply-accumulate.c @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_saturating_multiply_accumulate_s16(int16x4_t arg_i16x4, int32_t arg_i32, int16_t arg_i16, + int32x4_t arg_i32x4, int16x8_t arg_i16x8) { + vqdmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 0); + vqdmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 3); + vqdmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlalh_lane_s16(arg_i32, arg_i16, arg_i16x4, 0); + vqdmlalh_lane_s16(arg_i32, arg_i16, arg_i16x4, 3); + vqdmlalh_lane_s16(arg_i32, arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlalh_lane_s16(arg_i32, arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 0); + vqdmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 3); + vqdmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 0); + vqdmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 7); + vqdmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlalh_laneq_s16(arg_i32, arg_i16, arg_i16x8, 0); + vqdmlalh_laneq_s16(arg_i32, arg_i16, arg_i16x8, 7); + vqdmlalh_laneq_s16(arg_i32, arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlalh_laneq_s16(arg_i32, arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 0); + vqdmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 7); + vqdmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 0); + vqdmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 3); + vqdmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlslh_lane_s16(arg_i32, arg_i16, arg_i16x4, 0); + vqdmlslh_lane_s16(arg_i32, arg_i16, arg_i16x4, 3); + vqdmlslh_lane_s16(arg_i32, arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlslh_lane_s16(arg_i32, arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 0); + vqdmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 3); + vqdmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 0); + vqdmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 7); + vqdmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlslh_laneq_s16(arg_i32, arg_i16, arg_i16x8, 0); + vqdmlslh_laneq_s16(arg_i32, arg_i16, arg_i16x8, 7); + vqdmlslh_laneq_s16(arg_i32, arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlslh_laneq_s16(arg_i32, arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 0); + vqdmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 7); + vqdmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_saturating_multiply_accumulate_s32(int32_t arg_i32, int32x4_t arg_i32x4, int64_t arg_i64, int64x2_t arg_i64x2, int32x2_t arg_i32x2) { + vqdmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 0); + vqdmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 1); + vqdmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlals_lane_s32(arg_i64, arg_i32, arg_i32x2, 0); + vqdmlals_lane_s32(arg_i64, arg_i32, arg_i32x2, 1); + vqdmlals_lane_s32(arg_i64, arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlals_lane_s32(arg_i64, arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 0); + vqdmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 1); + vqdmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 0); + vqdmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 3); + vqdmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlals_laneq_s32(arg_i64, arg_i32, arg_i32x4, 0); + vqdmlals_laneq_s32(arg_i64, arg_i32, arg_i32x4, 3); + vqdmlals_laneq_s32(arg_i64, arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlals_laneq_s32(arg_i64, arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 0); + vqdmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 3); + vqdmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 0); + vqdmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 1); + vqdmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsls_lane_s32(arg_i64, arg_i32, arg_i32x2, 0); + vqdmlsls_lane_s32(arg_i64, arg_i32, arg_i32x2, 1); + vqdmlsls_lane_s32(arg_i64, arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsls_lane_s32(arg_i64, arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 0); + vqdmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 1); + vqdmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 0); + vqdmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 3); + vqdmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsls_laneq_s32(arg_i64, arg_i32, arg_i32x4, 0); + vqdmlsls_laneq_s32(arg_i64, arg_i32, arg_i32x4, 3); + vqdmlsls_laneq_s32(arg_i64, arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsls_laneq_s32(arg_i64, arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 0); + vqdmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 3); + vqdmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/saturating-multiply-by-scalar-and-widen.c b/clang/test/Sema/aarch64-neon-immediate-ranges/saturating-multiply-by-scalar-and-widen.c new file mode 100644 index 0000000000000..662a3c2ed172d --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/saturating-multiply-by-scalar-and-widen.c @@ -0,0 +1,193 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_saturating_multiply_by_scalar_and_widen_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8, int16_t arg_i16) { + vqdmull_lane_s16(arg_i16x4, arg_i16x4, 0); + vqdmull_lane_s16(arg_i16x4, arg_i16x4, 3); + vqdmull_lane_s16(arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_lane_s16(arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmullh_lane_s16(arg_i16, arg_i16x4, 0); + vqdmullh_lane_s16(arg_i16, arg_i16x4, 3); + vqdmullh_lane_s16(arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmullh_lane_s16(arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmull_high_lane_s16(arg_i16x8, arg_i16x4, 0); + vqdmull_high_lane_s16(arg_i16x8, arg_i16x4, 3); + vqdmull_high_lane_s16(arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_high_lane_s16(arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmull_laneq_s16(arg_i16x4, arg_i16x8, 0); + vqdmull_laneq_s16(arg_i16x4, arg_i16x8, 7); + vqdmull_laneq_s16(arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_laneq_s16(arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmullh_laneq_s16(arg_i16, arg_i16x8, 0); + vqdmullh_laneq_s16(arg_i16, arg_i16x8, 7); + vqdmullh_laneq_s16(arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmullh_laneq_s16(arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmull_high_laneq_s16(arg_i16x8, arg_i16x8, 0); + vqdmull_high_laneq_s16(arg_i16x8, arg_i16x8, 7); + vqdmull_high_laneq_s16(arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_high_laneq_s16(arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulh_lane_s16(arg_i16x4, arg_i16x4, 0); + vqdmulh_lane_s16(arg_i16x4, arg_i16x4, 3); + vqdmulh_lane_s16(arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulh_lane_s16(arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhq_lane_s16(arg_i16x8, arg_i16x4, 0); + vqdmulhq_lane_s16(arg_i16x8, arg_i16x4, 3); + vqdmulhq_lane_s16(arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhq_lane_s16(arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhh_lane_s16(arg_i16, arg_i16x4, 0); + vqdmulhh_lane_s16(arg_i16, arg_i16x4, 3); + vqdmulhh_lane_s16(arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhh_lane_s16(arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulh_laneq_s16(arg_i16x4, arg_i16x8, 0); + vqdmulh_laneq_s16(arg_i16x4, arg_i16x8, 7); + vqdmulh_laneq_s16(arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulh_laneq_s16(arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhq_laneq_s16(arg_i16x8, arg_i16x8, 0); + vqdmulhq_laneq_s16(arg_i16x8, arg_i16x8, 7); + vqdmulhq_laneq_s16(arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhq_laneq_s16(arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhh_laneq_s16(arg_i16, arg_i16x8, 0); + vqdmulhh_laneq_s16(arg_i16, arg_i16x8, 7); + vqdmulhh_laneq_s16(arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhh_laneq_s16(arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulh_lane_s16(arg_i16x4, arg_i16x4, 0); + vqrdmulh_lane_s16(arg_i16x4, arg_i16x4, 3); + vqrdmulh_lane_s16(arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulh_lane_s16(arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhq_lane_s16(arg_i16x8, arg_i16x4, 0); + vqrdmulhq_lane_s16(arg_i16x8, arg_i16x4, 3); + vqrdmulhq_lane_s16(arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhq_lane_s16(arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhh_lane_s16(arg_i16, arg_i16x4, 0); + vqrdmulhh_lane_s16(arg_i16, arg_i16x4, 3); + vqrdmulhh_lane_s16(arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhh_lane_s16(arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulh_laneq_s16(arg_i16x4, arg_i16x8, 0); + vqrdmulh_laneq_s16(arg_i16x4, arg_i16x8, 7); + vqrdmulh_laneq_s16(arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulh_laneq_s16(arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhq_laneq_s16(arg_i16x8, arg_i16x8, 0); + vqrdmulhq_laneq_s16(arg_i16x8, arg_i16x8, 7); + vqrdmulhq_laneq_s16(arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhq_laneq_s16(arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhh_laneq_s16(arg_i16, arg_i16x8, 0); + vqrdmulhh_laneq_s16(arg_i16, arg_i16x8, 7); + vqrdmulhh_laneq_s16(arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhh_laneq_s16(arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + + +void test_saturating_multiply_by_scalar_and_widen_s32(int32x2_t arg_i32x2, int32_t arg_i32, int32x4_t arg_i32x4) { + vqdmull_lane_s32(arg_i32x2, arg_i32x2, 0); + vqdmull_lane_s32(arg_i32x2, arg_i32x2, 1); + vqdmull_lane_s32(arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_lane_s32(arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulls_lane_s32(arg_i32, arg_i32x2, 0); + vqdmulls_lane_s32(arg_i32, arg_i32x2, 1); + vqdmulls_lane_s32(arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulls_lane_s32(arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmull_high_lane_s32(arg_i32x4, arg_i32x2, 0); + vqdmull_high_lane_s32(arg_i32x4, arg_i32x2, 1); + vqdmull_high_lane_s32(arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_high_lane_s32(arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmull_laneq_s32(arg_i32x2, arg_i32x4, 0); + vqdmull_laneq_s32(arg_i32x2, arg_i32x4, 3); + vqdmull_laneq_s32(arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_laneq_s32(arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulls_laneq_s32(arg_i32, arg_i32x4, 0); + vqdmulls_laneq_s32(arg_i32, arg_i32x4, 3); + vqdmulls_laneq_s32(arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulls_laneq_s32(arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmull_high_laneq_s32(arg_i32x4, arg_i32x4, 0); + vqdmull_high_laneq_s32(arg_i32x4, arg_i32x4, 3); + vqdmull_high_laneq_s32(arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmull_high_laneq_s32(arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulh_lane_s32(arg_i32x2, arg_i32x2, 0); + vqdmulh_lane_s32(arg_i32x2, arg_i32x2, 1); + vqdmulh_lane_s32(arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulh_lane_s32(arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhq_lane_s32(arg_i32x4, arg_i32x2, 0); + vqdmulhq_lane_s32(arg_i32x4, arg_i32x2, 1); + vqdmulhq_lane_s32(arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhq_lane_s32(arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhs_lane_s32(arg_i32, arg_i32x2, 0); + vqdmulhs_lane_s32(arg_i32, arg_i32x2, 1); + vqdmulhs_lane_s32(arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhs_lane_s32(arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulh_laneq_s32(arg_i32x2, arg_i32x4, 0); + vqdmulh_laneq_s32(arg_i32x2, arg_i32x4, 3); + vqdmulh_laneq_s32(arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulh_laneq_s32(arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhq_laneq_s32(arg_i32x4, arg_i32x4, 0); + vqdmulhq_laneq_s32(arg_i32x4, arg_i32x4, 3); + vqdmulhq_laneq_s32(arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhq_laneq_s32(arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqdmulhs_laneq_s32(arg_i32, arg_i32x4, 0); + vqdmulhs_laneq_s32(arg_i32, arg_i32x4, 3); + vqdmulhs_laneq_s32(arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqdmulhs_laneq_s32(arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulh_lane_s32(arg_i32x2, arg_i32x2, 0); + vqrdmulh_lane_s32(arg_i32x2, arg_i32x2, 1); + vqrdmulh_lane_s32(arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulh_lane_s32(arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhq_lane_s32(arg_i32x4, arg_i32x2, 0); + vqrdmulhq_lane_s32(arg_i32x4, arg_i32x2, 1); + vqrdmulhq_lane_s32(arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhq_lane_s32(arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhs_lane_s32(arg_i32, arg_i32x2, 0); + vqrdmulhs_lane_s32(arg_i32, arg_i32x2, 1); + vqrdmulhs_lane_s32(arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhs_lane_s32(arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulh_laneq_s32(arg_i32x2, arg_i32x4, 0); + vqrdmulh_laneq_s32(arg_i32x2, arg_i32x4, 3); + vqrdmulh_laneq_s32(arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulh_laneq_s32(arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhq_laneq_s32(arg_i32x4, arg_i32x4, 0); + vqrdmulhq_laneq_s32(arg_i32x4, arg_i32x4, 3); + vqrdmulhq_laneq_s32(arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhq_laneq_s32(arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmulhs_laneq_s32(arg_i32, arg_i32x4, 0); + vqrdmulhs_laneq_s32(arg_i32, arg_i32x4, 3); + vqrdmulhs_laneq_s32(arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmulhs_laneq_s32(arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/set-lanes-to-value.c b/clang/test/Sema/aarch64-neon-immediate-ranges/set-lanes-to-value.c new file mode 100644 index 0000000000000..b5fa76b5be882 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/set-lanes-to-value.c @@ -0,0 +1,297 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_set_all_lanes_to_the_same_value_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vdup_lane_s8(arg_i8x8, 0); + vdup_lane_s8(arg_i8x8, 7); + vdup_lane_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_s8(arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_s8(arg_i8x8, 0); + vdupq_lane_s8(arg_i8x8, 7); + vdupq_lane_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_s8(arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_s8(arg_i8x16, 0); + vdup_laneq_s8(arg_i8x16, 15); + vdup_laneq_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_s8(arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_s8(arg_i8x16, 0); + vdupq_laneq_s8(arg_i8x16, 15); + vdupq_laneq_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_s8(arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vdup_lane_s16(arg_i16x4, 0); + vdup_lane_s16(arg_i16x4, 3); + vdup_lane_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_s16(arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_s16(arg_i16x4, 0); + vdupq_lane_s16(arg_i16x4, 3); + vdupq_lane_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_s16(arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_s16(arg_i16x8, 0); + vdup_laneq_s16(arg_i16x8, 7); + vdup_laneq_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_s16(arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_s16(arg_i16x8, 0); + vdupq_laneq_s16(arg_i16x8, 7); + vdupq_laneq_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_s16(arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_s32(int32x4_t arg_i32x4, int32x2_t arg_i32x2) { + vdup_lane_s32(arg_i32x2, 0); + vdup_lane_s32(arg_i32x2, 1); + vdup_lane_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_s32(arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_s32(arg_i32x2, 0); + vdupq_lane_s32(arg_i32x2, 1); + vdupq_lane_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_s32(arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_s32(arg_i32x4, 0); + vdup_laneq_s32(arg_i32x4, 3); + vdup_laneq_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_s32(arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_s32(arg_i32x4, 0); + vdupq_laneq_s32(arg_i32x4, 3); + vdupq_laneq_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_s32(arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_s64(int64x1_t arg_i64x1, int64x2_t arg_i64x2) { + vdup_lane_s64(arg_i64x1, 0); + vdup_lane_s64(arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_s64(arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_s64(arg_i64x1, 0); + vdupq_lane_s64(arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_s64(arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_s64(arg_i64x2, 0); + vdup_laneq_s64(arg_i64x2, 1); + vdup_laneq_s64(arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_s64(arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_s64(arg_i64x2, 0); + vdupq_laneq_s64(arg_i64x2, 1); + vdupq_laneq_s64(arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_s64(arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vdup_lane_u8(arg_u8x8, 0); + vdup_lane_u8(arg_u8x8, 7); + vdup_lane_u8(arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_u8(arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_u8(arg_u8x8, 0); + vdupq_lane_u8(arg_u8x8, 7); + vdupq_lane_u8(arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_u8(arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_u8(arg_u8x16, 0); + vdup_laneq_u8(arg_u8x16, 15); + vdup_laneq_u8(arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_u8(arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_u8(arg_u8x16, 0); + vdupq_laneq_u8(arg_u8x16, 15); + vdupq_laneq_u8(arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_u8(arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_u16(uint16x4_t arg_u16x4, uint16x8_t arg_u16x8) { + vdup_lane_u16(arg_u16x4, 0); + vdup_lane_u16(arg_u16x4, 3); + vdup_lane_u16(arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_u16(arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_u16(arg_u16x4, 0); + vdupq_lane_u16(arg_u16x4, 3); + vdupq_lane_u16(arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_u16(arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_u16(arg_u16x8, 0); + vdup_laneq_u16(arg_u16x8, 7); + vdup_laneq_u16(arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_u16(arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_u16(arg_u16x8, 0); + vdupq_laneq_u16(arg_u16x8, 7); + vdupq_laneq_u16(arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_u16(arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_u32(uint32x4_t arg_u32x4, uint32x2_t arg_u32x2) { + vdup_lane_u32(arg_u32x2, 0); + vdup_lane_u32(arg_u32x2, 1); + vdup_lane_u32(arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_u32(arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_u32(arg_u32x2, 0); + vdupq_lane_u32(arg_u32x2, 1); + vdupq_lane_u32(arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_u32(arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_u32(arg_u32x4, 0); + vdup_laneq_u32(arg_u32x4, 3); + vdup_laneq_u32(arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_u32(arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_u32(arg_u32x4, 0); + vdupq_laneq_u32(arg_u32x4, 3); + vdupq_laneq_u32(arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_u32(arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_u64(uint64x1_t arg_u64x1, uint64x2_t arg_u64x2) { + vdup_lane_u64(arg_u64x1, 0); + vdup_lane_u64(arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_u64(arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_u64(arg_u64x1, 0); + vdupq_lane_u64(arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_u64(arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_u64(arg_u64x2, 0); + vdup_laneq_u64(arg_u64x2, 1); + vdup_laneq_u64(arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_u64(arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_u64(arg_u64x2, 0); + vdupq_laneq_u64(arg_u64x2, 1); + vdupq_laneq_u64(arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_u64(arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_p64(poly64x1_t arg_p64x1, poly64x2_t arg_p64x2) { + vdup_lane_p64(arg_p64x1, 0); + vdup_lane_p64(arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_p64(arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_p64(arg_p64x1, 0); + vdupq_lane_p64(arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_p64(arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_p64(arg_p64x2, 0); + vdup_laneq_p64(arg_p64x2, 1); + vdup_laneq_p64(arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_p64(arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_p64(arg_p64x2, 0); + vdupq_laneq_p64(arg_p64x2, 1); + vdupq_laneq_p64(arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_p64(arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_f32(float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vdup_lane_f32(arg_f32x2, 0); + vdup_lane_f32(arg_f32x2, 1); + vdup_lane_f32(arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_f32(arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_f32(arg_f32x2, 0); + vdupq_lane_f32(arg_f32x2, 1); + vdupq_lane_f32(arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_f32(arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_f32(arg_f32x4, 0); + vdup_laneq_f32(arg_f32x4, 3); + vdup_laneq_f32(arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_f32(arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_f32(arg_f32x4, 0); + vdupq_laneq_f32(arg_f32x4, 3); + vdupq_laneq_f32(arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_f32(arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_p8(poly8x16_t arg_p8x16, poly8x8_t arg_p8x8) { + vdup_lane_p8(arg_p8x8, 0); + vdup_lane_p8(arg_p8x8, 7); + vdup_lane_p8(arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_p8(arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_p8(arg_p8x8, 0); + vdupq_lane_p8(arg_p8x8, 7); + vdupq_lane_p8(arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_p8(arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_p8(arg_p8x16, 0); + vdup_laneq_p8(arg_p8x16, 15); + vdup_laneq_p8(arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_p8(arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_p8(arg_p8x16, 0); + vdupq_laneq_p8(arg_p8x16, 15); + vdupq_laneq_p8(arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_p8(arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_p16(poly16x4_t arg_p16x4, poly16x8_t arg_p16x8) { + vdup_lane_p16(arg_p16x4, 0); + vdup_lane_p16(arg_p16x4, 3); + vdup_lane_p16(arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_p16(arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_p16(arg_p16x4, 0); + vdupq_lane_p16(arg_p16x4, 3); + vdupq_lane_p16(arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_p16(arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_p16(arg_p16x8, 0); + vdup_laneq_p16(arg_p16x8, 7); + vdup_laneq_p16(arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_p16(arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_p16(arg_p16x8, 0); + vdupq_laneq_p16(arg_p16x8, 7); + vdupq_laneq_p16(arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_p16(arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_all_lanes_to_the_same_value_f64(float64x2_t arg_f64x2, float64x1_t arg_f64x1) { + vdup_lane_f64(arg_f64x1, 0); + vdup_lane_f64(arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_lane_f64(arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_lane_f64(arg_f64x1, 0); + vdupq_lane_f64(arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_lane_f64(arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdup_laneq_f64(arg_f64x2, 0); + vdup_laneq_f64(arg_f64x2, 1); + vdup_laneq_f64(arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdup_laneq_f64(arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vdupq_laneq_f64(arg_f64x2, 0); + vdupq_laneq_f64(arg_f64x2, 1); + vdupq_laneq_f64(arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vdupq_laneq_f64(arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/set-vector-lane.c b/clang/test/Sema/aarch64-neon-immediate-ranges/set-vector-lane.c new file mode 100644 index 0000000000000..3ab077ed56287 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/set-vector-lane.c @@ -0,0 +1,162 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + +// vsetq_lane_u8, vsetq_lane_u16, vsetq_lane_u32, vsetq_lane_u64 are +// tesed under clang/test/Sema/arm-mve-immediates.c + +void test_set_vector_lane_u8(uint8x16_t arg_u8x16, uint8_t arg_u8, uint8x8_t arg_u8x8) { + vset_lane_u8(arg_u8, arg_u8x8, 0); + vset_lane_u8(arg_u8, arg_u8x8, 7); + vset_lane_u8(arg_u8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_u8(arg_u8, arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_set_vector_lane_u16(uint16x4_t arg_u16x4, uint16_t arg_u16, uint16x8_t arg_u16x8) { + vset_lane_u16(arg_u16, arg_u16x4, 0); + vset_lane_u16(arg_u16, arg_u16x4, 3); + vset_lane_u16(arg_u16, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_u16(arg_u16, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_set_vector_lane_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4, uint32_t arg_u32) { + vset_lane_u32(arg_u32, arg_u32x2, 0); + vset_lane_u32(arg_u32, arg_u32x2, 1); + vset_lane_u32(arg_u32, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_u32(arg_u32, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_set_vector_lane_u64(uint64x2_t arg_u64x2, uint64x1_t arg_u64x1, uint64_t arg_u64) { + vset_lane_u64(arg_u64, arg_u64x1, 0); + vset_lane_u64(arg_u64, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_u64(arg_u64, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_set_vector_lane_p64(poly64_t arg_p64, poly64x1_t arg_p64x1, poly64x2_t arg_p64x2) { + vset_lane_p64(arg_p64, arg_p64x1, 0); + vset_lane_p64(arg_p64, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_p64(arg_p64, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_p64(arg_p64, arg_p64x2, 0); + vsetq_lane_p64(arg_p64, arg_p64x2, 1); + vsetq_lane_p64(arg_p64, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_p64(arg_p64, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_s8(int8x16_t arg_i8x16, int8x8_t arg_i8x8, int8_t arg_i8) { + vset_lane_s8(arg_i8, arg_i8x8, 0); + vset_lane_s8(arg_i8, arg_i8x8, 7); + vset_lane_s8(arg_i8, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_s8(arg_i8, arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_s8(arg_i8, arg_i8x16, 0); + vsetq_lane_s8(arg_i8, arg_i8x16, 15); + vsetq_lane_s8(arg_i8, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_s8(arg_i8, arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_s16(int16x4_t arg_i16x4, int16_t arg_i16, int16x8_t arg_i16x8) { + vset_lane_s16(arg_i16, arg_i16x4, 0); + vset_lane_s16(arg_i16, arg_i16x4, 3); + vset_lane_s16(arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_s16(arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_s16(arg_i16, arg_i16x8, 0); + vsetq_lane_s16(arg_i16, arg_i16x8, 7); + vsetq_lane_s16(arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_s16(arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_s32(int32_t arg_i32, int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vset_lane_s32(arg_i32, arg_i32x2, 0); + vset_lane_s32(arg_i32, arg_i32x2, 1); + vset_lane_s32(arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_s32(arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_s32(arg_i32, arg_i32x4, 0); + vsetq_lane_s32(arg_i32, arg_i32x4, 3); + vsetq_lane_s32(arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_s32(arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_s64(int64_t arg_i64, int64x2_t arg_i64x2, int64x1_t arg_i64x1) { + vset_lane_s64(arg_i64, arg_i64x1, 0); + vset_lane_s64(arg_i64, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_s64(arg_i64, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_s64(arg_i64, arg_i64x2, 0); + vsetq_lane_s64(arg_i64, arg_i64x2, 1); + vsetq_lane_s64(arg_i64, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_s64(arg_i64, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_p8(poly8_t arg_p8, poly8x16_t arg_p8x16, poly8x8_t arg_p8x8) { + vset_lane_p8(arg_p8, arg_p8x8, 0); + vset_lane_p8(arg_p8, arg_p8x8, 7); + vset_lane_p8(arg_p8, arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_p8(arg_p8, arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_p8(arg_p8, arg_p8x16, 0); + vsetq_lane_p8(arg_p8, arg_p8x16, 15); + vsetq_lane_p8(arg_p8, arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_p8(arg_p8, arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_p16(poly16x4_t arg_p16x4, poly16_t arg_p16, poly16x8_t arg_p16x8) { + vset_lane_p16(arg_p16, arg_p16x4, 0); + vset_lane_p16(arg_p16, arg_p16x4, 3); + vset_lane_p16(arg_p16, arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_p16(arg_p16, arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_p16(arg_p16, arg_p16x8, 0); + vsetq_lane_p16(arg_p16, arg_p16x8, 7); + vsetq_lane_p16(arg_p16, arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_p16(arg_p16, arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_f16(float16x8_t arg_f16x8, float16x4_t arg_f16x4, float16_t arg_f16) { + vset_lane_f16(arg_f16, arg_f16x4, 0); + vset_lane_f16(arg_f16, arg_f16x4, 3); + vset_lane_f16(arg_f16, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_f16(arg_f16, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_f16(arg_f16, arg_f16x8, 0); + vsetq_lane_f16(arg_f16, arg_f16x8, 7); + vsetq_lane_f16(arg_f16, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_f16(arg_f16, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_f32(float32x2_t arg_f32x2, float32x4_t arg_f32x4, float32_t arg_f32) { + vset_lane_f32(arg_f32, arg_f32x2, 0); + vset_lane_f32(arg_f32, arg_f32x2, 1); + vset_lane_f32(arg_f32, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_f32(arg_f32, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_f32(arg_f32, arg_f32x4, 0); + vsetq_lane_f32(arg_f32, arg_f32x4, 3); + vsetq_lane_f32(arg_f32, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_f32(arg_f32, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_set_vector_lane_f64(float64x1_t arg_f64x1, float64x2_t arg_f64x2, float64_t arg_f64) { + vset_lane_f64(arg_f64, arg_f64x1, 0); + vset_lane_f64(arg_f64, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vset_lane_f64(arg_f64, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsetq_lane_f64(arg_f64, arg_f64x2, 0); + vsetq_lane_f64(arg_f64, arg_f64x2, 1); + vsetq_lane_f64(arg_f64, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsetq_lane_f64(arg_f64, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/sqrdmlah-ranges.c b/clang/test/Sema/aarch64-neon-immediate-ranges/sqrdmlah-ranges.c new file mode 100644 index 0000000000000..2439fb79737e6 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/sqrdmlah-ranges.c @@ -0,0 +1,130 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +v8.1a -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + +void test_saturating_multiply_accumulate_by_element_s16(int16x8_t arg_i16x8, int16_t arg_i16, int16x4_t arg_i16x4) { + vqrdmlah_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 0); + vqrdmlah_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 3); + vqrdmlah_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlah_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 0); + vqrdmlahq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 3); + vqrdmlahq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlah_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 0); + vqrdmlah_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 7); + vqrdmlah_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlah_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 0); + vqrdmlahq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 7); + vqrdmlahq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlsh_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 0); + vqrdmlsh_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 3); + vqrdmlsh_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlsh_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 0); + vqrdmlshq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 3); + vqrdmlshq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlsh_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 0); + vqrdmlsh_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 7); + vqrdmlsh_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlsh_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 0); + vqrdmlshq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 7); + vqrdmlshq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahh_lane_s16(arg_i16, arg_i16, arg_i16x4, 0); + vqrdmlahh_lane_s16(arg_i16, arg_i16, arg_i16x4, 3); + vqrdmlahh_lane_s16(arg_i16, arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahh_lane_s16(arg_i16, arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahh_laneq_s16(arg_i16, arg_i16, arg_i16x8, 0); + vqrdmlahh_laneq_s16(arg_i16, arg_i16, arg_i16x8, 7); + vqrdmlahh_laneq_s16(arg_i16, arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahh_laneq_s16(arg_i16, arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshh_lane_s16(arg_i16, arg_i16, arg_i16x4, 0); + vqrdmlshh_lane_s16(arg_i16, arg_i16, arg_i16x4, 3); + vqrdmlshh_lane_s16(arg_i16, arg_i16, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshh_lane_s16(arg_i16, arg_i16, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshh_laneq_s16(arg_i16, arg_i16, arg_i16x8, 0); + vqrdmlshh_laneq_s16(arg_i16, arg_i16, arg_i16x8, 7); + vqrdmlshh_laneq_s16(arg_i16, arg_i16, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshh_laneq_s16(arg_i16, arg_i16, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_saturating_multiply_accumulate_by_element_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4, int32_t arg_i32) { + vqrdmlah_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 0); + vqrdmlah_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 1); + vqrdmlah_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlah_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 0); + vqrdmlahq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 1); + vqrdmlahq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlah_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 0); + vqrdmlah_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 3); + vqrdmlah_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlah_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 0); + vqrdmlahq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 3); + vqrdmlahq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlsh_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 0); + vqrdmlsh_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 1); + vqrdmlsh_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlsh_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 0); + vqrdmlshq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 1); + vqrdmlshq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlsh_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 0); + vqrdmlsh_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 3); + vqrdmlsh_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlsh_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 0); + vqrdmlshq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 3); + vqrdmlshq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahs_lane_s32(arg_i32, arg_i32, arg_i32x2, 0); + vqrdmlahs_lane_s32(arg_i32, arg_i32, arg_i32x2, 1); + vqrdmlahs_lane_s32(arg_i32, arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahs_lane_s32(arg_i32, arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlahs_laneq_s32(arg_i32, arg_i32, arg_i32x4, 0); + vqrdmlahs_laneq_s32(arg_i32, arg_i32, arg_i32x4, 3); + vqrdmlahs_laneq_s32(arg_i32, arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlahs_laneq_s32(arg_i32, arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshs_lane_s32(arg_i32, arg_i32, arg_i32x2, 0); + vqrdmlshs_lane_s32(arg_i32, arg_i32, arg_i32x2, 1); + vqrdmlshs_lane_s32(arg_i32, arg_i32, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshs_lane_s32(arg_i32, arg_i32, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrdmlshs_laneq_s32(arg_i32, arg_i32, arg_i32x4, 0); + vqrdmlshs_laneq_s32(arg_i32, arg_i32, arg_i32x4, 3); + vqrdmlshs_laneq_s32(arg_i32, arg_i32, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrdmlshs_laneq_s32(arg_i32, arg_i32, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vcmla.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vcmla.c new file mode 100644 index 0000000000000..21c24975b38b3 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vcmla.c @@ -0,0 +1,203 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +v8.3a -ffreestanding -fsyntax-only -verify %s +// REQUIRES: aarch64-registered-target + +#include +#include + +void test_vcmla_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c){ + vcmla_lane_f16(a, b, c, 0); + vcmla_lane_f16(a, b, c, 1); + + vcmla_lane_f16(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_lane_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c){ + vcmla_laneq_f16(a, b, c, 0); + vcmla_laneq_f16(a, b, c, 1); + vcmla_laneq_f16(a, b, c, 3); + + vcmla_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_lane_f16(float16x8_t a, float16x8_t b, float16x4_t c){ + vcmlaq_lane_f16(a, b, c, 0); + vcmlaq_lane_f16(a, b, c, 1); + + vcmlaq_lane_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_lane_f16(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c){ + vcmlaq_laneq_f16(a, b, c, 0); + vcmlaq_laneq_f16(a, b, c, 1); + vcmlaq_laneq_f16(a, b, c, 3); + + vcmlaq_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c){ + vcmla_lane_f32(a, b, c, 0); + + vcmla_lane_f32(a, b, c, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_lane_f32(a, b, c, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_lane_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t c){ + vcmla_laneq_f32(a, b, c, 0); + + vcmla_laneq_f32(a, b, c, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_laneq_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t c){ + vcmlaq_laneq_f32(a, b, c, 0); + vcmlaq_laneq_f32(a, b, c, 1); + + vcmlaq_laneq_f32(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_laneq_f32(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot90_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c){ + vcmla_rot90_lane_f16(a, b, c, 0); + vcmla_rot90_lane_f16(a, b, c, 1); + + vcmla_rot90_lane_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_rot90_lane_f16(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot90_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c){ + vcmla_rot90_laneq_f16(a, b, c, 0); + vcmla_rot90_laneq_f16(a, b, c, 3); + + vcmla_rot90_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_rot90_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_rot90_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c){ + vcmlaq_rot90_laneq_f16(a, b, c, 0); + vcmlaq_rot90_laneq_f16(a, b, c, 3); + + vcmlaq_rot90_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_rot90_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot180_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c){ + vcmla_rot180_lane_f16(a, b, c, 0); + vcmla_rot180_lane_f16(a, b, c, 1); + + vcmla_rot180_lane_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_rot180_lane_f16(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot180_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c){ + vcmla_rot180_laneq_f16(a, b, c, 0); + vcmla_rot180_laneq_f16(a, b, c, 3); + + vcmla_rot180_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_rot180_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_rot180_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c){ + vcmlaq_rot180_laneq_f16(a, b, c, 0); + vcmlaq_rot180_laneq_f16(a, b, c, 3); + + vcmlaq_rot180_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_rot180_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot270_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c){ + vcmla_rot270_lane_f16(a, b, c, 0); + vcmla_rot270_lane_f16(a, b, c, 1); + + vcmla_rot270_lane_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_rot270_lane_f16(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot270_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c){ + vcmla_rot270_laneq_f16(a, b, c, 0); + vcmla_rot270_laneq_f16(a, b, c, 3); + + vcmla_rot270_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmla_rot270_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_rot270_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c){ + vcmlaq_rot270_laneq_f16(a, b, c, 0); + vcmlaq_rot270_laneq_f16(a, b, c, 3); + + vcmlaq_rot270_laneq_f16(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_rot270_laneq_f16(a, b, c, 4); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot90_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c){ + vcmla_rot90_lane_f32(a, b, c, 0); + + vcmla_rot90_lane_f32(a, b, c, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_rot90_lane_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot90_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t c){ + vcmla_rot90_laneq_f32(a, b, c, 0); + vcmla_rot90_laneq_f32(a, b, c, 1); + + vcmla_rot90_laneq_f32(a, b, c, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_rot90_laneq_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_rot90_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t c){ + vcmlaq_rot90_laneq_f32(a, b, c, 0); + vcmlaq_rot90_laneq_f32(a, b, c, 1); + + vcmlaq_rot90_laneq_f32(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_rot90_laneq_f32(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot180_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c){ + vcmla_rot180_lane_f32(a, b, c, 0); + + vcmla_rot180_lane_f32(a, b, c, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_rot180_lane_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot180_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t c){ + vcmla_rot180_laneq_f32(a, b, c, 0); + vcmla_rot180_laneq_f32(a, b, c, 1); + + vcmla_rot180_laneq_f32(a, b, c, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_rot180_laneq_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_rot180_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t c){ + vcmlaq_rot90_laneq_f32(a, b, c, 0); + vcmlaq_rot90_laneq_f32(a, b, c, 1); + + vcmlaq_rot90_laneq_f32(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_rot90_laneq_f32(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot270_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c){ + vcmla_rot270_lane_f32(a, b, c, 0); + + vcmla_rot270_lane_f32(a, b, c, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_rot270_lane_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmla_rot270_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t c){ + vcmla_rot270_laneq_f32(a, b, c, 0); + vcmla_rot270_laneq_f32(a, b, c, 1); + + vcmla_rot270_laneq_f32(a, b, c, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vcmla_rot270_laneq_f32(a, b, c, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vcmlaq_rot270_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t c){ + vcmlaq_rot270_laneq_f32(a, b, c, 0); + vcmlaq_rot270_laneq_f32(a, b, c, 1); + + vcmlaq_rot270_laneq_f32(a, b, c, 2); // expected-error-re +{{argument value {{.*}} is outside the valid range}} + vcmlaq_rot270_laneq_f32(a, b, c, -1); // expected-error-re +{{argument value {{.*}} is outside the valid range}} +} \ No newline at end of file diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-load.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-load.c new file mode 100644 index 0000000000000..3259d47e1b625 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-load.c @@ -0,0 +1,692 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_vector_load_s8(int8x8x2_t arg_i8x8x2, int8x8x3_t arg_i8x8x3, int8x16x2_t arg_i8x16x2, + int8x16x3_t arg_i8x16x3, int8x8_t arg_i8x8, int8x16x4_t arg_i8x16x4, + int8x16_t arg_i8x16, int8x8x4_t arg_i8x8x4, int8_t* arg_i8_ptr) { + vld1_lane_s8(arg_i8_ptr, arg_i8x8, 0); + vld1_lane_s8(arg_i8_ptr, arg_i8x8, 7); + vld1_lane_s8(arg_i8_ptr, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_s8(arg_i8_ptr, arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_s8(arg_i8_ptr, arg_i8x16, 0); + vld1q_lane_s8(arg_i8_ptr, arg_i8x16, 15); + vld1q_lane_s8(arg_i8_ptr, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_s8(arg_i8_ptr, arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_s8(arg_i8_ptr, arg_i8x8x2, 0); + vld2_lane_s8(arg_i8_ptr, arg_i8x8x2, 7); + vld2_lane_s8(arg_i8_ptr, arg_i8x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_s8(arg_i8_ptr, arg_i8x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_s8(arg_i8_ptr, arg_i8x16x2, 0); + vld2q_lane_s8(arg_i8_ptr, arg_i8x16x2, 15); + vld2q_lane_s8(arg_i8_ptr, arg_i8x16x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_s8(arg_i8_ptr, arg_i8x16x2, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_s8(arg_i8_ptr, arg_i8x8x3, 0); + vld3_lane_s8(arg_i8_ptr, arg_i8x8x3, 7); + vld3_lane_s8(arg_i8_ptr, arg_i8x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_s8(arg_i8_ptr, arg_i8x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_s8(arg_i8_ptr, arg_i8x16x3, 0); + vld3q_lane_s8(arg_i8_ptr, arg_i8x16x3, 15); + vld3q_lane_s8(arg_i8_ptr, arg_i8x16x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_s8(arg_i8_ptr, arg_i8x16x3, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_s8(arg_i8_ptr, arg_i8x8x4, 0); + vld4_lane_s8(arg_i8_ptr, arg_i8x8x4, 7); + vld4_lane_s8(arg_i8_ptr, arg_i8x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_s8(arg_i8_ptr, arg_i8x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_s8(arg_i8_ptr, arg_i8x16x4, 0); + vld4q_lane_s8(arg_i8_ptr, arg_i8x16x4, 15); + vld4q_lane_s8(arg_i8_ptr, arg_i8x16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_s8(arg_i8_ptr, arg_i8x16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_s16(int16x8x2_t arg_i16x8x2, int16x8x3_t arg_i16x8x3, int16x8x4_t arg_i16x8x4, + int16_t* arg_i16_ptr, int16x4x2_t arg_i16x4x2, int16x4x3_t arg_i16x4x3, + int16x8_t arg_i16x8, int16x4x4_t arg_i16x4x4, int16x4_t arg_i16x4) { + vld1_lane_s16(arg_i16_ptr, arg_i16x4, 0); + vld1_lane_s16(arg_i16_ptr, arg_i16x4, 3); + vld1_lane_s16(arg_i16_ptr, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_s16(arg_i16_ptr, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_s16(arg_i16_ptr, arg_i16x8, 0); + vld1q_lane_s16(arg_i16_ptr, arg_i16x8, 7); + vld1q_lane_s16(arg_i16_ptr, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_s16(arg_i16_ptr, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_s16(arg_i16_ptr, arg_i16x4x2, 0); + vld2_lane_s16(arg_i16_ptr, arg_i16x4x2, 3); + vld2_lane_s16(arg_i16_ptr, arg_i16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_s16(arg_i16_ptr, arg_i16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_s16(arg_i16_ptr, arg_i16x8x2, 0); + vld2q_lane_s16(arg_i16_ptr, arg_i16x8x2, 7); + vld2q_lane_s16(arg_i16_ptr, arg_i16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_s16(arg_i16_ptr, arg_i16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_s16(arg_i16_ptr, arg_i16x4x3, 0); + vld3_lane_s16(arg_i16_ptr, arg_i16x4x3, 3); + vld3_lane_s16(arg_i16_ptr, arg_i16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_s16(arg_i16_ptr, arg_i16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_s16(arg_i16_ptr, arg_i16x8x3, 0); + vld3q_lane_s16(arg_i16_ptr, arg_i16x8x3, 7); + vld3q_lane_s16(arg_i16_ptr, arg_i16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_s16(arg_i16_ptr, arg_i16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_s16(arg_i16_ptr, arg_i16x4x4, 0); + vld4_lane_s16(arg_i16_ptr, arg_i16x4x4, 3); + vld4_lane_s16(arg_i16_ptr, arg_i16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_s16(arg_i16_ptr, arg_i16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_s16(arg_i16_ptr, arg_i16x8x4, 0); + vld4q_lane_s16(arg_i16_ptr, arg_i16x8x4, 7); + vld4q_lane_s16(arg_i16_ptr, arg_i16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_s16(arg_i16_ptr, arg_i16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_s32(int32x2x4_t arg_i32x2x4, int32x4_t arg_i32x4, int32x2_t arg_i32x2, + int32x4x2_t arg_i32x4x2, int32x4x4_t arg_i32x4x4, int32_t* arg_i32_ptr, + int32x2x3_t arg_i32x2x3, int32x4x3_t arg_i32x4x3, int32x2x2_t arg_i32x2x2) { + vld1_lane_s32(arg_i32_ptr, arg_i32x2, 0); + vld1_lane_s32(arg_i32_ptr, arg_i32x2, 1); + vld1_lane_s32(arg_i32_ptr, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_s32(arg_i32_ptr, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_s32(arg_i32_ptr, arg_i32x4, 0); + vld1q_lane_s32(arg_i32_ptr, arg_i32x4, 3); + vld1q_lane_s32(arg_i32_ptr, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_s32(arg_i32_ptr, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_s32(arg_i32_ptr, arg_i32x2x2, 0); + vld2_lane_s32(arg_i32_ptr, arg_i32x2x2, 1); + vld2_lane_s32(arg_i32_ptr, arg_i32x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_s32(arg_i32_ptr, arg_i32x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_s32(arg_i32_ptr, arg_i32x4x2, 0); + vld2q_lane_s32(arg_i32_ptr, arg_i32x4x2, 3); + vld2q_lane_s32(arg_i32_ptr, arg_i32x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_s32(arg_i32_ptr, arg_i32x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_s32(arg_i32_ptr, arg_i32x2x3, 0); + vld3_lane_s32(arg_i32_ptr, arg_i32x2x3, 1); + vld3_lane_s32(arg_i32_ptr, arg_i32x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_s32(arg_i32_ptr, arg_i32x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_s32(arg_i32_ptr, arg_i32x4x3, 0); + vld3q_lane_s32(arg_i32_ptr, arg_i32x4x3, 3); + vld3q_lane_s32(arg_i32_ptr, arg_i32x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_s32(arg_i32_ptr, arg_i32x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_s32(arg_i32_ptr, arg_i32x2x4, 0); + vld4_lane_s32(arg_i32_ptr, arg_i32x2x4, 1); + vld4_lane_s32(arg_i32_ptr, arg_i32x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_s32(arg_i32_ptr, arg_i32x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_s32(arg_i32_ptr, arg_i32x4x4, 0); + vld4q_lane_s32(arg_i32_ptr, arg_i32x4x4, 3); + vld4q_lane_s32(arg_i32_ptr, arg_i32x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_s32(arg_i32_ptr, arg_i32x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_s64(int64x1x4_t arg_i64x1x4, int64x1_t arg_i64x1, int64x2x2_t arg_i64x2x2, + int64x2x4_t arg_i64x2x4, int64x1x3_t arg_i64x1x3, int64x1x2_t arg_i64x1x2, + int64x2_t arg_i64x2, int64x2x3_t arg_i64x2x3, int64_t* arg_i64_ptr) { + vld1_lane_s64(arg_i64_ptr, arg_i64x1, 0); + vld1_lane_s64(arg_i64_ptr, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_s64(arg_i64_ptr, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_s64(arg_i64_ptr, arg_i64x2, 0); + vld1q_lane_s64(arg_i64_ptr, arg_i64x2, 1); + vld1q_lane_s64(arg_i64_ptr, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_s64(arg_i64_ptr, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1_lane_s64(arg_i64_ptr, arg_i64x1, 0); + vldap1_lane_s64(arg_i64_ptr, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1_lane_s64(arg_i64_ptr, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1q_lane_s64(arg_i64_ptr, arg_i64x2, 0); + vldap1q_lane_s64(arg_i64_ptr, arg_i64x2, 1); + vldap1q_lane_s64(arg_i64_ptr, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1q_lane_s64(arg_i64_ptr, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1_lane_s64(arg_i64_ptr, arg_i64x1, 0); + vstl1_lane_s64(arg_i64_ptr, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1_lane_s64(arg_i64_ptr, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1q_lane_s64(arg_i64_ptr, arg_i64x2, 0); + vstl1q_lane_s64(arg_i64_ptr, arg_i64x2, 1); + vstl1q_lane_s64(arg_i64_ptr, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1q_lane_s64(arg_i64_ptr, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_s64(arg_i64_ptr, arg_i64x1x2, 0); + vld2_lane_s64(arg_i64_ptr, arg_i64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_s64(arg_i64_ptr, arg_i64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_s64(arg_i64_ptr, arg_i64x2x2, 0); + vld2q_lane_s64(arg_i64_ptr, arg_i64x2x2, 1); + vld2q_lane_s64(arg_i64_ptr, arg_i64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_s64(arg_i64_ptr, arg_i64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_s64(arg_i64_ptr, arg_i64x1x3, 0); + vld3_lane_s64(arg_i64_ptr, arg_i64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_s64(arg_i64_ptr, arg_i64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_s64(arg_i64_ptr, arg_i64x2x3, 0); + vld3q_lane_s64(arg_i64_ptr, arg_i64x2x3, 1); + vld3q_lane_s64(arg_i64_ptr, arg_i64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_s64(arg_i64_ptr, arg_i64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_s64(arg_i64_ptr, arg_i64x1x4, 0); + vld4_lane_s64(arg_i64_ptr, arg_i64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_s64(arg_i64_ptr, arg_i64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_s64(arg_i64_ptr, arg_i64x2x4, 0); + vld4q_lane_s64(arg_i64_ptr, arg_i64x2x4, 1); + vld4q_lane_s64(arg_i64_ptr, arg_i64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_s64(arg_i64_ptr, arg_i64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_u8(uint8x8x2_t arg_u8x8x2, uint8x16x2_t arg_u8x16x2, uint8x8x4_t arg_u8x8x4, + uint8x8_t arg_u8x8, uint8x8x3_t arg_u8x8x3, uint8x16_t arg_u8x16, + uint8x16x4_t arg_u8x16x4, uint8_t *arg_u8_ptr, uint8x16x3_t arg_u8x16x3) { + vld1_lane_u8(arg_u8_ptr, arg_u8x8, 0); + vld1_lane_u8(arg_u8_ptr, arg_u8x8, 7); + vld1_lane_u8(arg_u8_ptr, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_u8(arg_u8_ptr, arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_u8(arg_u8_ptr, arg_u8x16, 0); + vld1q_lane_u8(arg_u8_ptr, arg_u8x16, 15); + vld1q_lane_u8(arg_u8_ptr, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_u8(arg_u8_ptr, arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_u8(arg_u8_ptr, arg_u8x8x2, 0); + vld2_lane_u8(arg_u8_ptr, arg_u8x8x2, 7); + vld2_lane_u8(arg_u8_ptr, arg_u8x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_u8(arg_u8_ptr, arg_u8x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_u8(arg_u8_ptr, arg_u8x16x2, 0); + vld2q_lane_u8(arg_u8_ptr, arg_u8x16x2, 15); + vld2q_lane_u8(arg_u8_ptr, arg_u8x16x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_u8(arg_u8_ptr, arg_u8x16x2, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_u8(arg_u8_ptr, arg_u8x8x3, 0); + vld3_lane_u8(arg_u8_ptr, arg_u8x8x3, 7); + vld3_lane_u8(arg_u8_ptr, arg_u8x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_u8(arg_u8_ptr, arg_u8x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_u8(arg_u8_ptr, arg_u8x16x3, 0); + vld3q_lane_u8(arg_u8_ptr, arg_u8x16x3, 15); + vld3q_lane_u8(arg_u8_ptr, arg_u8x16x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_u8(arg_u8_ptr, arg_u8x16x3, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_u8(arg_u8_ptr, arg_u8x8x4, 0); + vld4_lane_u8(arg_u8_ptr, arg_u8x8x4, 7); + vld4_lane_u8(arg_u8_ptr, arg_u8x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_u8(arg_u8_ptr, arg_u8x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_u8(arg_u8_ptr, arg_u8x16x4, 0); + vld4q_lane_u8(arg_u8_ptr, arg_u8x16x4, 15); + vld4q_lane_u8(arg_u8_ptr, arg_u8x16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_u8(arg_u8_ptr, arg_u8x16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_u16(uint16x8x2_t arg_u16x8x2, uint16x8x4_t arg_u16x8x4, uint16x4x4_t arg_u16x4x4, + uint16x4x2_t arg_u16x4x2, uint16x8_t arg_u16x8, uint16_t *arg_u16_ptr, + uint16x8x3_t arg_u16x8x3, uint16x4_t arg_u16x4, uint16x4x3_t arg_u16x4x3) { + vld1_lane_u16(arg_u16_ptr, arg_u16x4, 0); + vld1_lane_u16(arg_u16_ptr, arg_u16x4, 3); + vld1_lane_u16(arg_u16_ptr, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_u16(arg_u16_ptr, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_u16(arg_u16_ptr, arg_u16x8, 0); + vld1q_lane_u16(arg_u16_ptr, arg_u16x8, 7); + vld1q_lane_u16(arg_u16_ptr, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_u16(arg_u16_ptr, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_u16(arg_u16_ptr, arg_u16x4x2, 0); + vld2_lane_u16(arg_u16_ptr, arg_u16x4x2, 3); + vld2_lane_u16(arg_u16_ptr, arg_u16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_u16(arg_u16_ptr, arg_u16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_u16(arg_u16_ptr, arg_u16x8x2, 0); + vld2q_lane_u16(arg_u16_ptr, arg_u16x8x2, 7); + vld2q_lane_u16(arg_u16_ptr, arg_u16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_u16(arg_u16_ptr, arg_u16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_u16(arg_u16_ptr, arg_u16x4x3, 0); + vld3_lane_u16(arg_u16_ptr, arg_u16x4x3, 3); + vld3_lane_u16(arg_u16_ptr, arg_u16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_u16(arg_u16_ptr, arg_u16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_u16(arg_u16_ptr, arg_u16x8x3, 0); + vld3q_lane_u16(arg_u16_ptr, arg_u16x8x3, 7); + vld3q_lane_u16(arg_u16_ptr, arg_u16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_u16(arg_u16_ptr, arg_u16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_u16(arg_u16_ptr, arg_u16x4x4, 0); + vld4_lane_u16(arg_u16_ptr, arg_u16x4x4, 3); + vld4_lane_u16(arg_u16_ptr, arg_u16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_u16(arg_u16_ptr, arg_u16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_u16(arg_u16_ptr, arg_u16x8x4, 0); + vld4q_lane_u16(arg_u16_ptr, arg_u16x8x4, 7); + vld4q_lane_u16(arg_u16_ptr, arg_u16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_u16(arg_u16_ptr, arg_u16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_u32(uint32x2x3_t arg_u32x2x3, uint32x2_t arg_u32x2, uint32x2x4_t arg_u32x2x4, + uint32x4_t arg_u32x4, uint32x4x2_t arg_u32x4x2, uint32x2x2_t arg_u32x2x2, + void *arg_u32_ptr, uint32x4x4_t arg_u32x4x4, uint32x4x3_t arg_u32x4x3) { + vld1_lane_u32(arg_u32_ptr, arg_u32x2, 0); + vld1_lane_u32(arg_u32_ptr, arg_u32x2, 1); + vld1_lane_u32(arg_u32_ptr, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_u32(arg_u32_ptr, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_u32(arg_u32_ptr, arg_u32x4, 0); + vld1q_lane_u32(arg_u32_ptr, arg_u32x4, 3); + vld1q_lane_u32(arg_u32_ptr, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_u32(arg_u32_ptr, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_u32(arg_u32_ptr, arg_u32x2x2, 0); + vld2_lane_u32(arg_u32_ptr, arg_u32x2x2, 1); + vld2_lane_u32(arg_u32_ptr, arg_u32x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_u32(arg_u32_ptr, arg_u32x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_u32(arg_u32_ptr, arg_u32x4x2, 0); + vld2q_lane_u32(arg_u32_ptr, arg_u32x4x2, 3); + vld2q_lane_u32(arg_u32_ptr, arg_u32x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_u32(arg_u32_ptr, arg_u32x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_u32(arg_u32_ptr, arg_u32x2x3, 0); + vld3_lane_u32(arg_u32_ptr, arg_u32x2x3, 1); + vld3_lane_u32(arg_u32_ptr, arg_u32x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_u32(arg_u32_ptr, arg_u32x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_u32(arg_u32_ptr, arg_u32x4x3, 0); + vld3q_lane_u32(arg_u32_ptr, arg_u32x4x3, 3); + vld3q_lane_u32(arg_u32_ptr, arg_u32x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_u32(arg_u32_ptr, arg_u32x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_u32(arg_u32_ptr, arg_u32x2x4, 0); + vld4_lane_u32(arg_u32_ptr, arg_u32x2x4, 1); + vld4_lane_u32(arg_u32_ptr, arg_u32x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_u32(arg_u32_ptr, arg_u32x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_u32(arg_u32_ptr, arg_u32x4x4, 0); + vld4q_lane_u32(arg_u32_ptr, arg_u32x4x4, 3); + vld4q_lane_u32(arg_u32_ptr, arg_u32x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_u32(arg_u32_ptr, arg_u32x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_u64(uint64x2x2_t arg_u64x2x2, uint64x1x2_t arg_u64x1x2, uint64x2x3_t arg_u64x2x3, + uint64x1_t arg_u64x1, uint64x1x4_t arg_u64x1x4, uint64x1x3_t arg_u64x1x3, + uint64_t *arg_u64_ptr, uint64x2_t arg_u64x2, uint64x2x4_t arg_u64x2x4) { + vld1_lane_u64(arg_u64_ptr, arg_u64x1, 0); + vld1_lane_u64(arg_u64_ptr, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_u64(arg_u64_ptr, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_u64(arg_u64_ptr, arg_u64x2, 0); + vld1q_lane_u64(arg_u64_ptr, arg_u64x2, 1); + vld1q_lane_u64(arg_u64_ptr, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_u64(arg_u64_ptr, arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1_lane_u64(arg_u64_ptr, arg_u64x1, 0); + vldap1_lane_u64(arg_u64_ptr, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1_lane_u64(arg_u64_ptr, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1q_lane_u64(arg_u64_ptr, arg_u64x2, 0); + vldap1q_lane_u64(arg_u64_ptr, arg_u64x2, 1); + vldap1q_lane_u64(arg_u64_ptr, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1q_lane_u64(arg_u64_ptr, arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1_lane_u64(arg_u64_ptr, arg_u64x1, 0); + vstl1_lane_u64(arg_u64_ptr, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1_lane_u64(arg_u64_ptr, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1q_lane_u64(arg_u64_ptr, arg_u64x2, 0); + vstl1q_lane_u64(arg_u64_ptr, arg_u64x2, 1); + vstl1q_lane_u64(arg_u64_ptr, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1q_lane_u64(arg_u64_ptr, arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_u64(arg_u64_ptr, arg_u64x1x2, 0); + vld2_lane_u64(arg_u64_ptr, arg_u64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_u64(arg_u64_ptr, arg_u64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_u64(arg_u64_ptr, arg_u64x2x2, 0); + vld2q_lane_u64(arg_u64_ptr, arg_u64x2x2, 1); + vld2q_lane_u64(arg_u64_ptr, arg_u64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_u64(arg_u64_ptr, arg_u64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_u64(arg_u64_ptr, arg_u64x1x3, 0); + vld3_lane_u64(arg_u64_ptr, arg_u64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_u64(arg_u64_ptr, arg_u64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_u64(arg_u64_ptr, arg_u64x2x3, 0); + vld3q_lane_u64(arg_u64_ptr, arg_u64x2x3, 1); + vld3q_lane_u64(arg_u64_ptr, arg_u64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_u64(arg_u64_ptr, arg_u64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_u64(arg_u64_ptr, arg_u64x1x4, 0); + vld4_lane_u64(arg_u64_ptr, arg_u64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_u64(arg_u64_ptr, arg_u64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_u64(arg_u64_ptr, arg_u64x2x4, 0); + vld4q_lane_u64(arg_u64_ptr, arg_u64x2x4, 1); + vld4q_lane_u64(arg_u64_ptr, arg_u64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_u64(arg_u64_ptr, arg_u64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_p64(poly64_t *arg_p64_ptr, poly64x2x2_t arg_p64x2x2, poly64x1x2_t arg_p64x1x2, + poly64x2x4_t arg_p64x2x4, poly64x1x3_t arg_p64x1x3, poly64x2x3_t arg_p64x2x3, + poly64x1_t arg_p64x1, poly64x2_t arg_p64x2, poly64x1x4_t arg_p64x1x4) { + vld1_lane_p64(arg_p64_ptr, arg_p64x1, 0); + vld1_lane_p64(arg_p64_ptr, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_p64(arg_p64_ptr, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_p64(arg_p64_ptr, arg_p64x2, 0); + vld1q_lane_p64(arg_p64_ptr, arg_p64x2, 1); + vld1q_lane_p64(arg_p64_ptr, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_p64(arg_p64_ptr, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1_lane_p64(arg_p64_ptr, arg_p64x1, 0); + vldap1_lane_p64(arg_p64_ptr, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1_lane_p64(arg_p64_ptr, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1q_lane_p64(arg_p64_ptr, arg_p64x2, 0); + vldap1q_lane_p64(arg_p64_ptr, arg_p64x2, 1); + vldap1q_lane_p64(arg_p64_ptr, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1q_lane_p64(arg_p64_ptr, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1_lane_p64(arg_p64_ptr, arg_p64x1, 0); + vstl1_lane_p64(arg_p64_ptr, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1_lane_p64(arg_p64_ptr, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1q_lane_p64(arg_p64_ptr, arg_p64x2, 0); + vstl1q_lane_p64(arg_p64_ptr, arg_p64x2, 1); + vstl1q_lane_p64(arg_p64_ptr, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1q_lane_p64(arg_p64_ptr, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_p64(arg_p64_ptr, arg_p64x1x2, 0); + vld2_lane_p64(arg_p64_ptr, arg_p64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_p64(arg_p64_ptr, arg_p64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_p64(arg_p64_ptr, arg_p64x2x2, 0); + vld2q_lane_p64(arg_p64_ptr, arg_p64x2x2, 1); + vld2q_lane_p64(arg_p64_ptr, arg_p64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_p64(arg_p64_ptr, arg_p64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_p64(arg_p64_ptr, arg_p64x1x3, 0); + vld3_lane_p64(arg_p64_ptr, arg_p64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_p64(arg_p64_ptr, arg_p64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_p64(arg_p64_ptr, arg_p64x2x3, 0); + vld3q_lane_p64(arg_p64_ptr, arg_p64x2x3, 1); + vld3q_lane_p64(arg_p64_ptr, arg_p64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_p64(arg_p64_ptr, arg_p64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_p64(arg_p64_ptr, arg_p64x1x4, 0); + vld4_lane_p64(arg_p64_ptr, arg_p64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_p64(arg_p64_ptr, arg_p64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_p64(arg_p64_ptr, arg_p64x2x4, 0); + vld4q_lane_p64(arg_p64_ptr, arg_p64x2x4, 1); + vld4q_lane_p64(arg_p64_ptr, arg_p64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_p64(arg_p64_ptr, arg_p64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_f16(float16_t *arg_f16_ptr, float16x8_t arg_f16x8, float16x8x2_t arg_f16x8x2, + float16x8x3_t arg_f16x8x3, float16x4x4_t arg_f16x4x4, float16x8x4_t arg_f16x8x4, + float16x4x2_t arg_f16x4x2, float16x4_t arg_f16x4, float16x4x3_t arg_f16x4x3) { + vld1_lane_f16(arg_f16_ptr, arg_f16x4, 0); + vld1_lane_f16(arg_f16_ptr, arg_f16x4, 3); + vld1_lane_f16(arg_f16_ptr, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_f16(arg_f16_ptr, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_f16(arg_f16_ptr, arg_f16x8, 0); + vld1q_lane_f16(arg_f16_ptr, arg_f16x8, 7); + vld1q_lane_f16(arg_f16_ptr, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_f16(arg_f16_ptr, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_f16(arg_f16_ptr, arg_f16x4x2, 0); + vld2_lane_f16(arg_f16_ptr, arg_f16x4x2, 3); + vld2_lane_f16(arg_f16_ptr, arg_f16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_f16(arg_f16_ptr, arg_f16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_f16(arg_f16_ptr, arg_f16x8x2, 0); + vld2q_lane_f16(arg_f16_ptr, arg_f16x8x2, 7); + vld2q_lane_f16(arg_f16_ptr, arg_f16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_f16(arg_f16_ptr, arg_f16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_f16(arg_f16_ptr, arg_f16x4x3, 0); + vld3_lane_f16(arg_f16_ptr, arg_f16x4x3, 3); + vld3_lane_f16(arg_f16_ptr, arg_f16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_f16(arg_f16_ptr, arg_f16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_f16(arg_f16_ptr, arg_f16x8x3, 0); + vld3q_lane_f16(arg_f16_ptr, arg_f16x8x3, 7); + vld3q_lane_f16(arg_f16_ptr, arg_f16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_f16(arg_f16_ptr, arg_f16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_f16(arg_f16_ptr, arg_f16x4x4, 0); + vld4_lane_f16(arg_f16_ptr, arg_f16x4x4, 3); + vld4_lane_f16(arg_f16_ptr, arg_f16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_f16(arg_f16_ptr, arg_f16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_f16(arg_f16_ptr, arg_f16x8x4, 0); + vld4q_lane_f16(arg_f16_ptr, arg_f16x8x4, 7); + vld4q_lane_f16(arg_f16_ptr, arg_f16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_f16(arg_f16_ptr, arg_f16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_f32(float32_t *arg_f32_ptr, float32x4x3_t arg_f32x4x3, float32x2x4_t arg_f32x2x4, + float32x4x4_t arg_f32x4x4, float32x2x3_t arg_f32x2x3, float32x2x2_t arg_f32x2x2, + float32x4x2_t arg_f32x4x2, float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vld1_lane_f32(arg_f32_ptr, arg_f32x2, 0); + vld1_lane_f32(arg_f32_ptr, arg_f32x2, 1); + vld1_lane_f32(arg_f32_ptr, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_f32(arg_f32_ptr, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_f32(arg_f32_ptr, arg_f32x4, 0); + vld1q_lane_f32(arg_f32_ptr, arg_f32x4, 3); + vld1q_lane_f32(arg_f32_ptr, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_f32(arg_f32_ptr, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_f32(arg_f32_ptr, arg_f32x2x2, 0); + vld2_lane_f32(arg_f32_ptr, arg_f32x2x2, 1); + vld2_lane_f32(arg_f32_ptr, arg_f32x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_f32(arg_f32_ptr, arg_f32x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_f32(arg_f32_ptr, arg_f32x4x2, 0); + vld2q_lane_f32(arg_f32_ptr, arg_f32x4x2, 3); + vld2q_lane_f32(arg_f32_ptr, arg_f32x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_f32(arg_f32_ptr, arg_f32x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_f32(arg_f32_ptr, arg_f32x2x3, 0); + vld3_lane_f32(arg_f32_ptr, arg_f32x2x3, 1); + vld3_lane_f32(arg_f32_ptr, arg_f32x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_f32(arg_f32_ptr, arg_f32x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_f32(arg_f32_ptr, arg_f32x4x3, 0); + vld3q_lane_f32(arg_f32_ptr, arg_f32x4x3, 3); + vld3q_lane_f32(arg_f32_ptr, arg_f32x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_f32(arg_f32_ptr, arg_f32x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_f32(arg_f32_ptr, arg_f32x2x4, 0); + vld4_lane_f32(arg_f32_ptr, arg_f32x2x4, 1); + vld4_lane_f32(arg_f32_ptr, arg_f32x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_f32(arg_f32_ptr, arg_f32x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_f32(arg_f32_ptr, arg_f32x4x4, 0); + vld4q_lane_f32(arg_f32_ptr, arg_f32x4x4, 3); + vld4q_lane_f32(arg_f32_ptr, arg_f32x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_f32(arg_f32_ptr, arg_f32x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_p8(poly8x16_t arg_p8x16, poly8x8x2_t arg_p8x8x2, poly8x16x4_t arg_p8x16x4, + poly8_t *arg_p8_ptr, poly8x8_t arg_p8x8, poly8x8x4_t arg_p8x8x4, + poly8x16x2_t arg_p8x16x2, poly8x8x3_t arg_p8x8x3, poly8x16x3_t arg_p8x16x3) { + vld1_lane_p8(arg_p8_ptr, arg_p8x8, 0); + vld1_lane_p8(arg_p8_ptr, arg_p8x8, 7); + vld1_lane_p8(arg_p8_ptr, arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_p8(arg_p8_ptr, arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_p8(arg_p8_ptr, arg_p8x16, 0); + vld1q_lane_p8(arg_p8_ptr, arg_p8x16, 15); + vld1q_lane_p8(arg_p8_ptr, arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_p8(arg_p8_ptr, arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_p8(arg_p8_ptr, arg_p8x8x2, 0); + vld2_lane_p8(arg_p8_ptr, arg_p8x8x2, 7); + vld2_lane_p8(arg_p8_ptr, arg_p8x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_p8(arg_p8_ptr, arg_p8x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_p8(arg_p8_ptr, arg_p8x16x2, 0); + vld2q_lane_p8(arg_p8_ptr, arg_p8x16x2, 15); + vld2q_lane_p8(arg_p8_ptr, arg_p8x16x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_p8(arg_p8_ptr, arg_p8x16x2, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_p8(arg_p8_ptr, arg_p8x8x3, 0); + vld3_lane_p8(arg_p8_ptr, arg_p8x8x3, 7); + vld3_lane_p8(arg_p8_ptr, arg_p8x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_p8(arg_p8_ptr, arg_p8x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_p8(arg_p8_ptr, arg_p8x16x3, 0); + vld3q_lane_p8(arg_p8_ptr, arg_p8x16x3, 15); + vld3q_lane_p8(arg_p8_ptr, arg_p8x16x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_p8(arg_p8_ptr, arg_p8x16x3, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_p8(arg_p8_ptr, arg_p8x8x4, 0); + vld4_lane_p8(arg_p8_ptr, arg_p8x8x4, 7); + vld4_lane_p8(arg_p8_ptr, arg_p8x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_p8(arg_p8_ptr, arg_p8x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_p8(arg_p8_ptr, arg_p8x16x4, 0); + vld4q_lane_p8(arg_p8_ptr, arg_p8x16x4, 15); + vld4q_lane_p8(arg_p8_ptr, arg_p8x16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_p8(arg_p8_ptr, arg_p8x16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_p16(poly16x8x4_t arg_p16x8x4, poly16x8_t arg_p16x8, poly16x4x4_t arg_p16x4x4, + poly16x8x3_t arg_p16x8x3, poly16_t *arg_p16_ptr, poly16x4_t arg_p16x4, + poly16x8x2_t arg_p16x8x2, poly16x4x2_t arg_p16x4x2, poly16x4x3_t arg_p16x4x3) { + vld1_lane_p16(arg_p16_ptr, arg_p16x4, 0); + vld1_lane_p16(arg_p16_ptr, arg_p16x4, 3); + vld1_lane_p16(arg_p16_ptr, arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_p16(arg_p16_ptr, arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_p16(arg_p16_ptr, arg_p16x8, 0); + vld1q_lane_p16(arg_p16_ptr, arg_p16x8, 7); + vld1q_lane_p16(arg_p16_ptr, arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_p16(arg_p16_ptr, arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_p16(arg_p16_ptr, arg_p16x4x2, 0); + vld2_lane_p16(arg_p16_ptr, arg_p16x4x2, 3); + vld2_lane_p16(arg_p16_ptr, arg_p16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_p16(arg_p16_ptr, arg_p16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_p16(arg_p16_ptr, arg_p16x8x2, 0); + vld2q_lane_p16(arg_p16_ptr, arg_p16x8x2, 7); + vld2q_lane_p16(arg_p16_ptr, arg_p16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_p16(arg_p16_ptr, arg_p16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_p16(arg_p16_ptr, arg_p16x4x3, 0); + vld3_lane_p16(arg_p16_ptr, arg_p16x4x3, 3); + vld3_lane_p16(arg_p16_ptr, arg_p16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_p16(arg_p16_ptr, arg_p16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_p16(arg_p16_ptr, arg_p16x8x3, 0); + vld3q_lane_p16(arg_p16_ptr, arg_p16x8x3, 7); + vld3q_lane_p16(arg_p16_ptr, arg_p16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_p16(arg_p16_ptr, arg_p16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_p16(arg_p16_ptr, arg_p16x4x4, 0); + vld4_lane_p16(arg_p16_ptr, arg_p16x4x4, 3); + vld4_lane_p16(arg_p16_ptr, arg_p16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_p16(arg_p16_ptr, arg_p16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_p16(arg_p16_ptr, arg_p16x8x4, 0); + vld4q_lane_p16(arg_p16_ptr, arg_p16x8x4, 7); + vld4q_lane_p16(arg_p16_ptr, arg_p16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_p16(arg_p16_ptr, arg_p16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_load_f64(float64x1_t arg_f64x1, float64x1x2_t arg_f64x1x2, float64_t* arg_f64_ptr, + float64x2x3_t arg_f64x2x3, float64x2x4_t arg_f64x2x4, float64x2x2_t arg_f64x2x2, + float64x2_t arg_f64x2, float64x1x3_t arg_f64x1x3, float64x1x4_t arg_f64x1x4) { + vld1_lane_f64(arg_f64_ptr, arg_f64x1, 0); + vld1_lane_f64(arg_f64_ptr, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1_lane_f64(arg_f64_ptr, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld1q_lane_f64(arg_f64_ptr, arg_f64x2, 0); + vld1q_lane_f64(arg_f64_ptr, arg_f64x2, 1); + vld1q_lane_f64(arg_f64_ptr, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld1q_lane_f64(arg_f64_ptr, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1_lane_f64(arg_f64_ptr, arg_f64x1, 0); + vldap1_lane_f64(arg_f64_ptr, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1_lane_f64(arg_f64_ptr, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vldap1q_lane_f64(arg_f64_ptr, arg_f64x2, 0); + vldap1q_lane_f64(arg_f64_ptr, arg_f64x2, 1); + vldap1q_lane_f64(arg_f64_ptr, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vldap1q_lane_f64(arg_f64_ptr, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1_lane_f64(arg_f64_ptr, arg_f64x1, 0); + vstl1_lane_f64(arg_f64_ptr, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1_lane_f64(arg_f64_ptr, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vstl1q_lane_f64(arg_f64_ptr, arg_f64x2, 0); + vstl1q_lane_f64(arg_f64_ptr, arg_f64x2, 1); + vstl1q_lane_f64(arg_f64_ptr, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vstl1q_lane_f64(arg_f64_ptr, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2_lane_f64(arg_f64_ptr, arg_f64x1x2, 0); + vld2_lane_f64(arg_f64_ptr, arg_f64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2_lane_f64(arg_f64_ptr, arg_f64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld2q_lane_f64(arg_f64_ptr, arg_f64x2x2, 0); + vld2q_lane_f64(arg_f64_ptr, arg_f64x2x2, 1); + vld2q_lane_f64(arg_f64_ptr, arg_f64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld2q_lane_f64(arg_f64_ptr, arg_f64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3_lane_f64(arg_f64_ptr, arg_f64x1x3, 0); + vld3_lane_f64(arg_f64_ptr, arg_f64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3_lane_f64(arg_f64_ptr, arg_f64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld3q_lane_f64(arg_f64_ptr, arg_f64x2x3, 0); + vld3q_lane_f64(arg_f64_ptr, arg_f64x2x3, 1); + vld3q_lane_f64(arg_f64_ptr, arg_f64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld3q_lane_f64(arg_f64_ptr, arg_f64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4_lane_f64(arg_f64_ptr, arg_f64x1x4, 0); + vld4_lane_f64(arg_f64_ptr, arg_f64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4_lane_f64(arg_f64_ptr, arg_f64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vld4q_lane_f64(arg_f64_ptr, arg_f64x2x4, 0); + vld4q_lane_f64(arg_f64_ptr, arg_f64x2x4, 1); + vld4q_lane_f64(arg_f64_ptr, arg_f64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vld4q_lane_f64(arg_f64_ptr, arg_f64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-accumulate-by-scalar.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-accumulate-by-scalar.c new file mode 100644 index 0000000000000..a7eee3ad25e09 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-accumulate-by-scalar.c @@ -0,0 +1,200 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + +void test_vector_multiply_accumulate_by_scalar_s16(int32x4_t arg_i32x4, int16x8_t arg_i16x8, int16x4_t arg_i16x4) { + vmla_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 0); + vmla_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 3); + vmla_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 0); + vmlaq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 3); + vmlaq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmla_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 0); + vmla_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 7); + vmla_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 0); + vmlaq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 7); + vmlaq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 0); + vmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 3); + vmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 0); + vmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 3); + vmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 0); + vmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 7); + vmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 0); + vmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 7); + vmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_accumulate_by_scalar_s32(int32x4_t arg_i32x4, int32x2_t arg_i32x2, int64x2_t arg_i64x2) { + vmla_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 0); + vmla_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 1); + vmla_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 0); + vmlaq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 1); + vmlaq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmla_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 0); + vmla_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 3); + vmla_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 0); + vmlaq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 3); + vmlaq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 0); + vmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 1); + vmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 0); + vmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 1); + vmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 0); + vmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 3); + vmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 0); + vmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 3); + vmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_accumulate_by_scalar_u16(uint16x4_t arg_u16x4, uint16x8_t arg_u16x8, uint32x4_t arg_u32x4) { + vmla_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, 0); + vmla_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, 3); + vmla_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, 0); + vmlaq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, 3); + vmlaq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmla_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, 0); + vmla_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, 7); + vmla_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, 0); + vmlaq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, 7); + vmlaq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, 0); + vmlal_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, 3); + vmlal_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, 0); + vmlal_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, 3); + vmlal_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, 0); + vmlal_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, 7); + vmlal_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, 0); + vmlal_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, 7); + vmlal_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_accumulate_by_scalar_u32(uint64x2_t arg_u64x2, uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vmla_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, 0); + vmla_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, 1); + vmla_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, 0); + vmlaq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, 1); + vmlaq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmla_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, 0); + vmla_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, 3); + vmla_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, 0); + vmlaq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, 3); + vmlaq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, 0); + vmlal_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, 1); + vmlal_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, 0); + vmlal_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, 1); + vmlal_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, 0); + vmlal_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, 3); + vmlal_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlal_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, 0); + vmlal_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, 3); + vmlal_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlal_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_accumulate_by_scalar_f32(float32x4_t arg_f32x4, float32x2_t arg_f32x2) { + vmla_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 0); + vmla_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 1); + vmla_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 0); + vmlaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 1); + vmlaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmla_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 0); + vmla_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 3); + vmla_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmla_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 0); + vmlaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 3); + vmlaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlaq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-by-scalar-and-widen.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-by-scalar-and-widen.c new file mode 100644 index 0000000000000..1ed848742e681 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-by-scalar-and-widen.c @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_vector_multiply_by_scalar_and_widen_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vmull_lane_s16(arg_i16x4, arg_i16x4, 0); + vmull_lane_s16(arg_i16x4, arg_i16x4, 3); + vmull_lane_s16(arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_lane_s16(arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_lane_s16(arg_i16x8, arg_i16x4, 0); + vmull_high_lane_s16(arg_i16x8, arg_i16x4, 3); + vmull_high_lane_s16(arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_lane_s16(arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_laneq_s16(arg_i16x4, arg_i16x8, 0); + vmull_laneq_s16(arg_i16x4, arg_i16x8, 7); + vmull_laneq_s16(arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_laneq_s16(arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_laneq_s16(arg_i16x8, arg_i16x8, 0); + vmull_high_laneq_s16(arg_i16x8, arg_i16x8, 7); + vmull_high_laneq_s16(arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_laneq_s16(arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_and_widen_s32(int32x4_t arg_i32x4, int32x2_t arg_i32x2) { + vmull_lane_s32(arg_i32x2, arg_i32x2, 0); + vmull_lane_s32(arg_i32x2, arg_i32x2, 1); + vmull_lane_s32(arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_lane_s32(arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_lane_s32(arg_i32x4, arg_i32x2, 0); + vmull_high_lane_s32(arg_i32x4, arg_i32x2, 1); + vmull_high_lane_s32(arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_lane_s32(arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_laneq_s32(arg_i32x2, arg_i32x4, 0); + vmull_laneq_s32(arg_i32x2, arg_i32x4, 3); + vmull_laneq_s32(arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_laneq_s32(arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_laneq_s32(arg_i32x4, arg_i32x4, 0); + vmull_high_laneq_s32(arg_i32x4, arg_i32x4, 3); + vmull_high_laneq_s32(arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_laneq_s32(arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_and_widen_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vmull_lane_u16(arg_u16x4, arg_u16x4, 0); + vmull_lane_u16(arg_u16x4, arg_u16x4, 3); + vmull_lane_u16(arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_lane_u16(arg_u16x4, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_lane_u16(arg_u16x8, arg_u16x4, 0); + vmull_high_lane_u16(arg_u16x8, arg_u16x4, 3); + vmull_high_lane_u16(arg_u16x8, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_lane_u16(arg_u16x8, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_laneq_u16(arg_u16x4, arg_u16x8, 0); + vmull_laneq_u16(arg_u16x4, arg_u16x8, 7); + vmull_laneq_u16(arg_u16x4, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_laneq_u16(arg_u16x4, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_laneq_u16(arg_u16x8, arg_u16x8, 0); + vmull_high_laneq_u16(arg_u16x8, arg_u16x8, 7); + vmull_high_laneq_u16(arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_laneq_u16(arg_u16x8, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_and_widen_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vmull_lane_u32(arg_u32x2, arg_u32x2, 0); + vmull_lane_u32(arg_u32x2, arg_u32x2, 1); + vmull_lane_u32(arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_lane_u32(arg_u32x2, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_lane_u32(arg_u32x4, arg_u32x2, 0); + vmull_high_lane_u32(arg_u32x4, arg_u32x2, 1); + vmull_high_lane_u32(arg_u32x4, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_lane_u32(arg_u32x4, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_laneq_u32(arg_u32x2, arg_u32x4, 0); + vmull_laneq_u32(arg_u32x2, arg_u32x4, 3); + vmull_laneq_u32(arg_u32x2, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_laneq_u32(arg_u32x2, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmull_high_laneq_u32(arg_u32x4, arg_u32x4, 0); + vmull_high_laneq_u32(arg_u32x4, arg_u32x4, 3); + vmull_high_laneq_u32(arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmull_high_laneq_u32(arg_u32x4, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-by-scalar.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-by-scalar.c new file mode 100644 index 0000000000000..7c9e73fb12a5a --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-by-scalar.c @@ -0,0 +1,160 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_vector_multiply_by_scalar_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vmul_lane_s16(arg_i16x4, arg_i16x4, 0); + vmul_lane_s16(arg_i16x4, arg_i16x4, 3); + vmul_lane_s16(arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_lane_s16(arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_lane_s16(arg_i16x8, arg_i16x4, 0); + vmulq_lane_s16(arg_i16x8, arg_i16x4, 3); + vmulq_lane_s16(arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_lane_s16(arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmul_laneq_s16(arg_i16x4, arg_i16x8, 0); + vmul_laneq_s16(arg_i16x4, arg_i16x8, 7); + vmul_laneq_s16(arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_laneq_s16(arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_laneq_s16(arg_i16x8, arg_i16x8, 0); + vmulq_laneq_s16(arg_i16x8, arg_i16x8, 7); + vmulq_laneq_s16(arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_laneq_s16(arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vmul_lane_s32(arg_i32x2, arg_i32x2, 0); + vmul_lane_s32(arg_i32x2, arg_i32x2, 1); + vmul_lane_s32(arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_lane_s32(arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_lane_s32(arg_i32x4, arg_i32x2, 0); + vmulq_lane_s32(arg_i32x4, arg_i32x2, 1); + vmulq_lane_s32(arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_lane_s32(arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmul_laneq_s32(arg_i32x2, arg_i32x4, 0); + vmul_laneq_s32(arg_i32x2, arg_i32x4, 3); + vmul_laneq_s32(arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_laneq_s32(arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_laneq_s32(arg_i32x4, arg_i32x4, 0); + vmulq_laneq_s32(arg_i32x4, arg_i32x4, 3); + vmulq_laneq_s32(arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_laneq_s32(arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vmul_lane_u16(arg_u16x4, arg_u16x4, 0); + vmul_lane_u16(arg_u16x4, arg_u16x4, 3); + vmul_lane_u16(arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_lane_u16(arg_u16x4, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_lane_u16(arg_u16x8, arg_u16x4, 0); + vmulq_lane_u16(arg_u16x8, arg_u16x4, 3); + vmulq_lane_u16(arg_u16x8, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_lane_u16(arg_u16x8, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmul_laneq_u16(arg_u16x4, arg_u16x8, 0); + vmul_laneq_u16(arg_u16x4, arg_u16x8, 7); + vmul_laneq_u16(arg_u16x4, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_laneq_u16(arg_u16x4, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_laneq_u16(arg_u16x8, arg_u16x8, 0); + vmulq_laneq_u16(arg_u16x8, arg_u16x8, 7); + vmulq_laneq_u16(arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_laneq_u16(arg_u16x8, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vmul_lane_u32(arg_u32x2, arg_u32x2, 0); + vmul_lane_u32(arg_u32x2, arg_u32x2, 1); + vmul_lane_u32(arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_lane_u32(arg_u32x2, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_lane_u32(arg_u32x4, arg_u32x2, 0); + vmulq_lane_u32(arg_u32x4, arg_u32x2, 1); + vmulq_lane_u32(arg_u32x4, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_lane_u32(arg_u32x4, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmul_laneq_u32(arg_u32x2, arg_u32x4, 0); + vmul_laneq_u32(arg_u32x2, arg_u32x4, 3); + vmul_laneq_u32(arg_u32x2, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_laneq_u32(arg_u32x2, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_laneq_u32(arg_u32x4, arg_u32x4, 0); + vmulq_laneq_u32(arg_u32x4, arg_u32x4, 3); + vmulq_laneq_u32(arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_laneq_u32(arg_u32x4, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_f32(float32_t arg_f32, float32x2_t arg_f32x2, float32x4_t arg_f32x4) { + vmul_lane_f32(arg_f32x2, arg_f32x2, 0); + vmul_lane_f32(arg_f32x2, arg_f32x2, 1); + vmul_lane_f32(arg_f32x2, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_lane_f32(arg_f32x2, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_lane_f32(arg_f32x4, arg_f32x2, 0); + vmulq_lane_f32(arg_f32x4, arg_f32x2, 1); + vmulq_lane_f32(arg_f32x4, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_lane_f32(arg_f32x4, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmuls_lane_f32(arg_f32, arg_f32x2, 0); + vmuls_lane_f32(arg_f32, arg_f32x2, 1); + vmuls_lane_f32(arg_f32, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmuls_lane_f32(arg_f32, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmul_laneq_f32(arg_f32x2, arg_f32x4, 0); + vmul_laneq_f32(arg_f32x2, arg_f32x4, 3); + vmul_laneq_f32(arg_f32x2, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_laneq_f32(arg_f32x2, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_laneq_f32(arg_f32x4, arg_f32x4, 0); + vmulq_laneq_f32(arg_f32x4, arg_f32x4, 3); + vmulq_laneq_f32(arg_f32x4, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_laneq_f32(arg_f32x4, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmuls_laneq_f32(arg_f32, arg_f32x4, 0); + vmuls_laneq_f32(arg_f32, arg_f32x4, 3); + vmuls_laneq_f32(arg_f32, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmuls_laneq_f32(arg_f32, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_by_scalar_f64(float64x1_t arg_f64x1, float64_t arg_f64, float64x2_t arg_f64x2) { + vmul_lane_f64(arg_f64x1, arg_f64x1, 0); + vmul_lane_f64(arg_f64x1, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_lane_f64(arg_f64x1, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_lane_f64(arg_f64x2, arg_f64x1, 0); + vmulq_lane_f64(arg_f64x2, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_lane_f64(arg_f64x2, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmuld_lane_f64(arg_f64, arg_f64x1, 0); + vmuld_lane_f64(arg_f64, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmuld_lane_f64(arg_f64, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmul_laneq_f64(arg_f64x1, arg_f64x2, 0); + vmul_laneq_f64(arg_f64x1, arg_f64x2, 1); + vmul_laneq_f64(arg_f64x1, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmul_laneq_f64(arg_f64x1, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmulq_laneq_f64(arg_f64x2, arg_f64x2, 0); + vmulq_laneq_f64(arg_f64x2, arg_f64x2, 1); + vmulq_laneq_f64(arg_f64x2, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmulq_laneq_f64(arg_f64x2, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmuld_laneq_f64(arg_f64, arg_f64x2, 0); + vmuld_laneq_f64(arg_f64, arg_f64x2, 1); + vmuld_laneq_f64(arg_f64, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmuld_laneq_f64(arg_f64, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-subtract-by-scalar.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-subtract-by-scalar.c new file mode 100644 index 0000000000000..c717948b13da9 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-multiply-subtract-by-scalar.c @@ -0,0 +1,201 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_vector_multiply_subtract_by_scalar_s16(int16x8_t arg_i16x8, int16x4_t arg_i16x4, int32x4_t arg_i32x4) { + vmls_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 0); + vmls_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 3); + vmls_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_lane_s16(arg_i16x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 0); + vmlsq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 3); + vmlsq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_lane_s16(arg_i16x8, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmls_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 0); + vmls_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 7); + vmls_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_laneq_s16(arg_i16x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 0); + vmlsq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 7); + vmlsq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_laneq_s16(arg_i16x8, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 0); + vmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 3); + vmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_lane_s16(arg_i32x4, arg_i16x4, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 0); + vmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 3); + vmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_lane_s16(arg_i32x4, arg_i16x8, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 0); + vmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 7); + vmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_laneq_s16(arg_i32x4, arg_i16x4, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 0); + vmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 7); + vmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_laneq_s16(arg_i32x4, arg_i16x8, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_subtract_by_scalar_s32(int64x2_t arg_i64x2, int32x4_t arg_i32x4, int32x2_t arg_i32x2) { + vmls_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 0); + vmls_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 1); + vmls_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_lane_s32(arg_i32x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 0); + vmlsq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 1); + vmlsq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_lane_s32(arg_i32x4, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmls_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 0); + vmls_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 3); + vmls_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_laneq_s32(arg_i32x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 0); + vmlsq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 3); + vmlsq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_laneq_s32(arg_i32x4, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 0); + vmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 1); + vmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_lane_s32(arg_i64x2, arg_i32x2, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 0); + vmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 1); + vmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_lane_s32(arg_i64x2, arg_i32x4, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 0); + vmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 3); + vmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_laneq_s32(arg_i64x2, arg_i32x2, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 0); + vmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 3); + vmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_laneq_s32(arg_i64x2, arg_i32x4, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_subtract_by_scalar_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4, uint32x4_t arg_u32x4) { + vmls_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, 0); + vmls_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, 3); + vmls_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_lane_u16(arg_u16x4, arg_u16x4, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, 0); + vmlsq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, 3); + vmlsq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_lane_u16(arg_u16x8, arg_u16x8, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmls_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, 0); + vmls_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, 7); + vmls_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_laneq_u16(arg_u16x4, arg_u16x4, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, 0); + vmlsq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, 7); + vmlsq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_laneq_u16(arg_u16x8, arg_u16x8, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, 0); + vmlsl_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, 3); + vmlsl_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_lane_u16(arg_u32x4, arg_u16x4, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, 0); + vmlsl_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, 3); + vmlsl_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_lane_u16(arg_u32x4, arg_u16x8, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, 0); + vmlsl_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, 7); + vmlsl_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_laneq_u16(arg_u32x4, arg_u16x4, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, 0); + vmlsl_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, 7); + vmlsl_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_laneq_u16(arg_u32x4, arg_u16x8, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_subtract_by_scalar_u32(uint64x2_t arg_u64x2, uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vmls_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, 0); + vmls_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, 1); + vmls_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_lane_u32(arg_u32x2, arg_u32x2, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, 0); + vmlsq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, 1); + vmlsq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_lane_u32(arg_u32x4, arg_u32x4, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmls_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, 0); + vmls_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, 3); + vmls_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_laneq_u32(arg_u32x2, arg_u32x2, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, 0); + vmlsq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, 3); + vmlsq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_laneq_u32(arg_u32x4, arg_u32x4, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, 0); + vmlsl_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, 1); + vmlsl_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_lane_u32(arg_u64x2, arg_u32x2, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, 0); + vmlsl_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, 1); + vmlsl_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_lane_u32(arg_u64x2, arg_u32x4, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, 0); + vmlsl_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, 3); + vmlsl_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_laneq_u32(arg_u64x2, arg_u32x2, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsl_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, 0); + vmlsl_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, 3); + vmlsl_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsl_high_laneq_u32(arg_u64x2, arg_u32x4, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_multiply_subtract_by_scalar_f32(float32x4_t arg_f32x4, float32x2_t arg_f32x2) { + vmls_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 0); + vmls_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 1); + vmls_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_lane_f32(arg_f32x2, arg_f32x2, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 0); + vmlsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 1); + vmlsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_lane_f32(arg_f32x4, arg_f32x4, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmls_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 0); + vmls_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 3); + vmls_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmls_laneq_f32(arg_f32x2, arg_f32x2, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vmlsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 0); + vmlsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 3); + vmlsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vmlsq_laneq_f32(arg_f32x4, arg_f32x4, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-shift-left.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-shift-left.c new file mode 100644 index 0000000000000..1def72fc843d9 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-shift-left.c @@ -0,0 +1,542 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + +// Widening left-shifts should have a range of 0..(sizeinbits(arg)-1), this range has had +// to be weakened to 0..((sizeinbits(arg)*2)-1) due to a use of vshll_n_s16 with an +// out-of-bounds immediate in the defintiion of vcvt_f32_bf16. As a result, the upper bounds +// of widening left-shift intrinsics are not currently tested here. + +void test_vector_shift_left_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vshl_n_s8(arg_i8x8, 0); + vshl_n_s8(arg_i8x8, 7); + vshl_n_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_s8(arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_s8(arg_i8x16, 0); + vshlq_n_s8(arg_i8x16, 7); + vshlq_n_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_s8(arg_i8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vshl_n_s16(arg_i16x4, 0); + vshl_n_s16(arg_i16x4, 15); + vshl_n_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_s16(arg_i16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_s16(arg_i16x8, 0); + vshlq_n_s16(arg_i16x8, 15); + vshlq_n_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_s16(arg_i16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vshl_n_s32(arg_i32x2, 0); + vshl_n_s32(arg_i32x2, 31); + vshl_n_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_s32(arg_i32x2, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_s32(arg_i32x4, 0); + vshlq_n_s32(arg_i32x4, 31); + vshlq_n_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_s32(arg_i32x4, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_s64(int64_t arg_i64, int64x2_t arg_i64x2, int64x1_t arg_i64x1) { + vshl_n_s64(arg_i64x1, 0); + vshl_n_s64(arg_i64x1, 63); + vshl_n_s64(arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_s64(arg_i64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_s64(arg_i64x2, 0); + vshlq_n_s64(arg_i64x2, 63); + vshlq_n_s64(arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_s64(arg_i64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshld_n_s64(arg_i64, 0); + vshld_n_s64(arg_i64, 63); + vshld_n_s64(arg_i64, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshld_n_s64(arg_i64, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vshl_n_u8(arg_u8x8, 0); + vshl_n_u8(arg_u8x8, 7); + vshl_n_u8(arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_u8(arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_u8(arg_u8x16, 0); + vshlq_n_u8(arg_u8x16, 7); + vshlq_n_u8(arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_u8(arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_u16(uint16x4_t arg_u16x4, uint16x8_t arg_u16x8) { + vshl_n_u16(arg_u16x4, 0); + vshl_n_u16(arg_u16x4, 15); + vshl_n_u16(arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_u16(arg_u16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_u16(arg_u16x8, 0); + vshlq_n_u16(arg_u16x8, 15); + vshlq_n_u16(arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_u16(arg_u16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vshl_n_u32(arg_u32x2, 0); + vshl_n_u32(arg_u32x2, 31); + vshl_n_u32(arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_u32(arg_u32x2, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_u32(arg_u32x4, 0); + vshlq_n_u32(arg_u32x4, 31); + vshlq_n_u32(arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_u32(arg_u32x4, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_u64(uint64x1_t arg_u64x1, uint64_t arg_u64, uint64x2_t arg_u64x2) { + vshl_n_u64(arg_u64x1, 0); + vshl_n_u64(arg_u64x1, 63); + vshl_n_u64(arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshl_n_u64(arg_u64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshlq_n_u64(arg_u64x2, 0); + vshlq_n_u64(arg_u64x2, 63); + vshlq_n_u64(arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshlq_n_u64(arg_u64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshld_n_u64(arg_u64, 0); + vshld_n_u64(arg_u64, 63); + vshld_n_u64(arg_u64, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshld_n_u64(arg_u64, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16, int8_t arg_i8) { + vqshl_n_s8(arg_i8x8, 0); + vqshl_n_s8(arg_i8x8, 7); + vqshl_n_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_s8(arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_s8(arg_i8x16, 0); + vqshlq_n_s8(arg_i8x16, 7); + vqshlq_n_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_s8(arg_i8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlb_n_s8(arg_i8, 0); + vqshlb_n_s8(arg_i8, 7); + vqshlb_n_s8(arg_i8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlb_n_s8(arg_i8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlu_n_s8(arg_i8x8, 0); + vqshlu_n_s8(arg_i8x8, 7); + vqshlu_n_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlu_n_s8(arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshluq_n_s8(arg_i8x16, 0); + vqshluq_n_s8(arg_i8x16, 7); + vqshluq_n_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshluq_n_s8(arg_i8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlub_n_s8(arg_i8, 0); + vqshlub_n_s8(arg_i8, 7); + vqshlub_n_s8(arg_i8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlub_n_s8(arg_i8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_s16(int16x4_t arg_i16x4, int16_t arg_i16, int16x8_t arg_i16x8) { + vqshl_n_s16(arg_i16x4, 0); + vqshl_n_s16(arg_i16x4, 15); + vqshl_n_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_s16(arg_i16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_s16(arg_i16x8, 0); + vqshlq_n_s16(arg_i16x8, 15); + vqshlq_n_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_s16(arg_i16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlh_n_s16(arg_i16, 0); + vqshlh_n_s16(arg_i16, 15); + vqshlh_n_s16(arg_i16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlh_n_s16(arg_i16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlu_n_s16(arg_i16x4, 0); + vqshlu_n_s16(arg_i16x4, 15); + vqshlu_n_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlu_n_s16(arg_i16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshluq_n_s16(arg_i16x8, 0); + vqshluq_n_s16(arg_i16x8, 15); + vqshluq_n_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshluq_n_s16(arg_i16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshluh_n_s16(arg_i16, 0); + vqshluh_n_s16(arg_i16, 15); + vqshluh_n_s16(arg_i16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshluh_n_s16(arg_i16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_s32(int32x2_t arg_i32x2, int32_t arg_i32, int32x4_t arg_i32x4) { + vqshl_n_s32(arg_i32x2, 0); + vqshl_n_s32(arg_i32x2, 31); + vqshl_n_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_s32(arg_i32x2, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_s32(arg_i32x4, 0); + vqshlq_n_s32(arg_i32x4, 31); + vqshlq_n_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_s32(arg_i32x4, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshls_n_s32(arg_i32, 0); + vqshls_n_s32(arg_i32, 31); + vqshls_n_s32(arg_i32, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshls_n_s32(arg_i32, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlu_n_s32(arg_i32x2, 0); + vqshlu_n_s32(arg_i32x2, 31); + vqshlu_n_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlu_n_s32(arg_i32x2, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshluq_n_s32(arg_i32x4, 0); + vqshluq_n_s32(arg_i32x4, 31); + vqshluq_n_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshluq_n_s32(arg_i32x4, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlus_n_s32(arg_i32, 0); + vqshlus_n_s32(arg_i32, 31); + vqshlus_n_s32(arg_i32, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlus_n_s32(arg_i32, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_s64(int64_t arg_i64, int64x2_t arg_i64x2, int64x1_t arg_i64x1) { + vqshl_n_s64(arg_i64x1, 0); + vqshl_n_s64(arg_i64x1, 63); + vqshl_n_s64(arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_s64(arg_i64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_s64(arg_i64x2, 0); + vqshlq_n_s64(arg_i64x2, 63); + vqshlq_n_s64(arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_s64(arg_i64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshld_n_s64(arg_i64, 0); + vqshld_n_s64(arg_i64, 63); + vqshld_n_s64(arg_i64, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshld_n_s64(arg_i64, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlu_n_s64(arg_i64x1, 0); + vqshlu_n_s64(arg_i64x1, 63); + vqshlu_n_s64(arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlu_n_s64(arg_i64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshluq_n_s64(arg_i64x2, 0); + vqshluq_n_s64(arg_i64x2, 63); + vqshluq_n_s64(arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshluq_n_s64(arg_i64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlud_n_s64(arg_i64, 0); + vqshlud_n_s64(arg_i64, 63); + vqshlud_n_s64(arg_i64, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlud_n_s64(arg_i64, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_u8(uint8x8_t arg_u8x8, uint8_t arg_u8, uint8x16_t arg_u8x16) { + vqshl_n_u8(arg_u8x8, 0); + vqshl_n_u8(arg_u8x8, 7); + vqshl_n_u8(arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_u8(arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_u8(arg_u8x16, 0); + vqshlq_n_u8(arg_u8x16, 7); + vqshlq_n_u8(arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_u8(arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlb_n_u8(arg_u8, 0); + vqshlb_n_u8(arg_u8, 7); + vqshlb_n_u8(arg_u8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlb_n_u8(arg_u8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_u16(uint16_t arg_u16, uint16x4_t arg_u16x4, uint16x8_t arg_u16x8) { + vqshl_n_u16(arg_u16x4, 0); + vqshl_n_u16(arg_u16x4, 15); + vqshl_n_u16(arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_u16(arg_u16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_u16(arg_u16x8, 0); + vqshlq_n_u16(arg_u16x8, 15); + vqshlq_n_u16(arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_u16(arg_u16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlh_n_u16(arg_u16, 0); + vqshlh_n_u16(arg_u16, 15); + vqshlh_n_u16(arg_u16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlh_n_u16(arg_u16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4, uint32_t arg_u32) { + vqshl_n_u32(arg_u32x2, 0); + vqshl_n_u32(arg_u32x2, 31); + vqshl_n_u32(arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_u32(arg_u32x2, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_u32(arg_u32x4, 0); + vqshlq_n_u32(arg_u32x4, 31); + vqshlq_n_u32(arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_u32(arg_u32x4, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshls_n_u32(arg_u32, 0); + vqshls_n_u32(arg_u32, 31); + vqshls_n_u32(arg_u32, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshls_n_u32(arg_u32, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_left_u64(uint64x1_t arg_u64x1, uint64_t arg_u64, uint64x2_t arg_u64x2) { + vqshl_n_u64(arg_u64x1, 0); + vqshl_n_u64(arg_u64x1, 63); + vqshl_n_u64(arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshl_n_u64(arg_u64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshlq_n_u64(arg_u64x2, 0); + vqshlq_n_u64(arg_u64x2, 63); + vqshlq_n_u64(arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshlq_n_u64(arg_u64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshld_n_u64(arg_u64, 0); + vqshld_n_u64(arg_u64, 63); + vqshld_n_u64(arg_u64, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshld_n_u64(arg_u64, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_widen_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vshll_n_s8(arg_i8x8, 0); + vshll_n_s8(arg_i8x8, 7); + vshll_n_s8(arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + + vshll_high_n_s8(arg_i8x16, 0); + vshll_high_n_s8(arg_i8x16, 7); + vshll_high_n_s8(arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vector_shift_left_and_widen_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vshll_n_s16(arg_i16x4, 0); + vshll_n_s16(arg_i16x4, 15); + vshll_n_s16(arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshll_high_n_s16(arg_i16x8, 0); + vshll_high_n_s16(arg_i16x8, 15); + vshll_high_n_s16(arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vector_shift_left_and_widen_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vshll_n_s32(arg_i32x2, 0); + vshll_n_s32(arg_i32x2, 31); + vshll_n_s32(arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshll_high_n_s32(arg_i32x4, 0); + vshll_high_n_s32(arg_i32x4, 31); + vshll_high_n_s32(arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vector_shift_left_and_widen_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vshll_n_u8(arg_u8x8, 0); + vshll_n_u8(arg_u8x8, 7); + vshll_n_u8(arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshll_high_n_u8(arg_u8x16, 0); + vshll_high_n_u8(arg_u8x16, 7); + vshll_high_n_u8(arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vector_shift_left_and_widen_u16(uint16x4_t arg_u16x4, uint16x8_t arg_u16x8) { + vshll_n_u16(arg_u16x4, 0); + vshll_n_u16(arg_u16x4, 15); + vshll_n_u16(arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshll_high_n_u16(arg_u16x8, 0); + vshll_high_n_u16(arg_u16x8, 15); + vshll_high_n_u16(arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vector_shift_left_and_widen_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vshll_n_u32(arg_u32x2, 0); + vshll_n_u32(arg_u32x2, 31); + vshll_n_u32(arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshll_high_n_u32(arg_u32x4, 0); + vshll_high_n_u32(arg_u32x4, 31); + vshll_high_n_u32(arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + +void test_vector_shift_left_and_insert_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vsli_n_s8(arg_i8x8, arg_i8x8, 0); + vsli_n_s8(arg_i8x8, arg_i8x8, 7); + vsli_n_s8(arg_i8x8, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_s8(arg_i8x8, arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_s8(arg_i8x16, arg_i8x16, 0); + vsliq_n_s8(arg_i8x16, arg_i8x16, 7); + vsliq_n_s8(arg_i8x16, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_s8(arg_i8x16, arg_i8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vsli_n_s16(arg_i16x4, arg_i16x4, 0); + vsli_n_s16(arg_i16x4, arg_i16x4, 15); + vsli_n_s16(arg_i16x4, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_s16(arg_i16x4, arg_i16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_s16(arg_i16x8, arg_i16x8, 0); + vsliq_n_s16(arg_i16x8, arg_i16x8, 15); + vsliq_n_s16(arg_i16x8, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_s16(arg_i16x8, arg_i16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vsli_n_s32(arg_i32x2, arg_i32x2, 0); + vsli_n_s32(arg_i32x2, arg_i32x2, 31); + vsli_n_s32(arg_i32x2, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_s32(arg_i32x2, arg_i32x2, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_s32(arg_i32x4, arg_i32x4, 0); + vsliq_n_s32(arg_i32x4, arg_i32x4, 31); + vsliq_n_s32(arg_i32x4, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_s32(arg_i32x4, arg_i32x4, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_s64(int64_t arg_i64, int64x2_t arg_i64x2, int64x1_t arg_i64x1) { + vsli_n_s64(arg_i64x1, arg_i64x1, 0); + vsli_n_s64(arg_i64x1, arg_i64x1, 63); + vsli_n_s64(arg_i64x1, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_s64(arg_i64x1, arg_i64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_s64(arg_i64x2, arg_i64x2, 0); + vsliq_n_s64(arg_i64x2, arg_i64x2, 63); + vsliq_n_s64(arg_i64x2, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_s64(arg_i64x2, arg_i64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vslid_n_s64(arg_i64, arg_i64, 0); + vslid_n_s64(arg_i64, arg_i64, 63); + vslid_n_s64(arg_i64, arg_i64, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vslid_n_s64(arg_i64, arg_i64, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_u8(uint8x8_t arg_u8x8, uint8x16_t arg_u8x16) { + vsli_n_u8(arg_u8x8, arg_u8x8, 0); + vsli_n_u8(arg_u8x8, arg_u8x8, 7); + vsli_n_u8(arg_u8x8, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_u8(arg_u8x8, arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_u8(arg_u8x16, arg_u8x16, 0); + vsliq_n_u8(arg_u8x16, arg_u8x16, 7); + vsliq_n_u8(arg_u8x16, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_u8(arg_u8x16, arg_u8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_u16(uint16x4_t arg_u16x4, uint16x8_t arg_u16x8) { + vsli_n_u16(arg_u16x4, arg_u16x4, 0); + vsli_n_u16(arg_u16x4, arg_u16x4, 15); + vsli_n_u16(arg_u16x4, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_u16(arg_u16x4, arg_u16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_u16(arg_u16x8, arg_u16x8, 0); + vsliq_n_u16(arg_u16x8, arg_u16x8, 15); + vsliq_n_u16(arg_u16x8, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_u16(arg_u16x8, arg_u16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vsli_n_u32(arg_u32x2, arg_u32x2, 0); + vsli_n_u32(arg_u32x2, arg_u32x2, 31); + vsli_n_u32(arg_u32x2, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_u32(arg_u32x2, arg_u32x2, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_u32(arg_u32x4, arg_u32x4, 0); + vsliq_n_u32(arg_u32x4, arg_u32x4, 31); + vsliq_n_u32(arg_u32x4, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_u32(arg_u32x4, arg_u32x4, 32); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_u64(uint64x1_t arg_u64x1, uint64_t arg_u64, uint64x2_t arg_u64x2) { + vsli_n_u64(arg_u64x1, arg_u64x1, 0); + vsli_n_u64(arg_u64x1, arg_u64x1, 63); + vsli_n_u64(arg_u64x1, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_u64(arg_u64x1, arg_u64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_u64(arg_u64x2, arg_u64x2, 0); + vsliq_n_u64(arg_u64x2, arg_u64x2, 63); + vsliq_n_u64(arg_u64x2, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_u64(arg_u64x2, arg_u64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vslid_n_u64(arg_u64, arg_u64, 0); + vslid_n_u64(arg_u64, arg_u64, 63); + vslid_n_u64(arg_u64, arg_u64, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vslid_n_u64(arg_u64, arg_u64, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_p64(poly64x2_t arg_p64x2, poly64x1_t arg_p64x1) { + vsli_n_p64(arg_p64x1, arg_p64x1, 0); + vsli_n_p64(arg_p64x1, arg_p64x1, 63); + vsli_n_p64(arg_p64x1, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_p64(arg_p64x1, arg_p64x1, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_p64(arg_p64x2, arg_p64x2, 0); + vsliq_n_p64(arg_p64x2, arg_p64x2, 63); + vsliq_n_p64(arg_p64x2, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_p64(arg_p64x2, arg_p64x2, 64); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_p8(poly8x16_t arg_p8x16, poly8x8_t arg_p8x8) { + vsli_n_p8(arg_p8x8, arg_p8x8, 0); + vsli_n_p8(arg_p8x8, arg_p8x8, 7); + vsli_n_p8(arg_p8x8, arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_p8(arg_p8x8, arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_p8(arg_p8x16, arg_p8x16, 0); + vsliq_n_p8(arg_p8x16, arg_p8x16, 7); + vsliq_n_p8(arg_p8x16, arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_p8(arg_p8x16, arg_p8x16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_left_and_insert_p16(poly16x4_t arg_p16x4, poly16x8_t arg_p16x8) { + vsli_n_p16(arg_p16x4, arg_p16x4, 0); + vsli_n_p16(arg_p16x4, arg_p16x4, 15); + vsli_n_p16(arg_p16x4, arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsli_n_p16(arg_p16x4, arg_p16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsliq_n_p16(arg_p16x8, arg_p16x8, 0); + vsliq_n_p16(arg_p16x8, arg_p16x8, 15); + vsliq_n_p16(arg_p16x8, arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsliq_n_p16(arg_p16x8, arg_p16x8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-shift-right.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-shift-right.c new file mode 100644 index 0000000000000..ad4677fe43666 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-shift-right.c @@ -0,0 +1,1083 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_vector_shift_right_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vshr_n_s8(arg_i8x8, 1); + vshr_n_s8(arg_i8x8, 8); + vshr_n_s8(arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_s8(arg_i8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_s8(arg_i8x16, 1); + vshrq_n_s8(arg_i8x16, 8); + vshrq_n_s8(arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_s8(arg_i8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vshr_n_s16(arg_i16x4, 1); + vshr_n_s16(arg_i16x4, 16); + vshr_n_s16(arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_s16(arg_i16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_s16(arg_i16x8, 1); + vshrq_n_s16(arg_i16x8, 16); + vshrq_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_s16(arg_i16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vshr_n_s32(arg_i32x2, 1); + vshr_n_s32(arg_i32x2, 32); + vshr_n_s32(arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_s32(arg_i32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_s32(arg_i32x4, 1); + vshrq_n_s32(arg_i32x4, 32); + vshrq_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_s32(arg_i32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_s64(int64_t arg_i64, int64x1_t arg_i64x1, int64x2_t arg_i64x2) { + vshr_n_s64(arg_i64x1, 1); + vshr_n_s64(arg_i64x1, 64); + vshr_n_s64(arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_s64(arg_i64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_s64(arg_i64x2, 1); + vshrq_n_s64(arg_i64x2, 64); + vshrq_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_s64(arg_i64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrd_n_s64(arg_i64, 1); + vshrd_n_s64(arg_i64, 64); + vshrd_n_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrd_n_s64(arg_i64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_u8(uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vshr_n_u8(arg_u8x8, 1); + vshr_n_u8(arg_u8x8, 8); + vshr_n_u8(arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_u8(arg_u8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_u8(arg_u8x16, 1); + vshrq_n_u8(arg_u8x16, 8); + vshrq_n_u8(arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_u8(arg_u8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vshr_n_u16(arg_u16x4, 1); + vshr_n_u16(arg_u16x4, 16); + vshr_n_u16(arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_u16(arg_u16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_u16(arg_u16x8, 1); + vshrq_n_u16(arg_u16x8, 16); + vshrq_n_u16(arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_u16(arg_u16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vshr_n_u32(arg_u32x2, 1); + vshr_n_u32(arg_u32x2, 32); + vshr_n_u32(arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_u32(arg_u32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_u32(arg_u32x4, 1); + vshrq_n_u32(arg_u32x4, 32); + vshrq_n_u32(arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_u32(arg_u32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_u64(uint64x2_t arg_u64x2, uint64_t arg_u64, uint64x1_t arg_u64x1) { + vshr_n_u64(arg_u64x1, 1); + vshr_n_u64(arg_u64x1, 64); + vshr_n_u64(arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshr_n_u64(arg_u64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrq_n_u64(arg_u64x2, 1); + vshrq_n_u64(arg_u64x2, 64); + vshrq_n_u64(arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrq_n_u64(arg_u64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrd_n_u64(arg_u64, 1); + vshrd_n_u64(arg_u64, 64); + vshrd_n_u64(arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrd_n_u64(arg_u64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vrshr_n_s8(arg_i8x8, 1); + vrshr_n_s8(arg_i8x8, 8); + vrshr_n_s8(arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_s8(arg_i8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_s8(arg_i8x16, 1); + vrshrq_n_s8(arg_i8x16, 8); + vrshrq_n_s8(arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_s8(arg_i8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vrshr_n_s16(arg_i16x4, 1); + vrshr_n_s16(arg_i16x4, 16); + vrshr_n_s16(arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_s16(arg_i16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_s16(arg_i16x8, 1); + vrshrq_n_s16(arg_i16x8, 16); + vrshrq_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_s16(arg_i16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vrshr_n_s32(arg_i32x2, 1); + vrshr_n_s32(arg_i32x2, 32); + vrshr_n_s32(arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_s32(arg_i32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_s32(arg_i32x4, 1); + vrshrq_n_s32(arg_i32x4, 32); + vrshrq_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_s32(arg_i32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_s64(int64_t arg_i64, int64x1_t arg_i64x1, int64x2_t arg_i64x2) { + vrshr_n_s64(arg_i64x1, 1); + vrshr_n_s64(arg_i64x1, 64); + vrshr_n_s64(arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_s64(arg_i64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_s64(arg_i64x2, 1); + vrshrq_n_s64(arg_i64x2, 64); + vrshrq_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_s64(arg_i64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrd_n_s64(arg_i64, 1); + vrshrd_n_s64(arg_i64, 64); + vrshrd_n_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrd_n_s64(arg_i64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_u8(uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vrshr_n_u8(arg_u8x8, 1); + vrshr_n_u8(arg_u8x8, 8); + vrshr_n_u8(arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_u8(arg_u8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_u8(arg_u8x16, 1); + vrshrq_n_u8(arg_u8x16, 8); + vrshrq_n_u8(arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_u8(arg_u8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vrshr_n_u16(arg_u16x4, 1); + vrshr_n_u16(arg_u16x4, 16); + vrshr_n_u16(arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_u16(arg_u16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_u16(arg_u16x8, 1); + vrshrq_n_u16(arg_u16x8, 16); + vrshrq_n_u16(arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_u16(arg_u16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vrshr_n_u32(arg_u32x2, 1); + vrshr_n_u32(arg_u32x2, 32); + vrshr_n_u32(arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_u32(arg_u32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_u32(arg_u32x4, 1); + vrshrq_n_u32(arg_u32x4, 32); + vrshrq_n_u32(arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_u32(arg_u32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_u64(uint64x2_t arg_u64x2, uint64_t arg_u64, uint64x1_t arg_u64x1) { + vrshr_n_u64(arg_u64x1, 1); + vrshr_n_u64(arg_u64x1, 64); + vrshr_n_u64(arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshr_n_u64(arg_u64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrq_n_u64(arg_u64x2, 1); + vrshrq_n_u64(arg_u64x2, 64); + vrshrq_n_u64(arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrq_n_u64(arg_u64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrd_n_u64(arg_u64, 1); + vrshrd_n_u64(arg_u64, 64); + vrshrd_n_u64(arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrd_n_u64(arg_u64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vsra_n_s8(arg_i8x8, arg_i8x8, 1); + vsra_n_s8(arg_i8x8, arg_i8x8, 8); + vsra_n_s8(arg_i8x8, arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_s8(arg_i8x8, arg_i8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_s8(arg_i8x16, arg_i8x16, 1); + vsraq_n_s8(arg_i8x16, arg_i8x16, 8); + vsraq_n_s8(arg_i8x16, arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_s8(arg_i8x16, arg_i8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vsra_n_s16(arg_i16x4, arg_i16x4, 1); + vsra_n_s16(arg_i16x4, arg_i16x4, 16); + vsra_n_s16(arg_i16x4, arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_s16(arg_i16x4, arg_i16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_s16(arg_i16x8, arg_i16x8, 1); + vsraq_n_s16(arg_i16x8, arg_i16x8, 16); + vsraq_n_s16(arg_i16x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_s16(arg_i16x8, arg_i16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vsra_n_s32(arg_i32x2, arg_i32x2, 1); + vsra_n_s32(arg_i32x2, arg_i32x2, 32); + vsra_n_s32(arg_i32x2, arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_s32(arg_i32x2, arg_i32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_s32(arg_i32x4, arg_i32x4, 1); + vsraq_n_s32(arg_i32x4, arg_i32x4, 32); + vsraq_n_s32(arg_i32x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_s32(arg_i32x4, arg_i32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_s64(int64_t arg_i64, int64x1_t arg_i64x1, int64x2_t arg_i64x2) { + vsra_n_s64(arg_i64x1, arg_i64x1, 1); + vsra_n_s64(arg_i64x1, arg_i64x1, 64); + vsra_n_s64(arg_i64x1, arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_s64(arg_i64x1, arg_i64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_s64(arg_i64x2, arg_i64x2, 1); + vsraq_n_s64(arg_i64x2, arg_i64x2, 64); + vsraq_n_s64(arg_i64x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_s64(arg_i64x2, arg_i64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsrad_n_s64(arg_i64, arg_i64, 1); + vsrad_n_s64(arg_i64, arg_i64, 64); + vsrad_n_s64(arg_i64, arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsrad_n_s64(arg_i64, arg_i64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_u8(uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vsra_n_u8(arg_u8x8, arg_u8x8, 1); + vsra_n_u8(arg_u8x8, arg_u8x8, 8); + vsra_n_u8(arg_u8x8, arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_u8(arg_u8x8, arg_u8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_u8(arg_u8x16, arg_u8x16, 1); + vsraq_n_u8(arg_u8x16, arg_u8x16, 8); + vsraq_n_u8(arg_u8x16, arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_u8(arg_u8x16, arg_u8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vsra_n_u16(arg_u16x4, arg_u16x4, 1); + vsra_n_u16(arg_u16x4, arg_u16x4, 16); + vsra_n_u16(arg_u16x4, arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_u16(arg_u16x4, arg_u16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_u16(arg_u16x8, arg_u16x8, 1); + vsraq_n_u16(arg_u16x8, arg_u16x8, 16); + vsraq_n_u16(arg_u16x8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_u16(arg_u16x8, arg_u16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vsra_n_u32(arg_u32x2, arg_u32x2, 1); + vsra_n_u32(arg_u32x2, arg_u32x2, 32); + vsra_n_u32(arg_u32x2, arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_u32(arg_u32x2, arg_u32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_u32(arg_u32x4, arg_u32x4, 1); + vsraq_n_u32(arg_u32x4, arg_u32x4, 32); + vsraq_n_u32(arg_u32x4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_u32(arg_u32x4, arg_u32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_accumulate_u64(uint64x2_t arg_u64x2, uint64_t arg_u64, uint64x1_t arg_u64x1) { + vsra_n_u64(arg_u64x1, arg_u64x1, 1); + vsra_n_u64(arg_u64x1, arg_u64x1, 64); + vsra_n_u64(arg_u64x1, arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsra_n_u64(arg_u64x1, arg_u64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsraq_n_u64(arg_u64x2, arg_u64x2, 1); + vsraq_n_u64(arg_u64x2, arg_u64x2, 64); + vsraq_n_u64(arg_u64x2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsraq_n_u64(arg_u64x2, arg_u64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsrad_n_u64(arg_u64, arg_u64, 1); + vsrad_n_u64(arg_u64, arg_u64, 64); + vsrad_n_u64(arg_u64, arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsrad_n_u64(arg_u64, arg_u64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vrsra_n_s8(arg_i8x8, arg_i8x8, 1); + vrsra_n_s8(arg_i8x8, arg_i8x8, 8); + vrsra_n_s8(arg_i8x8, arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_s8(arg_i8x8, arg_i8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_s8(arg_i8x16, arg_i8x16, 1); + vrsraq_n_s8(arg_i8x16, arg_i8x16, 8); + vrsraq_n_s8(arg_i8x16, arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_s8(arg_i8x16, arg_i8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vrsra_n_s16(arg_i16x4, arg_i16x4, 1); + vrsra_n_s16(arg_i16x4, arg_i16x4, 16); + vrsra_n_s16(arg_i16x4, arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_s16(arg_i16x4, arg_i16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_s16(arg_i16x8, arg_i16x8, 1); + vrsraq_n_s16(arg_i16x8, arg_i16x8, 16); + vrsraq_n_s16(arg_i16x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_s16(arg_i16x8, arg_i16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vrsra_n_s32(arg_i32x2, arg_i32x2, 1); + vrsra_n_s32(arg_i32x2, arg_i32x2, 32); + vrsra_n_s32(arg_i32x2, arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_s32(arg_i32x2, arg_i32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_s32(arg_i32x4, arg_i32x4, 1); + vrsraq_n_s32(arg_i32x4, arg_i32x4, 32); + vrsraq_n_s32(arg_i32x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_s32(arg_i32x4, arg_i32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_s64(int64_t arg_i64, int64x1_t arg_i64x1, int64x2_t arg_i64x2) { + vrsra_n_s64(arg_i64x1, arg_i64x1, 1); + vrsra_n_s64(arg_i64x1, arg_i64x1, 64); + vrsra_n_s64(arg_i64x1, arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_s64(arg_i64x1, arg_i64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_s64(arg_i64x2, arg_i64x2, 1); + vrsraq_n_s64(arg_i64x2, arg_i64x2, 64); + vrsraq_n_s64(arg_i64x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_s64(arg_i64x2, arg_i64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsrad_n_s64(arg_i64, arg_i64, 1); + vrsrad_n_s64(arg_i64, arg_i64, 64); + vrsrad_n_s64(arg_i64, arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsrad_n_s64(arg_i64, arg_i64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_u8(uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vrsra_n_u8(arg_u8x8, arg_u8x8, 1); + vrsra_n_u8(arg_u8x8, arg_u8x8, 8); + vrsra_n_u8(arg_u8x8, arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_u8(arg_u8x8, arg_u8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_u8(arg_u8x16, arg_u8x16, 1); + vrsraq_n_u8(arg_u8x16, arg_u8x16, 8); + vrsraq_n_u8(arg_u8x16, arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_u8(arg_u8x16, arg_u8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vrsra_n_u16(arg_u16x4, arg_u16x4, 1); + vrsra_n_u16(arg_u16x4, arg_u16x4, 16); + vrsra_n_u16(arg_u16x4, arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_u16(arg_u16x4, arg_u16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_u16(arg_u16x8, arg_u16x8, 1); + vrsraq_n_u16(arg_u16x8, arg_u16x8, 16); + vrsraq_n_u16(arg_u16x8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_u16(arg_u16x8, arg_u16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vrsra_n_u32(arg_u32x2, arg_u32x2, 1); + vrsra_n_u32(arg_u32x2, arg_u32x2, 32); + vrsra_n_u32(arg_u32x2, arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_u32(arg_u32x2, arg_u32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_u32(arg_u32x4, arg_u32x4, 1); + vrsraq_n_u32(arg_u32x4, arg_u32x4, 32); + vrsraq_n_u32(arg_u32x4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_u32(arg_u32x4, arg_u32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_accumulate_u64(uint64x2_t arg_u64x2, uint64_t arg_u64, uint64x1_t arg_u64x1) { + vrsra_n_u64(arg_u64x1, arg_u64x1, 1); + vrsra_n_u64(arg_u64x1, arg_u64x1, 64); + vrsra_n_u64(arg_u64x1, arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsra_n_u64(arg_u64x1, arg_u64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsraq_n_u64(arg_u64x2, arg_u64x2, 1); + vrsraq_n_u64(arg_u64x2, arg_u64x2, 64); + vrsraq_n_u64(arg_u64x2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsraq_n_u64(arg_u64x2, arg_u64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrsrad_n_u64(arg_u64, arg_u64, 1); + vrsrad_n_u64(arg_u64, arg_u64, 64); + vrsrad_n_u64(arg_u64, arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrsrad_n_u64(arg_u64, arg_u64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_narrow_s16(int16x8_t arg_i16x8, int8x8_t arg_i8x8) { + vshrn_n_s16(arg_i16x8, 1); + vshrn_n_s16(arg_i16x8, 8); + vshrn_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_n_s16(arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrn_high_n_s16(arg_i8x8, arg_i16x8, 1); + vshrn_high_n_s16(arg_i8x8, arg_i16x8, 8); + vshrn_high_n_s16(arg_i8x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_high_n_s16(arg_i8x8, arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_narrow_s32(int32x4_t arg_i32x4, int16x4_t arg_i16x4) { + vshrn_n_s32(arg_i32x4, 1); + vshrn_n_s32(arg_i32x4, 16); + vshrn_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_n_s32(arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrn_high_n_s32(arg_i16x4, arg_i32x4, 1); + vshrn_high_n_s32(arg_i16x4, arg_i32x4, 16); + vshrn_high_n_s32(arg_i16x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_high_n_s32(arg_i16x4, arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_narrow_s64(int32x2_t arg_i32x2, int64x2_t arg_i64x2) { + vshrn_n_s64(arg_i64x2, 1); + vshrn_n_s64(arg_i64x2, 32); + vshrn_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_n_s64(arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrn_high_n_s64(arg_i32x2, arg_i64x2, 1); + vshrn_high_n_s64(arg_i32x2, arg_i64x2, 32); + vshrn_high_n_s64(arg_i32x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_high_n_s64(arg_i32x2, arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_narrow_u16(uint16x8_t arg_u16x8, uint8x8_t arg_u8x8) { + vshrn_n_u16(arg_u16x8, 1); + vshrn_n_u16(arg_u16x8, 8); + vshrn_n_u16(arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_n_u16(arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrn_high_n_u16(arg_u8x8, arg_u16x8, 1); + vshrn_high_n_u16(arg_u8x8, arg_u16x8, 8); + vshrn_high_n_u16(arg_u8x8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_high_n_u16(arg_u8x8, arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_narrow_u32(uint32x4_t arg_u32x4, uint16x4_t arg_u16x4) { + vshrn_n_u32(arg_u32x4, 1); + vshrn_n_u32(arg_u32x4, 16); + vshrn_n_u32(arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_n_u32(arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrn_high_n_u32(arg_u16x4, arg_u32x4, 1); + vshrn_high_n_u32(arg_u16x4, arg_u32x4, 16); + vshrn_high_n_u32(arg_u16x4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_high_n_u32(arg_u16x4, arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_narrow_u64(uint64x2_t arg_u64x2, uint32x2_t arg_u32x2) { + vshrn_n_u64(arg_u64x2, 1); + vshrn_n_u64(arg_u64x2, 32); + vshrn_n_u64(arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_n_u64(arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vshrn_high_n_u64(arg_u32x2, arg_u64x2, 1); + vshrn_high_n_u64(arg_u32x2, arg_u64x2, 32); + vshrn_high_n_u64(arg_u32x2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vshrn_high_n_u64(arg_u32x2, arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_right_and_narrow_s16(int16x8_t arg_i16x8, uint8x8_t arg_u8x8, int16_t arg_i16, int8x8_t arg_i8x8) { + vqshrun_n_s16(arg_i16x8, 1); + vqshrun_n_s16(arg_i16x8, 8); + vqshrun_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrun_n_s16(arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrunh_n_s16(arg_i16, 1); + vqshrunh_n_s16(arg_i16, 8); + vqshrunh_n_s16(arg_i16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrunh_n_s16(arg_i16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrun_high_n_s16(arg_u8x8, arg_i16x8, 1); + vqshrun_high_n_s16(arg_u8x8, arg_i16x8, 8); + vqshrun_high_n_s16(arg_u8x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrun_high_n_s16(arg_u8x8, arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_n_s16(arg_i16x8, 1); + vqshrn_n_s16(arg_i16x8, 8); + vqshrn_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_n_s16(arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrnh_n_s16(arg_i16, 1); + vqshrnh_n_s16(arg_i16, 8); + vqshrnh_n_s16(arg_i16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrnh_n_s16(arg_i16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_high_n_s16(arg_i8x8, arg_i16x8, 1); + vqshrn_high_n_s16(arg_i8x8, arg_i16x8, 8); + vqshrn_high_n_s16(arg_i8x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_high_n_s16(arg_i8x8, arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_right_and_narrow_s32(int16x4_t arg_i16x4, int32_t arg_i32, int32x4_t arg_i32x4, uint16x4_t arg_u16x4) { + vqshrun_n_s32(arg_i32x4, 1); + vqshrun_n_s32(arg_i32x4, 16); + vqshrun_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrun_n_s32(arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshruns_n_s32(arg_i32, 1); + vqshruns_n_s32(arg_i32, 16); + vqshruns_n_s32(arg_i32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshruns_n_s32(arg_i32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrun_high_n_s32(arg_u16x4, arg_i32x4, 1); + vqshrun_high_n_s32(arg_u16x4, arg_i32x4, 16); + vqshrun_high_n_s32(arg_u16x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrun_high_n_s32(arg_u16x4, arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_n_s32(arg_i32x4, 1); + vqshrn_n_s32(arg_i32x4, 16); + vqshrn_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_n_s32(arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrns_n_s32(arg_i32, 1); + vqshrns_n_s32(arg_i32, 16); + vqshrns_n_s32(arg_i32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrns_n_s32(arg_i32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_high_n_s32(arg_i16x4, arg_i32x4, 1); + vqshrn_high_n_s32(arg_i16x4, arg_i32x4, 16); + vqshrn_high_n_s32(arg_i16x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_high_n_s32(arg_i16x4, arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_right_and_narrow_s64(uint32x2_t arg_u32x2, int64x2_t arg_i64x2, int32x2_t arg_i32x2, int64_t arg_i64) { + vqshrun_n_s64(arg_i64x2, 1); + vqshrun_n_s64(arg_i64x2, 32); + vqshrun_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrun_n_s64(arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrund_n_s64(arg_i64, 1); + vqshrund_n_s64(arg_i64, 32); + vqshrund_n_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrund_n_s64(arg_i64, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrun_high_n_s64(arg_u32x2, arg_i64x2, 1); + vqshrun_high_n_s64(arg_u32x2, arg_i64x2, 32); + vqshrun_high_n_s64(arg_u32x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrun_high_n_s64(arg_u32x2, arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_n_s64(arg_i64x2, 1); + vqshrn_n_s64(arg_i64x2, 32); + vqshrn_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_n_s64(arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrnd_n_s64(arg_i64, 1); + vqshrnd_n_s64(arg_i64, 32); + vqshrnd_n_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrnd_n_s64(arg_i64, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_high_n_s64(arg_i32x2, arg_i64x2, 1); + vqshrn_high_n_s64(arg_i32x2, arg_i64x2, 32); + vqshrn_high_n_s64(arg_i32x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_high_n_s64(arg_i32x2, arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_right_and_narrow_u16(uint16x8_t arg_u16x8, uint16_t arg_u16, uint8x8_t arg_u8x8) { + vqshrn_n_u16(arg_u16x8, 1); + vqshrn_n_u16(arg_u16x8, 8); + vqshrn_n_u16(arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_n_u16(arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrnh_n_u16(arg_u16, 1); + vqshrnh_n_u16(arg_u16, 8); + vqshrnh_n_u16(arg_u16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrnh_n_u16(arg_u16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_high_n_u16(arg_u8x8, arg_u16x8, 1); + vqshrn_high_n_u16(arg_u8x8, arg_u16x8, 8); + vqshrn_high_n_u16(arg_u8x8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_high_n_u16(arg_u8x8, arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_right_and_narrow_u32(uint32x4_t arg_u32x4, uint32_t arg_u32, uint16x4_t arg_u16x4) { + vqshrn_n_u32(arg_u32x4, 1); + vqshrn_n_u32(arg_u32x4, 16); + vqshrn_n_u32(arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_n_u32(arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrns_n_u32(arg_u32, 1); + vqshrns_n_u32(arg_u32, 16); + vqshrns_n_u32(arg_u32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrns_n_u32(arg_u32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_high_n_u32(arg_u16x4, arg_u32x4, 1); + vqshrn_high_n_u32(arg_u16x4, arg_u32x4, 16); + vqshrn_high_n_u32(arg_u16x4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_high_n_u32(arg_u16x4, arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_shift_right_and_narrow_u64(uint64x2_t arg_u64x2, uint32x2_t arg_u32x2, uint64_t arg_u64) { + vqshrn_n_u64(arg_u64x2, 1); + vqshrn_n_u64(arg_u64x2, 32); + vqshrn_n_u64(arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_n_u64(arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrnd_n_u64(arg_u64, 1); + vqshrnd_n_u64(arg_u64, 32); + vqshrnd_n_u64(arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrnd_n_u64(arg_u64, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqshrn_high_n_u64(arg_u32x2, arg_u64x2, 1); + vqshrn_high_n_u64(arg_u32x2, arg_u64x2, 32); + vqshrn_high_n_u64(arg_u32x2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqshrn_high_n_u64(arg_u32x2, arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_rounding_shift_right_and_narrow_s16(int16x8_t arg_i16x8, uint8x8_t arg_u8x8, + int16_t arg_i16, int8x8_t arg_i8x8) { + vqrshrun_n_s16(arg_i16x8, 1); + vqrshrun_n_s16(arg_i16x8, 8); + vqrshrun_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrun_n_s16(arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrunh_n_s16(arg_i16, 1); + vqrshrunh_n_s16(arg_i16, 8); + vqrshrunh_n_s16(arg_i16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrunh_n_s16(arg_i16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrun_high_n_s16(arg_u8x8, arg_i16x8, 1); + vqrshrun_high_n_s16(arg_u8x8, arg_i16x8, 8); + vqrshrun_high_n_s16(arg_u8x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrun_high_n_s16(arg_u8x8, arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_n_s16(arg_i16x8, 1); + vqrshrn_n_s16(arg_i16x8, 8); + vqrshrn_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_n_s16(arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrnh_n_s16(arg_i16, 1); + vqrshrnh_n_s16(arg_i16, 8); + vqrshrnh_n_s16(arg_i16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrnh_n_s16(arg_i16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_high_n_s16(arg_i8x8, arg_i16x8, 1); + vqrshrn_high_n_s16(arg_i8x8, arg_i16x8, 8); + vqrshrn_high_n_s16(arg_i8x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_high_n_s16(arg_i8x8, arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_rounding_shift_right_and_narrow_s32(int16x4_t arg_i16x4, int32_t arg_i32, + int32x4_t arg_i32x4, uint16x4_t arg_u16x4) { + vqrshrun_n_s32(arg_i32x4, 1); + vqrshrun_n_s32(arg_i32x4, 16); + vqrshrun_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrun_n_s32(arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshruns_n_s32(arg_i32, 1); + vqrshruns_n_s32(arg_i32, 16); + vqrshruns_n_s32(arg_i32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshruns_n_s32(arg_i32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrun_high_n_s32(arg_u16x4, arg_i32x4, 1); + vqrshrun_high_n_s32(arg_u16x4, arg_i32x4, 16); + vqrshrun_high_n_s32(arg_u16x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrun_high_n_s32(arg_u16x4, arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_n_s32(arg_i32x4, 1); + vqrshrn_n_s32(arg_i32x4, 16); + vqrshrn_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_n_s32(arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrns_n_s32(arg_i32, 1); + vqrshrns_n_s32(arg_i32, 16); + vqrshrns_n_s32(arg_i32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrns_n_s32(arg_i32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_high_n_s32(arg_i16x4, arg_i32x4, 1); + vqrshrn_high_n_s32(arg_i16x4, arg_i32x4, 16); + vqrshrn_high_n_s32(arg_i16x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_high_n_s32(arg_i16x4, arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_rounding_shift_right_and_narrow_s64(uint32x2_t arg_u32x2, int64x2_t arg_i64x2, + int32x2_t arg_i32x2, int64_t arg_i64) { + vqrshrun_n_s64(arg_i64x2, 1); + vqrshrun_n_s64(arg_i64x2, 32); + vqrshrun_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrun_n_s64(arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrund_n_s64(arg_i64, 1); + vqrshrund_n_s64(arg_i64, 32); + vqrshrund_n_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrund_n_s64(arg_i64, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrun_high_n_s64(arg_u32x2, arg_i64x2, 1); + vqrshrun_high_n_s64(arg_u32x2, arg_i64x2, 32); + vqrshrun_high_n_s64(arg_u32x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrun_high_n_s64(arg_u32x2, arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_n_s64(arg_i64x2, 1); + vqrshrn_n_s64(arg_i64x2, 32); + vqrshrn_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_n_s64(arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrnd_n_s64(arg_i64, 1); + vqrshrnd_n_s64(arg_i64, 32); + vqrshrnd_n_s64(arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrnd_n_s64(arg_i64, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_high_n_s64(arg_i32x2, arg_i64x2, 1); + vqrshrn_high_n_s64(arg_i32x2, arg_i64x2, 32); + vqrshrn_high_n_s64(arg_i32x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_high_n_s64(arg_i32x2, arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_rounding_shift_right_and_narrow_u16(uint16x8_t arg_u16x8, uint16_t arg_u16, + uint8x8_t arg_u8x8) { + vqrshrn_n_u16(arg_u16x8, 1); + vqrshrn_n_u16(arg_u16x8, 8); + vqrshrn_n_u16(arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_n_u16(arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrnh_n_u16(arg_u16, 1); + vqrshrnh_n_u16(arg_u16, 8); + vqrshrnh_n_u16(arg_u16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrnh_n_u16(arg_u16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_high_n_u16(arg_u8x8, arg_u16x8, 1); + vqrshrn_high_n_u16(arg_u8x8, arg_u16x8, 8); + vqrshrn_high_n_u16(arg_u8x8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_high_n_u16(arg_u8x8, arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_rounding_shift_right_and_narrow_u32(uint32x4_t arg_u32x4, uint32_t arg_u32, + uint16x4_t arg_u16x4) { + vqrshrn_n_u32(arg_u32x4, 1); + vqrshrn_n_u32(arg_u32x4, 16); + vqrshrn_n_u32(arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_n_u32(arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrns_n_u32(arg_u32, 1); + vqrshrns_n_u32(arg_u32, 16); + vqrshrns_n_u32(arg_u32, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrns_n_u32(arg_u32, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_high_n_u32(arg_u16x4, arg_u32x4, 1); + vqrshrn_high_n_u32(arg_u16x4, arg_u32x4, 16); + vqrshrn_high_n_u32(arg_u16x4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_high_n_u32(arg_u16x4, arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_saturating_rounding_shift_right_and_narrow_u64(uint64x2_t arg_u64x2, uint32x2_t arg_u32x2, + uint64_t arg_u64) { + vqrshrn_n_u64(arg_u64x2, 1); + vqrshrn_n_u64(arg_u64x2, 32); + vqrshrn_n_u64(arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_n_u64(arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrnd_n_u64(arg_u64, 1); + vqrshrnd_n_u64(arg_u64, 32); + vqrshrnd_n_u64(arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrnd_n_u64(arg_u64, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vqrshrn_high_n_u64(arg_u32x2, arg_u64x2, 1); + vqrshrn_high_n_u64(arg_u32x2, arg_u64x2, 32); + vqrshrn_high_n_u64(arg_u32x2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vqrshrn_high_n_u64(arg_u32x2, arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_narrow_s16(int16x8_t arg_i16x8, int8x8_t arg_i8x8) { + vrshrn_n_s16(arg_i16x8, 1); + vrshrn_n_s16(arg_i16x8, 8); + vrshrn_n_s16(arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_n_s16(arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrn_high_n_s16(arg_i8x8, arg_i16x8, 1); + vrshrn_high_n_s16(arg_i8x8, arg_i16x8, 8); + vrshrn_high_n_s16(arg_i8x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_high_n_s16(arg_i8x8, arg_i16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_narrow_s32(int32x4_t arg_i32x4, int16x4_t arg_i16x4) { + vrshrn_n_s32(arg_i32x4, 1); + vrshrn_n_s32(arg_i32x4, 16); + vrshrn_n_s32(arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_n_s32(arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrn_high_n_s32(arg_i16x4, arg_i32x4, 1); + vrshrn_high_n_s32(arg_i16x4, arg_i32x4, 16); + vrshrn_high_n_s32(arg_i16x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_high_n_s32(arg_i16x4, arg_i32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_narrow_s64(int32x2_t arg_i32x2, int64x2_t arg_i64x2) { + vrshrn_n_s64(arg_i64x2, 1); + vrshrn_n_s64(arg_i64x2, 32); + vrshrn_n_s64(arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_n_s64(arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrn_high_n_s64(arg_i32x2, arg_i64x2, 1); + vrshrn_high_n_s64(arg_i32x2, arg_i64x2, 32); + vrshrn_high_n_s64(arg_i32x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_high_n_s64(arg_i32x2, arg_i64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_narrow_u16(uint16x8_t arg_u16x8, uint8x8_t arg_u8x8) { + vrshrn_n_u16(arg_u16x8, 1); + vrshrn_n_u16(arg_u16x8, 8); + vrshrn_n_u16(arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_n_u16(arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrn_high_n_u16(arg_u8x8, arg_u16x8, 1); + vrshrn_high_n_u16(arg_u8x8, arg_u16x8, 8); + vrshrn_high_n_u16(arg_u8x8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_high_n_u16(arg_u8x8, arg_u16x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_narrow_u32(uint32x4_t arg_u32x4, uint16x4_t arg_u16x4) { + vrshrn_n_u32(arg_u32x4, 1); + vrshrn_n_u32(arg_u32x4, 16); + vrshrn_n_u32(arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_n_u32(arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrn_high_n_u32(arg_u16x4, arg_u32x4, 1); + vrshrn_high_n_u32(arg_u16x4, arg_u32x4, 16); + vrshrn_high_n_u32(arg_u16x4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_high_n_u32(arg_u16x4, arg_u32x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_rounding_shift_right_and_narrow_u64(uint64x2_t arg_u64x2, uint32x2_t arg_u32x2) { + vrshrn_n_u64(arg_u64x2, 1); + vrshrn_n_u64(arg_u64x2, 32); + vrshrn_n_u64(arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_n_u64(arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vrshrn_high_n_u64(arg_u32x2, arg_u64x2, 1); + vrshrn_high_n_u64(arg_u32x2, arg_u64x2, 32); + vrshrn_high_n_u64(arg_u32x2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vrshrn_high_n_u64(arg_u32x2, arg_u64x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_s8(int8x8_t arg_i8x8, int8x16_t arg_i8x16) { + vsri_n_s8(arg_i8x8, arg_i8x8, 1); + vsri_n_s8(arg_i8x8, arg_i8x8, 8); + vsri_n_s8(arg_i8x8, arg_i8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_s8(arg_i8x8, arg_i8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_s8(arg_i8x16, arg_i8x16, 1); + vsriq_n_s8(arg_i8x16, arg_i8x16, 8); + vsriq_n_s8(arg_i8x16, arg_i8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_s8(arg_i8x16, arg_i8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_s16(int16x4_t arg_i16x4, int16x8_t arg_i16x8) { + vsri_n_s16(arg_i16x4, arg_i16x4, 1); + vsri_n_s16(arg_i16x4, arg_i16x4, 16); + vsri_n_s16(arg_i16x4, arg_i16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_s16(arg_i16x4, arg_i16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_s16(arg_i16x8, arg_i16x8, 1); + vsriq_n_s16(arg_i16x8, arg_i16x8, 16); + vsriq_n_s16(arg_i16x8, arg_i16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_s16(arg_i16x8, arg_i16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_s32(int32x2_t arg_i32x2, int32x4_t arg_i32x4) { + vsri_n_s32(arg_i32x2, arg_i32x2, 1); + vsri_n_s32(arg_i32x2, arg_i32x2, 32); + vsri_n_s32(arg_i32x2, arg_i32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_s32(arg_i32x2, arg_i32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_s32(arg_i32x4, arg_i32x4, 1); + vsriq_n_s32(arg_i32x4, arg_i32x4, 32); + vsriq_n_s32(arg_i32x4, arg_i32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_s32(arg_i32x4, arg_i32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_s64(int64_t arg_i64, int64x1_t arg_i64x1, int64x2_t arg_i64x2) { + vsri_n_s64(arg_i64x1, arg_i64x1, 1); + vsri_n_s64(arg_i64x1, arg_i64x1, 64); + vsri_n_s64(arg_i64x1, arg_i64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_s64(arg_i64x1, arg_i64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_s64(arg_i64x2, arg_i64x2, 1); + vsriq_n_s64(arg_i64x2, arg_i64x2, 64); + vsriq_n_s64(arg_i64x2, arg_i64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_s64(arg_i64x2, arg_i64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsrid_n_s64(arg_i64, arg_i64, 1); + vsrid_n_s64(arg_i64, arg_i64, 64); + vsrid_n_s64(arg_i64, arg_i64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsrid_n_s64(arg_i64, arg_i64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_u8(uint8x16_t arg_u8x16, uint8x8_t arg_u8x8) { + vsri_n_u8(arg_u8x8, arg_u8x8, 1); + vsri_n_u8(arg_u8x8, arg_u8x8, 8); + vsri_n_u8(arg_u8x8, arg_u8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_u8(arg_u8x8, arg_u8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_u8(arg_u8x16, arg_u8x16, 1); + vsriq_n_u8(arg_u8x16, arg_u8x16, 8); + vsriq_n_u8(arg_u8x16, arg_u8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_u8(arg_u8x16, arg_u8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_u16(uint16x8_t arg_u16x8, uint16x4_t arg_u16x4) { + vsri_n_u16(arg_u16x4, arg_u16x4, 1); + vsri_n_u16(arg_u16x4, arg_u16x4, 16); + vsri_n_u16(arg_u16x4, arg_u16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_u16(arg_u16x4, arg_u16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_u16(arg_u16x8, arg_u16x8, 1); + vsriq_n_u16(arg_u16x8, arg_u16x8, 16); + vsriq_n_u16(arg_u16x8, arg_u16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_u16(arg_u16x8, arg_u16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_u32(uint32x2_t arg_u32x2, uint32x4_t arg_u32x4) { + vsri_n_u32(arg_u32x2, arg_u32x2, 1); + vsri_n_u32(arg_u32x2, arg_u32x2, 32); + vsri_n_u32(arg_u32x2, arg_u32x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_u32(arg_u32x2, arg_u32x2, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_u32(arg_u32x4, arg_u32x4, 1); + vsriq_n_u32(arg_u32x4, arg_u32x4, 32); + vsriq_n_u32(arg_u32x4, arg_u32x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_u32(arg_u32x4, arg_u32x4, 33); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_u64(uint64x2_t arg_u64x2, uint64_t arg_u64, uint64x1_t arg_u64x1) { + vsri_n_u64(arg_u64x1, arg_u64x1, 1); + vsri_n_u64(arg_u64x1, arg_u64x1, 64); + vsri_n_u64(arg_u64x1, arg_u64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_u64(arg_u64x1, arg_u64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_u64(arg_u64x2, arg_u64x2, 1); + vsriq_n_u64(arg_u64x2, arg_u64x2, 64); + vsriq_n_u64(arg_u64x2, arg_u64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_u64(arg_u64x2, arg_u64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsrid_n_u64(arg_u64, arg_u64, 1); + vsrid_n_u64(arg_u64, arg_u64, 64); + vsrid_n_u64(arg_u64, arg_u64, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsrid_n_u64(arg_u64, arg_u64, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_p64(poly64x2_t arg_p64x2, poly64x1_t arg_p64x1) { + vsri_n_p64(arg_p64x1, arg_p64x1, 1); + vsri_n_p64(arg_p64x1, arg_p64x1, 64); + vsri_n_p64(arg_p64x1, arg_p64x1, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_p64(arg_p64x1, arg_p64x1, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_p64(arg_p64x2, arg_p64x2, 1); + vsriq_n_p64(arg_p64x2, arg_p64x2, 64); + vsriq_n_p64(arg_p64x2, arg_p64x2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_p64(arg_p64x2, arg_p64x2, 65); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_p8(poly8x16_t arg_p8x16, poly8x8_t arg_p8x8) { + vsri_n_p8(arg_p8x8, arg_p8x8, 1); + vsri_n_p8(arg_p8x8, arg_p8x8, 8); + vsri_n_p8(arg_p8x8, arg_p8x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_p8(arg_p8x8, arg_p8x8, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_p8(arg_p8x16, arg_p8x16, 1); + vsriq_n_p8(arg_p8x16, arg_p8x16, 8); + vsriq_n_p8(arg_p8x16, arg_p8x16, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_p8(arg_p8x16, arg_p8x16, 9); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_shift_right_and_insert_p16(poly16x4_t arg_p16x4, poly16x8_t arg_p16x8) { + vsri_n_p16(arg_p16x4, arg_p16x4, 1); + vsri_n_p16(arg_p16x4, arg_p16x4, 16); + vsri_n_p16(arg_p16x4, arg_p16x4, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsri_n_p16(arg_p16x4, arg_p16x4, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vsriq_n_p16(arg_p16x8, arg_p16x8, 1); + vsriq_n_p16(arg_p16x8, arg_p16x8, 16); + vsriq_n_p16(arg_p16x8, arg_p16x8, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vsriq_n_p16(arg_p16x8, arg_p16x8, 17); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-immediate-ranges/vector-store.c b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-store.c new file mode 100644 index 0000000000000..a35891c9adbb5 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-immediate-ranges/vector-store.c @@ -0,0 +1,620 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s + +#include +// REQUIRES: aarch64-registered-target + + +void test_vector_store_s8(int8x8_t arg_i8x8, int8x8x3_t arg_i8x8x3, int8_t* arg_i8_ptr, + int8x16x3_t arg_i8x16x3, int8x8x4_t arg_i8x8x4, int8x16x4_t arg_i8x16x4, + int8x8x2_t arg_i8x8x2, int8x16_t arg_i8x16, int8x16x2_t arg_i8x16x2) { + vst1_lane_s8(arg_i8_ptr, arg_i8x8, 0); + vst1_lane_s8(arg_i8_ptr, arg_i8x8, 7); + vst1_lane_s8(arg_i8_ptr, arg_i8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_s8(arg_i8_ptr, arg_i8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_s8(arg_i8_ptr, arg_i8x16, 0); + vst1q_lane_s8(arg_i8_ptr, arg_i8x16, 15); + vst1q_lane_s8(arg_i8_ptr, arg_i8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_s8(arg_i8_ptr, arg_i8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_s8(arg_i8_ptr, arg_i8x8x2, 0); + vst2_lane_s8(arg_i8_ptr, arg_i8x8x2, 7); + vst2_lane_s8(arg_i8_ptr, arg_i8x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_s8(arg_i8_ptr, arg_i8x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_s8(arg_i8_ptr, arg_i8x8x3, 0); + vst3_lane_s8(arg_i8_ptr, arg_i8x8x3, 7); + vst3_lane_s8(arg_i8_ptr, arg_i8x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_s8(arg_i8_ptr, arg_i8x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_s8(arg_i8_ptr, arg_i8x8x4, 0); + vst4_lane_s8(arg_i8_ptr, arg_i8x8x4, 7); + vst4_lane_s8(arg_i8_ptr, arg_i8x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_s8(arg_i8_ptr, arg_i8x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_s8(arg_i8_ptr, arg_i8x16x2, 0); + vst2q_lane_s8(arg_i8_ptr, arg_i8x16x2, 15); + vst2q_lane_s8(arg_i8_ptr, arg_i8x16x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_s8(arg_i8_ptr, arg_i8x16x2, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_s8(arg_i8_ptr, arg_i8x16x3, 0); + vst3q_lane_s8(arg_i8_ptr, arg_i8x16x3, 15); + vst3q_lane_s8(arg_i8_ptr, arg_i8x16x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_s8(arg_i8_ptr, arg_i8x16x3, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_s8(arg_i8_ptr, arg_i8x16x4, 0); + vst4q_lane_s8(arg_i8_ptr, arg_i8x16x4, 15); + vst4q_lane_s8(arg_i8_ptr, arg_i8x16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_s8(arg_i8_ptr, arg_i8x16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_s16(int16x8x3_t arg_i16x8x3, int16x4_t arg_i16x4, int16x4x3_t arg_i16x4x3, + int16x8_t arg_i16x8, int16_t* arg_i16_ptr, int16x8x2_t arg_i16x8x2, + int16x8x4_t arg_i16x8x4, int16x4x4_t arg_i16x4x4, int16x4x2_t arg_i16x4x2) { + vst1_lane_s16(arg_i16_ptr, arg_i16x4, 0); + vst1_lane_s16(arg_i16_ptr, arg_i16x4, 3); + vst1_lane_s16(arg_i16_ptr, arg_i16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_s16(arg_i16_ptr, arg_i16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_s16(arg_i16_ptr, arg_i16x8, 0); + vst1q_lane_s16(arg_i16_ptr, arg_i16x8, 7); + vst1q_lane_s16(arg_i16_ptr, arg_i16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_s16(arg_i16_ptr, arg_i16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_s16(arg_i16_ptr, arg_i16x4x2, 0); + vst2_lane_s16(arg_i16_ptr, arg_i16x4x2, 3); + vst2_lane_s16(arg_i16_ptr, arg_i16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_s16(arg_i16_ptr, arg_i16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_s16(arg_i16_ptr, arg_i16x8x2, 0); + vst2q_lane_s16(arg_i16_ptr, arg_i16x8x2, 7); + vst2q_lane_s16(arg_i16_ptr, arg_i16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_s16(arg_i16_ptr, arg_i16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_s16(arg_i16_ptr, arg_i16x4x3, 0); + vst3_lane_s16(arg_i16_ptr, arg_i16x4x3, 3); + vst3_lane_s16(arg_i16_ptr, arg_i16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_s16(arg_i16_ptr, arg_i16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_s16(arg_i16_ptr, arg_i16x8x3, 0); + vst3q_lane_s16(arg_i16_ptr, arg_i16x8x3, 7); + vst3q_lane_s16(arg_i16_ptr, arg_i16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_s16(arg_i16_ptr, arg_i16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_s16(arg_i16_ptr, arg_i16x4x4, 0); + vst4_lane_s16(arg_i16_ptr, arg_i16x4x4, 3); + vst4_lane_s16(arg_i16_ptr, arg_i16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_s16(arg_i16_ptr, arg_i16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_s16(arg_i16_ptr, arg_i16x8x4, 0); + vst4q_lane_s16(arg_i16_ptr, arg_i16x8x4, 7); + vst4q_lane_s16(arg_i16_ptr, arg_i16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_s16(arg_i16_ptr, arg_i16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_s32(int32x4x3_t arg_i32x4x3, int32x4_t arg_i32x4, int32x2x2_t arg_i32x2x2, + int32x2x3_t arg_i32x2x3, int32x4x4_t arg_i32x4x4, int32x4x2_t arg_i32x4x2, + int32x2_t arg_i32x2, int32x2x4_t arg_i32x2x4, int32_t* arg_i32_ptr) { + vst1_lane_s32(arg_i32_ptr, arg_i32x2, 0); + vst1_lane_s32(arg_i32_ptr, arg_i32x2, 1); + vst1_lane_s32(arg_i32_ptr, arg_i32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_s32(arg_i32_ptr, arg_i32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_s32(arg_i32_ptr, arg_i32x4, 0); + vst1q_lane_s32(arg_i32_ptr, arg_i32x4, 3); + vst1q_lane_s32(arg_i32_ptr, arg_i32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_s32(arg_i32_ptr, arg_i32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_s32(arg_i32_ptr, arg_i32x2x2, 0); + vst2_lane_s32(arg_i32_ptr, arg_i32x2x2, 1); + vst2_lane_s32(arg_i32_ptr, arg_i32x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_s32(arg_i32_ptr, arg_i32x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_s32(arg_i32_ptr, arg_i32x4x2, 0); + vst2q_lane_s32(arg_i32_ptr, arg_i32x4x2, 3); + vst2q_lane_s32(arg_i32_ptr, arg_i32x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_s32(arg_i32_ptr, arg_i32x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_s32(arg_i32_ptr, arg_i32x2x3, 0); + vst3_lane_s32(arg_i32_ptr, arg_i32x2x3, 1); + vst3_lane_s32(arg_i32_ptr, arg_i32x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_s32(arg_i32_ptr, arg_i32x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_s32(arg_i32_ptr, arg_i32x4x3, 0); + vst3q_lane_s32(arg_i32_ptr, arg_i32x4x3, 3); + vst3q_lane_s32(arg_i32_ptr, arg_i32x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_s32(arg_i32_ptr, arg_i32x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_s32(arg_i32_ptr, arg_i32x2x4, 0); + vst4_lane_s32(arg_i32_ptr, arg_i32x2x4, 1); + vst4_lane_s32(arg_i32_ptr, arg_i32x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_s32(arg_i32_ptr, arg_i32x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_s32(arg_i32_ptr, arg_i32x4x4, 0); + vst4q_lane_s32(arg_i32_ptr, arg_i32x4x4, 3); + vst4q_lane_s32(arg_i32_ptr, arg_i32x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_s32(arg_i32_ptr, arg_i32x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_s64(int64x2x2_t arg_i64x2x2, int64_t* arg_i64_ptr, int64x1_t arg_i64x1, + int64x2x4_t arg_i64x2x4, int64x1x4_t arg_i64x1x4, int64x1x2_t arg_i64x1x2, + int64x1x3_t arg_i64x1x3, int64x2x3_t arg_i64x2x3, int64x2_t arg_i64x2) { + vst1_lane_s64(arg_i64_ptr, arg_i64x1, 0); + vst1_lane_s64(arg_i64_ptr, arg_i64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_s64(arg_i64_ptr, arg_i64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_s64(arg_i64_ptr, arg_i64x2, 0); + vst1q_lane_s64(arg_i64_ptr, arg_i64x2, 1); + vst1q_lane_s64(arg_i64_ptr, arg_i64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_s64(arg_i64_ptr, arg_i64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_s64(arg_i64_ptr, arg_i64x1x2, 0); + vst2_lane_s64(arg_i64_ptr, arg_i64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_s64(arg_i64_ptr, arg_i64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_s64(arg_i64_ptr, arg_i64x2x2, 0); + vst2q_lane_s64(arg_i64_ptr, arg_i64x2x2, 1); + vst2q_lane_s64(arg_i64_ptr, arg_i64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_s64(arg_i64_ptr, arg_i64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_s64(arg_i64_ptr, arg_i64x1x3, 0); + vst3_lane_s64(arg_i64_ptr, arg_i64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_s64(arg_i64_ptr, arg_i64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_s64(arg_i64_ptr, arg_i64x2x3, 0); + vst3q_lane_s64(arg_i64_ptr, arg_i64x2x3, 1); + vst3q_lane_s64(arg_i64_ptr, arg_i64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_s64(arg_i64_ptr, arg_i64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_s64(arg_i64_ptr, arg_i64x1x4, 0); + vst4_lane_s64(arg_i64_ptr, arg_i64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_s64(arg_i64_ptr, arg_i64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_s64(arg_i64_ptr, arg_i64x2x4, 0); + vst4q_lane_s64(arg_i64_ptr, arg_i64x2x4, 1); + vst4q_lane_s64(arg_i64_ptr, arg_i64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_s64(arg_i64_ptr, arg_i64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_u8(uint8x16_t arg_u8x16, uint8x16x3_t arg_u8x16x3, uint8x8x4_t arg_u8x8x4, + uint8x16x2_t arg_u8x16x2, uint8x8_t arg_u8x8, uint8x8x3_t arg_u8x8x3, + uint8x16x4_t arg_u8x16x4, uint8_t* arg_u8_ptr, uint8x8x2_t arg_u8x8x2) { + vst1_lane_u8(arg_u8_ptr, arg_u8x8, 0); + vst1_lane_u8(arg_u8_ptr, arg_u8x8, 7); + vst1_lane_u8(arg_u8_ptr, arg_u8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_u8(arg_u8_ptr, arg_u8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_u8(arg_u8_ptr, arg_u8x16, 0); + vst1q_lane_u8(arg_u8_ptr, arg_u8x16, 15); + vst1q_lane_u8(arg_u8_ptr, arg_u8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_u8(arg_u8_ptr, arg_u8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_u8(arg_u8_ptr, arg_u8x8x2, 0); + vst2_lane_u8(arg_u8_ptr, arg_u8x8x2, 7); + vst2_lane_u8(arg_u8_ptr, arg_u8x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_u8(arg_u8_ptr, arg_u8x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_u8(arg_u8_ptr, arg_u8x8x3, 0); + vst3_lane_u8(arg_u8_ptr, arg_u8x8x3, 7); + vst3_lane_u8(arg_u8_ptr, arg_u8x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_u8(arg_u8_ptr, arg_u8x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_u8(arg_u8_ptr, arg_u8x8x4, 0); + vst4_lane_u8(arg_u8_ptr, arg_u8x8x4, 7); + vst4_lane_u8(arg_u8_ptr, arg_u8x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_u8(arg_u8_ptr, arg_u8x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_u8(arg_u8_ptr, arg_u8x16x2, 0); + vst2q_lane_u8(arg_u8_ptr, arg_u8x16x2, 15); + vst2q_lane_u8(arg_u8_ptr, arg_u8x16x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_u8(arg_u8_ptr, arg_u8x16x2, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_u8(arg_u8_ptr, arg_u8x16x3, 0); + vst3q_lane_u8(arg_u8_ptr, arg_u8x16x3, 15); + vst3q_lane_u8(arg_u8_ptr, arg_u8x16x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_u8(arg_u8_ptr, arg_u8x16x3, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_u8(arg_u8_ptr, arg_u8x16x4, 0); + vst4q_lane_u8(arg_u8_ptr, arg_u8x16x4, 15); + vst4q_lane_u8(arg_u8_ptr, arg_u8x16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_u8(arg_u8_ptr, arg_u8x16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_u16(uint16x8x3_t arg_u16x8x3, uint16x4x4_t arg_u16x4x4, uint16_t* arg_u16_ptr, + uint16x4_t arg_u16x4, uint16x4x2_t arg_u16x4x2, uint16x4x3_t arg_u16x4x3, + uint16x8_t arg_u16x8, uint16x8x2_t arg_u16x8x2, uint16x8x4_t arg_u16x8x4) { + vst1_lane_u16(arg_u16_ptr, arg_u16x4, 0); + vst1_lane_u16(arg_u16_ptr, arg_u16x4, 3); + vst1_lane_u16(arg_u16_ptr, arg_u16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_u16(arg_u16_ptr, arg_u16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_u16(arg_u16_ptr, arg_u16x8, 0); + vst1q_lane_u16(arg_u16_ptr, arg_u16x8, 7); + vst1q_lane_u16(arg_u16_ptr, arg_u16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_u16(arg_u16_ptr, arg_u16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_u16(arg_u16_ptr, arg_u16x4x2, 0); + vst2_lane_u16(arg_u16_ptr, arg_u16x4x2, 3); + vst2_lane_u16(arg_u16_ptr, arg_u16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_u16(arg_u16_ptr, arg_u16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_u16(arg_u16_ptr, arg_u16x8x2, 0); + vst2q_lane_u16(arg_u16_ptr, arg_u16x8x2, 7); + vst2q_lane_u16(arg_u16_ptr, arg_u16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_u16(arg_u16_ptr, arg_u16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_u16(arg_u16_ptr, arg_u16x4x3, 0); + vst3_lane_u16(arg_u16_ptr, arg_u16x4x3, 3); + vst3_lane_u16(arg_u16_ptr, arg_u16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_u16(arg_u16_ptr, arg_u16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_u16(arg_u16_ptr, arg_u16x8x3, 0); + vst3q_lane_u16(arg_u16_ptr, arg_u16x8x3, 7); + vst3q_lane_u16(arg_u16_ptr, arg_u16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_u16(arg_u16_ptr, arg_u16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_u16(arg_u16_ptr, arg_u16x4x4, 0); + vst4_lane_u16(arg_u16_ptr, arg_u16x4x4, 3); + vst4_lane_u16(arg_u16_ptr, arg_u16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_u16(arg_u16_ptr, arg_u16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_u16(arg_u16_ptr, arg_u16x8x4, 0); + vst4q_lane_u16(arg_u16_ptr, arg_u16x8x4, 7); + vst4q_lane_u16(arg_u16_ptr, arg_u16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_u16(arg_u16_ptr, arg_u16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_u32(uint32x4x3_t arg_u32x4x3, uint32x2_t arg_u32x2, uint32x2x3_t arg_u32x2x3, + uint32x4x4_t arg_u32x4x4, uint32x4_t arg_u32x4, uint32x2x2_t arg_u32x2x2, + uint32_t* arg_u32_ptr, uint32x2x4_t arg_u32x2x4, uint32x4x2_t arg_u32x4x2) { + vst1_lane_u32(arg_u32_ptr, arg_u32x2, 0); + vst1_lane_u32(arg_u32_ptr, arg_u32x2, 1); + vst1_lane_u32(arg_u32_ptr, arg_u32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_u32(arg_u32_ptr, arg_u32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_u32(arg_u32_ptr, arg_u32x4, 0); + vst1q_lane_u32(arg_u32_ptr, arg_u32x4, 3); + vst1q_lane_u32(arg_u32_ptr, arg_u32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_u32(arg_u32_ptr, arg_u32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_u32(arg_u32_ptr, arg_u32x2x2, 0); + vst2_lane_u32(arg_u32_ptr, arg_u32x2x2, 1); + vst2_lane_u32(arg_u32_ptr, arg_u32x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_u32(arg_u32_ptr, arg_u32x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_u32(arg_u32_ptr, arg_u32x4x2, 0); + vst2q_lane_u32(arg_u32_ptr, arg_u32x4x2, 3); + vst2q_lane_u32(arg_u32_ptr, arg_u32x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_u32(arg_u32_ptr, arg_u32x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_u32(arg_u32_ptr, arg_u32x2x3, 0); + vst3_lane_u32(arg_u32_ptr, arg_u32x2x3, 1); + vst3_lane_u32(arg_u32_ptr, arg_u32x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_u32(arg_u32_ptr, arg_u32x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_u32(arg_u32_ptr, arg_u32x4x3, 0); + vst3q_lane_u32(arg_u32_ptr, arg_u32x4x3, 3); + vst3q_lane_u32(arg_u32_ptr, arg_u32x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_u32(arg_u32_ptr, arg_u32x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_u32(arg_u32_ptr, arg_u32x2x4, 0); + vst4_lane_u32(arg_u32_ptr, arg_u32x2x4, 1); + vst4_lane_u32(arg_u32_ptr, arg_u32x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_u32(arg_u32_ptr, arg_u32x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_u32(arg_u32_ptr, arg_u32x4x4, 0); + vst4q_lane_u32(arg_u32_ptr, arg_u32x4x4, 3); + vst4q_lane_u32(arg_u32_ptr, arg_u32x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_u32(arg_u32_ptr, arg_u32x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_u64(uint64x2x3_t arg_u64x2x3, uint64x1_t arg_u64x1, uint64x2_t arg_u64x2, + uint64x1x2_t arg_u64x1x2, uint64x2x2_t arg_u64x2x2, uint64x1x3_t arg_u64x1x3, + uint64_t* arg_u64_ptr, uint64x2x4_t arg_u64x2x4, uint64x1x4_t arg_u64x1x4) { + vst1_lane_u64(arg_u64_ptr, arg_u64x1, 0); + vst1_lane_u64(arg_u64_ptr, arg_u64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_u64(arg_u64_ptr, arg_u64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_u64(arg_u64_ptr, arg_u64x2, 0); + vst1q_lane_u64(arg_u64_ptr, arg_u64x2, 1); + vst1q_lane_u64(arg_u64_ptr, arg_u64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_u64(arg_u64_ptr, arg_u64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_u64(arg_u64_ptr, arg_u64x1x2, 0); + vst2_lane_u64(arg_u64_ptr, arg_u64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_u64(arg_u64_ptr, arg_u64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_u64(arg_u64_ptr, arg_u64x2x2, 0); + vst2q_lane_u64(arg_u64_ptr, arg_u64x2x2, 1); + vst2q_lane_u64(arg_u64_ptr, arg_u64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_u64(arg_u64_ptr, arg_u64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_u64(arg_u64_ptr, arg_u64x1x3, 0); + vst3_lane_u64(arg_u64_ptr, arg_u64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_u64(arg_u64_ptr, arg_u64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_u64(arg_u64_ptr, arg_u64x2x3, 0); + vst3q_lane_u64(arg_u64_ptr, arg_u64x2x3, 1); + vst3q_lane_u64(arg_u64_ptr, arg_u64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_u64(arg_u64_ptr, arg_u64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_u64(arg_u64_ptr, arg_u64x1x4, 0); + vst4_lane_u64(arg_u64_ptr, arg_u64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_u64(arg_u64_ptr, arg_u64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_u64(arg_u64_ptr, arg_u64x2x4, 0); + vst4q_lane_u64(arg_u64_ptr, arg_u64x2x4, 1); + vst4q_lane_u64(arg_u64_ptr, arg_u64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_u64(arg_u64_ptr, arg_u64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_p64(poly64x2x4_t arg_p64x2x4, poly64x1x3_t arg_p64x1x3, poly64x1_t arg_p64x1, + poly64x2x2_t arg_p64x2x2, poly64x1x4_t arg_p64x1x4, poly64_t* arg_p64_ptr, + poly64x1x2_t arg_p64x1x2, poly64x2_t arg_p64x2, poly64x2x3_t arg_p64x2x3) { + vst1_lane_p64(arg_p64_ptr, arg_p64x1, 0); + vst1_lane_p64(arg_p64_ptr, arg_p64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_p64(arg_p64_ptr, arg_p64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_p64(arg_p64_ptr, arg_p64x2, 0); + vst1q_lane_p64(arg_p64_ptr, arg_p64x2, 1); + vst1q_lane_p64(arg_p64_ptr, arg_p64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_p64(arg_p64_ptr, arg_p64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_p64(arg_p64_ptr, arg_p64x1x2, 0); + vst2_lane_p64(arg_p64_ptr, arg_p64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_p64(arg_p64_ptr, arg_p64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_p64(arg_p64_ptr, arg_p64x2x2, 0); + vst2q_lane_p64(arg_p64_ptr, arg_p64x2x2, 1); + vst2q_lane_p64(arg_p64_ptr, arg_p64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_p64(arg_p64_ptr, arg_p64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_p64(arg_p64_ptr, arg_p64x1x3, 0); + vst3_lane_p64(arg_p64_ptr, arg_p64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_p64(arg_p64_ptr, arg_p64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_p64(arg_p64_ptr, arg_p64x2x3, 0); + vst3q_lane_p64(arg_p64_ptr, arg_p64x2x3, 1); + vst3q_lane_p64(arg_p64_ptr, arg_p64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_p64(arg_p64_ptr, arg_p64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_p64(arg_p64_ptr, arg_p64x1x4, 0); + vst4_lane_p64(arg_p64_ptr, arg_p64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_p64(arg_p64_ptr, arg_p64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_p64(arg_p64_ptr, arg_p64x2x4, 0); + vst4q_lane_p64(arg_p64_ptr, arg_p64x2x4, 1); + vst4q_lane_p64(arg_p64_ptr, arg_p64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_p64(arg_p64_ptr, arg_p64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_f16(float16x4x4_t arg_f16x4x4, float16x8_t arg_f16x8, float16x8x2_t arg_f16x8x2, + float16x8x3_t arg_f16x8x3, float16x4x2_t arg_f16x4x2, float16x4x3_t arg_f16x4x3, + float16x4_t arg_f16x4, float16_t* arg_f16_ptr, float16x8x4_t arg_f16x8x4) { + vst1_lane_f16(arg_f16_ptr, arg_f16x4, 0); + vst1_lane_f16(arg_f16_ptr, arg_f16x4, 3); + vst1_lane_f16(arg_f16_ptr, arg_f16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_f16(arg_f16_ptr, arg_f16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_f16(arg_f16_ptr, arg_f16x8, 0); + vst1q_lane_f16(arg_f16_ptr, arg_f16x8, 7); + vst1q_lane_f16(arg_f16_ptr, arg_f16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_f16(arg_f16_ptr, arg_f16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_f16(arg_f16_ptr, arg_f16x4x2, 0); + vst2_lane_f16(arg_f16_ptr, arg_f16x4x2, 3); + vst2_lane_f16(arg_f16_ptr, arg_f16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_f16(arg_f16_ptr, arg_f16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_f16(arg_f16_ptr, arg_f16x8x2, 0); + vst2q_lane_f16(arg_f16_ptr, arg_f16x8x2, 7); + vst2q_lane_f16(arg_f16_ptr, arg_f16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_f16(arg_f16_ptr, arg_f16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_f16(arg_f16_ptr, arg_f16x4x3, 0); + vst3_lane_f16(arg_f16_ptr, arg_f16x4x3, 3); + vst3_lane_f16(arg_f16_ptr, arg_f16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_f16(arg_f16_ptr, arg_f16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_f16(arg_f16_ptr, arg_f16x8x3, 0); + vst3q_lane_f16(arg_f16_ptr, arg_f16x8x3, 7); + vst3q_lane_f16(arg_f16_ptr, arg_f16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_f16(arg_f16_ptr, arg_f16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_f16(arg_f16_ptr, arg_f16x4x4, 0); + vst4_lane_f16(arg_f16_ptr, arg_f16x4x4, 3); + vst4_lane_f16(arg_f16_ptr, arg_f16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_f16(arg_f16_ptr, arg_f16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_f16(arg_f16_ptr, arg_f16x8x4, 0); + vst4q_lane_f16(arg_f16_ptr, arg_f16x8x4, 7); + vst4q_lane_f16(arg_f16_ptr, arg_f16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_f16(arg_f16_ptr, arg_f16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_f32(float32x2x3_t arg_f32x2x3, float32x2x2_t arg_f32x2x2, float32x4_t arg_f32x4, + float32x4x3_t arg_f32x4x3, float32_t* arg_f32_ptr, float32x4x4_t arg_f32x4x4, + float32x2x4_t arg_f32x2x4, float32x2_t arg_f32x2, float32x4x2_t arg_f32x4x2) { + vst1_lane_f32(arg_f32_ptr, arg_f32x2, 0); + vst1_lane_f32(arg_f32_ptr, arg_f32x2, 1); + vst1_lane_f32(arg_f32_ptr, arg_f32x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_f32(arg_f32_ptr, arg_f32x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_f32(arg_f32_ptr, arg_f32x4, 0); + vst1q_lane_f32(arg_f32_ptr, arg_f32x4, 3); + vst1q_lane_f32(arg_f32_ptr, arg_f32x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_f32(arg_f32_ptr, arg_f32x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_f32(arg_f32_ptr, arg_f32x2x2, 0); + vst2_lane_f32(arg_f32_ptr, arg_f32x2x2, 1); + vst2_lane_f32(arg_f32_ptr, arg_f32x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_f32(arg_f32_ptr, arg_f32x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_f32(arg_f32_ptr, arg_f32x4x2, 0); + vst2q_lane_f32(arg_f32_ptr, arg_f32x4x2, 3); + vst2q_lane_f32(arg_f32_ptr, arg_f32x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_f32(arg_f32_ptr, arg_f32x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_f32(arg_f32_ptr, arg_f32x2x3, 0); + vst3_lane_f32(arg_f32_ptr, arg_f32x2x3, 1); + vst3_lane_f32(arg_f32_ptr, arg_f32x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_f32(arg_f32_ptr, arg_f32x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_f32(arg_f32_ptr, arg_f32x4x3, 0); + vst3q_lane_f32(arg_f32_ptr, arg_f32x4x3, 3); + vst3q_lane_f32(arg_f32_ptr, arg_f32x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_f32(arg_f32_ptr, arg_f32x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_f32(arg_f32_ptr, arg_f32x2x4, 0); + vst4_lane_f32(arg_f32_ptr, arg_f32x2x4, 1); + vst4_lane_f32(arg_f32_ptr, arg_f32x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_f32(arg_f32_ptr, arg_f32x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_f32(arg_f32_ptr, arg_f32x4x4, 0); + vst4q_lane_f32(arg_f32_ptr, arg_f32x4x4, 3); + vst4q_lane_f32(arg_f32_ptr, arg_f32x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_f32(arg_f32_ptr, arg_f32x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_p8(poly8x16_t arg_p8x16, poly8x16x2_t arg_p8x16x2, poly8x8x3_t arg_p8x8x3, + poly8x16x3_t arg_p8x16x3, poly8x16x4_t arg_p8x16x4, poly8x8x4_t arg_p8x8x4, + poly8_t* arg_p8_ptr, poly8x8_t arg_p8x8, poly8x8x2_t arg_p8x8x2) { + vst1_lane_p8(arg_p8_ptr, arg_p8x8, 0); + vst1_lane_p8(arg_p8_ptr, arg_p8x8, 7); + vst1_lane_p8(arg_p8_ptr, arg_p8x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_p8(arg_p8_ptr, arg_p8x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_p8(arg_p8_ptr, arg_p8x16, 0); + vst1q_lane_p8(arg_p8_ptr, arg_p8x16, 15); + vst1q_lane_p8(arg_p8_ptr, arg_p8x16, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_p8(arg_p8_ptr, arg_p8x16, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_p8(arg_p8_ptr, arg_p8x8x2, 0); + vst2_lane_p8(arg_p8_ptr, arg_p8x8x2, 7); + vst2_lane_p8(arg_p8_ptr, arg_p8x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_p8(arg_p8_ptr, arg_p8x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_p8(arg_p8_ptr, arg_p8x8x3, 0); + vst3_lane_p8(arg_p8_ptr, arg_p8x8x3, 7); + vst3_lane_p8(arg_p8_ptr, arg_p8x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_p8(arg_p8_ptr, arg_p8x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_p8(arg_p8_ptr, arg_p8x8x4, 0); + vst4_lane_p8(arg_p8_ptr, arg_p8x8x4, 7); + vst4_lane_p8(arg_p8_ptr, arg_p8x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_p8(arg_p8_ptr, arg_p8x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_p8(arg_p8_ptr, arg_p8x16x2, 0); + vst2q_lane_p8(arg_p8_ptr, arg_p8x16x2, 15); + vst2q_lane_p8(arg_p8_ptr, arg_p8x16x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_p8(arg_p8_ptr, arg_p8x16x2, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_p8(arg_p8_ptr, arg_p8x16x3, 0); + vst3q_lane_p8(arg_p8_ptr, arg_p8x16x3, 15); + vst3q_lane_p8(arg_p8_ptr, arg_p8x16x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_p8(arg_p8_ptr, arg_p8x16x3, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_p8(arg_p8_ptr, arg_p8x16x4, 0); + vst4q_lane_p8(arg_p8_ptr, arg_p8x16x4, 15); + vst4q_lane_p8(arg_p8_ptr, arg_p8x16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_p8(arg_p8_ptr, arg_p8x16x4, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_p16(poly16x4x4_t arg_p16x4x4, poly16x4_t arg_p16x4, poly16x8x2_t arg_p16x8x2, + poly16_t* arg_p16_ptr, poly16x8_t arg_p16x8, poly16x8x3_t arg_p16x8x3, + poly16x4x3_t arg_p16x4x3, poly16x8x4_t arg_p16x8x4, poly16x4x2_t arg_p16x4x2) { + vst1_lane_p16(arg_p16_ptr, arg_p16x4, 0); + vst1_lane_p16(arg_p16_ptr, arg_p16x4, 3); + vst1_lane_p16(arg_p16_ptr, arg_p16x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_p16(arg_p16_ptr, arg_p16x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_p16(arg_p16_ptr, arg_p16x8, 0); + vst1q_lane_p16(arg_p16_ptr, arg_p16x8, 7); + vst1q_lane_p16(arg_p16_ptr, arg_p16x8, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_p16(arg_p16_ptr, arg_p16x8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_p16(arg_p16_ptr, arg_p16x4x2, 0); + vst2_lane_p16(arg_p16_ptr, arg_p16x4x2, 3); + vst2_lane_p16(arg_p16_ptr, arg_p16x4x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_p16(arg_p16_ptr, arg_p16x4x2, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_p16(arg_p16_ptr, arg_p16x8x2, 0); + vst2q_lane_p16(arg_p16_ptr, arg_p16x8x2, 7); + vst2q_lane_p16(arg_p16_ptr, arg_p16x8x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_p16(arg_p16_ptr, arg_p16x8x2, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_p16(arg_p16_ptr, arg_p16x4x3, 0); + vst3_lane_p16(arg_p16_ptr, arg_p16x4x3, 3); + vst3_lane_p16(arg_p16_ptr, arg_p16x4x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_p16(arg_p16_ptr, arg_p16x4x3, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_p16(arg_p16_ptr, arg_p16x8x3, 0); + vst3q_lane_p16(arg_p16_ptr, arg_p16x8x3, 7); + vst3q_lane_p16(arg_p16_ptr, arg_p16x8x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_p16(arg_p16_ptr, arg_p16x8x3, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_p16(arg_p16_ptr, arg_p16x4x4, 0); + vst4_lane_p16(arg_p16_ptr, arg_p16x4x4, 3); + vst4_lane_p16(arg_p16_ptr, arg_p16x4x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_p16(arg_p16_ptr, arg_p16x4x4, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_p16(arg_p16_ptr, arg_p16x8x4, 0); + vst4q_lane_p16(arg_p16_ptr, arg_p16x8x4, 7); + vst4q_lane_p16(arg_p16_ptr, arg_p16x8x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_p16(arg_p16_ptr, arg_p16x8x4, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + +void test_vector_store_f64(float64_t* arg_f64_ptr, float64x2_t arg_f64x2, float64x1x3_t arg_f64x1x3, + float64x2x4_t arg_f64x2x4, float64x1x4_t arg_f64x1x4, float64x1x2_t arg_f64x1x2, + float64x1_t arg_f64x1, float64x2x2_t arg_f64x2x2, float64x2x3_t arg_f64x2x3) { + vst1_lane_f64(arg_f64_ptr, arg_f64x1, 0); + vst1_lane_f64(arg_f64_ptr, arg_f64x1, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1_lane_f64(arg_f64_ptr, arg_f64x1, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst1q_lane_f64(arg_f64_ptr, arg_f64x2, 0); + vst1q_lane_f64(arg_f64_ptr, arg_f64x2, 1); + vst1q_lane_f64(arg_f64_ptr, arg_f64x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst1q_lane_f64(arg_f64_ptr, arg_f64x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2_lane_f64(arg_f64_ptr, arg_f64x1x2, 0); + vst2_lane_f64(arg_f64_ptr, arg_f64x1x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2_lane_f64(arg_f64_ptr, arg_f64x1x2, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst2q_lane_f64(arg_f64_ptr, arg_f64x2x2, 0); + vst2q_lane_f64(arg_f64_ptr, arg_f64x2x2, 1); + vst2q_lane_f64(arg_f64_ptr, arg_f64x2x2, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst2q_lane_f64(arg_f64_ptr, arg_f64x2x2, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3_lane_f64(arg_f64_ptr, arg_f64x1x3, 0); + vst3_lane_f64(arg_f64_ptr, arg_f64x1x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3_lane_f64(arg_f64_ptr, arg_f64x1x3, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst3q_lane_f64(arg_f64_ptr, arg_f64x2x3, 0); + vst3q_lane_f64(arg_f64_ptr, arg_f64x2x3, 1); + vst3q_lane_f64(arg_f64_ptr, arg_f64x2x3, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst3q_lane_f64(arg_f64_ptr, arg_f64x2x3, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4_lane_f64(arg_f64_ptr, arg_f64x1x4, 0); + vst4_lane_f64(arg_f64_ptr, arg_f64x1x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4_lane_f64(arg_f64_ptr, arg_f64x1x4, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + + vst4q_lane_f64(arg_f64_ptr, arg_f64x2x4, 0); + vst4q_lane_f64(arg_f64_ptr, arg_f64x2x4, 1); + vst4q_lane_f64(arg_f64_ptr, arg_f64x2x4, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vst4q_lane_f64(arg_f64_ptr, arg_f64x2x4, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} + +} + diff --git a/clang/test/Sema/aarch64-neon-ranges.c b/clang/test/Sema/aarch64-neon-ranges.c deleted file mode 100644 index 2e60a12c26380..0000000000000 --- a/clang/test/Sema/aarch64-neon-ranges.c +++ /dev/null @@ -1,220 +0,0 @@ -// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s -// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s - -// REQUIRES: aarch64-registered-target || arm-registered-target - -#include - -void test_vext_8bit(int8x8_t small, int8x16_t big) { - vext_s8(small, small, 7); - vext_u8(small, small, 7); - vext_p8(small, small, 7); - vextq_s8(big, big, 15); - vextq_u8(big, big, 15); - vextq_p8(big, big, 15); - - vext_s8(small, small, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vext_u8(small, small, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vext_p8(small, small, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vextq_s8(big, big, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vextq_u8(big, big, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vextq_p8(big, big, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - -void test_mul_lane_f64(float64x1_t small, float64x2_t big, float64x2_t rhs) { - vmul_lane_f64(small, small, 0); - vmul_laneq_f64(small, big, 1); - vmulq_lane_f64(big, small, 0); - vmulq_laneq_f64(big, big, 1); - vfma_lane_f64(small, small, small, 0); - vfma_laneq_f64(small, small, big, 1); - vfmaq_lane_f64(big, big, small, 0); - vfmaq_laneq_f64(big, big, big, 1); - - vmul_lane_f64(small, small, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vmul_laneq_f64(small, big, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vfma_lane_f64(small, small, small, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vfma_laneq_f64(small, small, big, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vfmaq_laneq_f64(big, big, big, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - -void test_ld1st1(int8x8_t small, int8x16_t big, void *addr) { - vld1_lane_s8(addr, small, 7); - vld1_lane_s16(addr, small, 3); - vld1_lane_s32(addr, small, 1); - vld1_lane_s64(addr, small, 0); - - vld1q_lane_s8(addr, big, 15); - vld1q_lane_s16(addr, big, 7); - vld1q_lane_s32(addr, big, 3); - vld1q_lane_s64(addr, big, 1); - - vld1_lane_s8(addr, small, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld1_lane_s16(addr, small, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld1_lane_s32(addr, small, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld1_lane_s64(addr, small, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vld1q_lane_s8(addr, big, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld1q_lane_s16(addr, big, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld1q_lane_s32(addr, big, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld1q_lane_s64(addr, big, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst1_lane_s8(addr, small, 7); - vst1_lane_s16(addr, small, 3); - vst1_lane_s32(addr, small, 1); - vst1_lane_s64(addr, small, 0); - - vst1q_lane_s8(addr, big, 15); - vst1q_lane_s16(addr, big, 7); - vst1q_lane_s32(addr, big, 3); - vst1q_lane_s64(addr, big, 1); - - vst1_lane_s8(addr, small, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst1_lane_s16(addr, small, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst1_lane_s32(addr, small, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst1_lane_s64(addr, small, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst1q_lane_s8(addr, big, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst1q_lane_s16(addr, big, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst1q_lane_s32(addr, big, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst1q_lane_s64(addr, big, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - -void test_ld2st2(int8x8x2_t small8, int8x16x2_t big8, - int16x4x2_t small16, int16x8x2_t big16, - int32x2x2_t small32, int32x4x2_t big32, - int64x1x2_t small64, int64x2x2_t big64, - void *addr) { - vld2_lane_s8(addr, small8, 7); - vld2_lane_s16(addr, small16, 3); - vld2_lane_s32(addr, small32, 1); - vld2_lane_s64(addr, small64, 0); - - vld2q_lane_s8(addr, big8, 15); - vld2q_lane_s16(addr, big16, 7); - vld2q_lane_s32(addr, big32, 3); - vld2q_lane_s64(addr, big64, 1); - - vld2_lane_s8(addr, small8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld2_lane_s16(addr, small16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld2_lane_s32(addr, small32, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld2_lane_s64(addr, small64, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vld2q_lane_s8(addr, big8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld2q_lane_s16(addr, big16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld2q_lane_s32(addr, big32, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld2q_lane_s64(addr, big64, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst2_lane_s8(addr, small8, 7); - vst2_lane_s16(addr, small16, 3); - vst2_lane_s32(addr, small32, 1); - vst2_lane_s64(addr, small64, 0); - - vst2q_lane_s8(addr, big8, 15); - vst2q_lane_s16(addr, big16, 7); - vst2q_lane_s32(addr, big32, 3); - vst2q_lane_s64(addr, big64, 1); - - vst2_lane_s8(addr, small8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst2_lane_s16(addr, small16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst2_lane_s32(addr, small32, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst2_lane_s64(addr, small64, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst2q_lane_s8(addr, big8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst2q_lane_s16(addr, big16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst2q_lane_s32(addr, big32, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst2q_lane_s64(addr, big64, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - -void test_ld3st3(int8x8x3_t small8, int8x16x3_t big8, - int16x4x3_t small16, int16x8x3_t big16, - int32x2x3_t small32, int32x4x3_t big32, - int64x1x3_t small64, int64x2x3_t big64, - void *addr) { - vld3_lane_s8(addr, small8, 7); - vld3_lane_s16(addr, small16, 3); - vld3_lane_s32(addr, small32, 1); - vld3_lane_s64(addr, small64, 0); - - vld3q_lane_s8(addr, big8, 15); - vld3q_lane_s16(addr, big16, 7); - vld3q_lane_s32(addr, big32, 3); - vld3q_lane_s64(addr, big64, 1); - - vld3_lane_s8(addr, small8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld3_lane_s16(addr, small16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld3_lane_s32(addr, small32, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld3_lane_s64(addr, small64, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vld3q_lane_s8(addr, big8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld3q_lane_s16(addr, big16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld3q_lane_s32(addr, big32, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld3q_lane_s64(addr, big64, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst3_lane_s8(addr, small8, 7); - vst3_lane_s16(addr, small16, 3); - vst3_lane_s32(addr, small32, 1); - vst3_lane_s64(addr, small64, 0); - - vst3q_lane_s8(addr, big8, 15); - vst3q_lane_s16(addr, big16, 7); - vst3q_lane_s32(addr, big32, 3); - vst3q_lane_s64(addr, big64, 1); - - vst3_lane_s8(addr, small8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst3_lane_s16(addr, small16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst3_lane_s32(addr, small32, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst3_lane_s64(addr, small64, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst3q_lane_s8(addr, big8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst3q_lane_s16(addr, big16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst3q_lane_s32(addr, big32, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst3q_lane_s64(addr, big64, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - -void test_ld4st4(int8x8x4_t small8, int8x16x4_t big8, - int16x4x4_t small16, int16x8x4_t big16, - int32x2x4_t small32, int32x4x4_t big32, - int64x1x4_t small64, int64x2x4_t big64, - void *addr) { - vld4_lane_s8(addr, small8, 7); - vld4_lane_s16(addr, small16, 3); - vld4_lane_s32(addr, small32, 1); - vld4_lane_s64(addr, small64, 0); - - vld4q_lane_s8(addr, big8, 15); - vld4q_lane_s16(addr, big16, 7); - vld4q_lane_s32(addr, big32, 3); - vld4q_lane_s64(addr, big64, 1); - - vld4_lane_s8(addr, small8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld4_lane_s16(addr, small16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld4_lane_s32(addr, small32, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld4_lane_s64(addr, small64, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vld4q_lane_s8(addr, big8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld4q_lane_s16(addr, big16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld4q_lane_s32(addr, big32, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vld4q_lane_s64(addr, big64, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst4_lane_s8(addr, small8, 7); - vst4_lane_s16(addr, small16, 3); - vst4_lane_s32(addr, small32, 1); - vst4_lane_s64(addr, small64, 0); - - vst4q_lane_s8(addr, big8, 15); - vst4q_lane_s16(addr, big16, 7); - vst4q_lane_s32(addr, big32, 3); - vst4q_lane_s64(addr, big64, 1); - - vst4_lane_s8(addr, small8, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst4_lane_s16(addr, small16, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst4_lane_s32(addr, small32, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst4_lane_s64(addr, small64, 1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - - vst4q_lane_s8(addr, big8, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst4q_lane_s16(addr, big16, 8); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst4q_lane_s32(addr, big32, 4); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vst4q_lane_s64(addr, big64, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} -} - diff --git a/clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_imm_lane.cpp b/clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_imm_lane.cpp index bca063385420a..e405077b3de93 100644 --- a/clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_imm_lane.cpp +++ b/clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_imm_lane.cpp @@ -78,6 +78,14 @@ void test_range_0_7() SVE_ACLE_FUNC(svqrdmlsh_lane,_s16,,)(svundef_s16(), svundef_s16(), svundef_s16(), -1); // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 7]}} SVE_ACLE_FUNC(svqrdmulh_lane,_s16,,)(svundef_s16(), svundef_s16(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 7]}} + SVE_ACLE_FUNC(svluti2_lane,_s16,,)(svundef_s16(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 7]}} + SVE_ACLE_FUNC(svluti2_lane,_u16,,)(svundef_u16(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 7]}} + SVE_ACLE_FUNC(svluti2_lane,_f16,,)(svundef_f16(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 7]}} + SVE_ACLE_FUNC(svluti2_lane,_bf16,,)(svundef_bf16(), svundef_u8(), -1); } void test_range_0_3() @@ -146,6 +154,26 @@ void test_range_0_3() SVE_ACLE_FUNC(svqdmullb_lane,_s64,,)(svundef_s32(), svundef_s32(), 4); // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} SVE_ACLE_FUNC(svqdmullt_lane,_s64,,)(svundef_s32(), svundef_s32(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti2_lane,_s8,,)(svundef_s8(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti2_lane,_u8,,)(svundef_u8(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_s16,,)(svundef_s16(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_u16,,)(svundef_u16(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_f16,,)(svundef_f16(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_bf16,,)(svundef_bf16(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_s16,_x2,)(svcreate2_s16(svundef_s16(),svundef_s16()), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_u16,_x2,)(svcreate2_u16(svundef_u16(),svundef_u16()), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_f16,_x2,)(svcreate2_f16(svundef_f16(),svundef_f16()), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} + SVE_ACLE_FUNC(svluti4_lane,_bf16,_x2,)(svcreate2_bf16(svundef_bf16(),svundef_bf16()), svundef_u8(), -1); } void test_range_0_1() @@ -180,4 +208,8 @@ void test_range_0_1() SVE_ACLE_FUNC(svqrdmlsh_lane,_s64,,)(svundef_s64(), svundef_s64(), svundef_s64(), 2); // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} SVE_ACLE_FUNC(svqrdmulh_lane,_s64,,)(svundef_s64(), svundef_s64(), 2); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} + SVE_ACLE_FUNC(svluti4_lane,_s8,,)(svundef_s8(), svundef_u8(), -1); + // expected-error-re@+1 {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} + SVE_ACLE_FUNC(svluti4_lane,_u8,,)(svundef_u8(), svundef_u8(), -1); } diff --git a/clang/test/Sema/attr-btf_type_tag.cpp b/clang/test/Sema/attr-btf_type_tag.cpp new file mode 100644 index 0000000000000..cef78fff79b96 --- /dev/null +++ b/clang/test/Sema/attr-btf_type_tag.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify=c -x c %s + +// c-no-diagnostics + +// Ensure that we diagnose the attribute as ignored in C++ but not in C. +#ifdef __cplusplus +static_assert(__builtin_is_implicit_lifetime(int __attribute__((btf_type_tag("user"))) *)); // expected-warning {{'btf_type_tag' attribute ignored}} +#endif +int __attribute__((btf_type_tag("user"))) *ptr; // expected-warning {{'btf_type_tag' attribute ignored}} + diff --git a/clang/test/Sema/builtin-unary-fp.c b/clang/test/Sema/builtin-unary-fp.c index 3f4f65eeb73a1..fb8e341156a59 100644 --- a/clang/test/Sema/builtin-unary-fp.c +++ b/clang/test/Sema/builtin-unary-fp.c @@ -14,4 +14,8 @@ void a(void) { check(__builtin_fpclassify(0, 1, 2, 3, 4.5, 5.0)); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 4.5 to 4}} check(__builtin_fpclassify(0, 0, 0, 0, 1)); // expected-error{{too few arguments}} check(__builtin_fpclassify(0, 0, 0, 0, 0, 1, 0)); // expected-error{{too many arguments}} + + check(__builtin_fpclassify(0,0,0,0,0, (invalid))); // expected-error{{use of undeclared identifier 'invalid'}} + check(__builtin_fpclassify(0,0,0,0,0, (inf))); // expected-error{{use of undeclared identifier 'inf'}} + // expected-error@-1{{reference to overloaded function could not be resolved}} } diff --git a/clang/test/Sema/pre-c2x-compat.c b/clang/test/Sema/pre-c2x-compat.c index fad472f1f72d5..15bb9b58349fa 100644 --- a/clang/test/Sema/pre-c2x-compat.c +++ b/clang/test/Sema/pre-c2x-compat.c @@ -1,3 +1,4 @@ // 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 C23}} +unsigned char u8_char = u8'x'; // expected-warning {{unicode literals are incompatible with C standards before C23}} diff --git a/clang/test/Sema/static-assert.c b/clang/test/Sema/static-assert.c index 4e9e6b7ee558b..d603bc19bb824 100644 --- a/clang/test/Sema/static-assert.c +++ b/clang/test/Sema/static-assert.c @@ -25,8 +25,12 @@ void foo(void) { #endif } -_Static_assert(1, invalid); // expected-error {{expected string literal for diagnostic message in static_assert}} \ - // ext-warning {{'_Static_assert' is a C11 extension}} +_Static_assert(1, invalid); // ext-warning {{'_Static_assert' is a C11 extension}} +#ifndef __cplusplus +// expected-error@-2 {{expected string literal for diagnostic message in static_assert}} +#endif +// cxx-error@-4 {{use of undeclared identifier 'invalid'}} +// cxx-warning@-5 {{'static_assert' with a user-generated message is a C++26 extension}} struct A { int a; diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index cd1904db32710..59357d0730a7d 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -275,6 +275,34 @@ int &danglingRawPtrFromLocal3() { return *o; // expected-warning {{reference to stack memory associated with local variable 'o' returned}} } +// GH100384 +std::string_view containerWithAnnotatedElements() { + std::string_view c1 = std::vector().at(0); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + c1 = std::vector().at(0); // expected-warning {{object backing the pointer}} + + // no warning on constructing from gsl-pointer + std::string_view c2 = std::vector().at(0); + + std::vector local; + return local.at(0); // expected-warning {{address of stack memory associated with local variable}} +} + +std::string_view localUniquePtr(int i) { + std::unique_ptr c1; + if (i) + return *c1; // expected-warning {{address of stack memory associated with local variable}} + std::unique_ptr c2; + return *c2; // expect no-warning. +} + +std::string_view localOptional(int i) { + std::optional o; + if (i) + return o.value(); // expected-warning {{address of stack memory associated with local variable}} + std::optional abc; + return abc.value(); // expect no warning +} + const char *danglingRawPtrFromTemp() { return std::basic_string().c_str(); // expected-warning {{returning address of local temporary object}} } @@ -498,4 +526,30 @@ std::string_view test2(int i, std::optional a) { return std::move(*a); return std::move(a.value()); } + +struct Foo; +struct FooView { + FooView(const Foo& foo [[clang::lifetimebound]]); +}; +FooView test3(int i, std::optional a) { + if (i) + return *a; // expected-warning {{address of stack memory}} + return a.value(); // expected-warning {{address of stack memory}} +} +} // namespace GH93386 + +namespace GH100549 { +struct UrlAnalyzed { + UrlAnalyzed(std::string_view url [[clang::lifetimebound]]); +}; +std::string StrCat(std::string_view, std::string_view); +void test1() { + UrlAnalyzed url(StrCat("abc", "bcd")); // expected-warning {{object backing the pointer will be destroyed}} +} + +std::string_view ReturnStringView(std::string_view abc [[clang::lifetimebound]]); + +void test() { + std::string_view svjkk1 = ReturnStringView(StrCat("bar", "x")); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} } +} // namespace GH100549 diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp index 6566ed6270cd1..0fb997a567108 100644 --- a/clang/test/SemaCXX/attr-lifetimebound.cpp +++ b/clang/test/SemaCXX/attr-lifetimebound.cpp @@ -287,3 +287,23 @@ std::span test2() { return abc; // expected-warning {{address of stack memory associated with local variable}} } } // namespace ctor_cases + +namespace GH106372 { +class [[gsl::Owner]] Foo {}; +class [[gsl::Pointer]] FooView {}; + +class NonAnnotatedFoo {}; +class NonAnnotatedFooView {}; + +template +struct StatusOr { + template + StatusOr& operator=(U&& v [[clang::lifetimebound]]); +}; + +void test(StatusOr foo1, StatusOr foo2) { + foo1 = Foo(); // expected-warning {{object backing the pointer foo1 will be destroyed at the end}} + // No warning on non-gsl annotated types. + foo2 = NonAnnotatedFoo(); +} +} // namespace GH106372 diff --git a/clang/test/SemaCXX/builtin-is-within-lifetime.cpp b/clang/test/SemaCXX/builtin-is-within-lifetime.cpp new file mode 100644 index 0000000000000..62ff2681952ce --- /dev/null +++ b/clang/test/SemaCXX/builtin-is-within-lifetime.cpp @@ -0,0 +1,431 @@ +// RUN: %clang_cc1 -std=c++20 -Wno-unused %s -verify=expected,cxx20 -Wno-vla-cxx-extension +// RUN: %clang_cc1 -std=c++23 -Wno-unused %s -verify=expected,sincecxx23 -Wno-vla-cxx-extension +// RUN: %clang_cc1 -std=c++26 -Wno-unused %s -verify=expected,sincecxx23 -Wno-vla-cxx-extension +// RUN: %clang_cc1 -std=c++26 -DINLINE_NAMESPACE -Wno-unused %s -verify=expected,sincecxx23 -Wno-vla-cxx-extension + +inline constexpr void* operator new(__SIZE_TYPE__, void* p) noexcept { return p; } +namespace std { +template +constexpr T* construct_at(T* p, Args&&... args) { return ::new((void*)p) T(static_cast(args)...); } +template +constexpr void destroy_at(T* p) { p->~T(); } +template +struct allocator { + constexpr T* allocate(__SIZE_TYPE__ n) { return static_cast(::operator new(n * sizeof(T))); } + constexpr void deallocate(T* p, __SIZE_TYPE__) { ::operator delete(p); } +}; +using nullptr_t = decltype(nullptr); +template +struct integral_constant { static constexpr T value = v; }; +template +using bool_constant = integral_constant; +using true_type = bool_constant; +using false_type = bool_constant; +template +inline constexpr bool is_function_v = __is_function(T); +#ifdef INLINE_NAMESPACE +inline namespace __1 { +#endif +template requires (!is_function_v) // #std-constraint +consteval bool is_within_lifetime(const T* p) noexcept { // #std-definition + return __builtin_is_within_lifetime(p); +} +#ifdef INLINE_NAMESPACE +} +#endif +} + +consteval bool test_union(int& i, char& c) { + if (__builtin_is_within_lifetime(&i) || __builtin_is_within_lifetime(&c)) + return false; + std::construct_at(&c, 1); + if (__builtin_is_within_lifetime(&i) || !__builtin_is_within_lifetime(&c)) + return false; + std::construct_at(&i, 3); + if (!__builtin_is_within_lifetime(&i) || __builtin_is_within_lifetime(&c)) + return false; + return true; +} + +static_assert([]{ + union { int i; char c; } u; + return test_union(u.i, u.c); +}()); +static_assert([]{ + union { int i; char c; }; + return test_union(i, c); +}()); +static_assert([]{ + struct { union { int i; char c; }; } u; + return test_union(u.i, u.c); +}()); +static_assert([]{ + struct { union { int i; char c; } u; } r; + return test_union(r.u.i, r.u.c); +}()); + +consteval bool test_nested() { + union { + union { int i; char c; } u; + long l; + }; + if (__builtin_is_within_lifetime(&l) || __builtin_is_within_lifetime(&u) || __builtin_is_within_lifetime(&u.i) || __builtin_is_within_lifetime(&u.c)) + return false; + std::construct_at(&l); + if (!__builtin_is_within_lifetime(&l) || __builtin_is_within_lifetime(&u) || __builtin_is_within_lifetime(&u.i) || __builtin_is_within_lifetime(&u.c)) + return false; + std::construct_at(&u); + std::construct_at(&u.i); + if (__builtin_is_within_lifetime(&l) || !__builtin_is_within_lifetime(&u) || !__builtin_is_within_lifetime(&u.i) || __builtin_is_within_lifetime(&u.c)) + return false; + std::construct_at(&u.c); + if (__builtin_is_within_lifetime(&l) || !__builtin_is_within_lifetime(&u) || __builtin_is_within_lifetime(&u.i) || !__builtin_is_within_lifetime(&u.c)) + return false; + return true; +} +static_assert(test_nested()); + +consteval bool test_dynamic(bool read_after_deallocate) { + std::allocator a; + int* p = a.allocate(1); + // a.allocate starts the lifetime of an array, + // the complete object of *p has started its lifetime + if (__builtin_is_within_lifetime(p)) + return false; + std::construct_at(p); + if (!__builtin_is_within_lifetime(p)) + return false; + std::destroy_at(p); + if (__builtin_is_within_lifetime(p)) + return false; + a.deallocate(p, 1); + if (read_after_deallocate) + __builtin_is_within_lifetime(p); // expected-note {{read of heap allocated object that has been deleted}} + return true; +} +static_assert(test_dynamic(false)); +static_assert(test_dynamic(true)); +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{in call to 'test_dynamic(true)'}} + +consteval bool test_automatic(int read_dangling) { + int* p; + { + int x = 0; + p = &x; + if (!__builtin_is_within_lifetime(p)) + return false; + } + { + int x = 0; + if (read_dangling == 1) + __builtin_is_within_lifetime(p); // expected-note {{read of object outside its lifetime is not allowed in a constant expression}} + } + if (read_dangling == 2) + __builtin_is_within_lifetime(p); // expected-note {{read of object outside its lifetime is not allowed in a constant expression}} + { + int x[4]; + p = &x[2]; + if (!__builtin_is_within_lifetime(p)) + return false; + } + if (read_dangling == 3) + __builtin_is_within_lifetime(p); // expected-note {{read of object outside its lifetime is not allowed in a constant expression}} + std::nullptr_t* q; + { + std::nullptr_t np = nullptr; + q = &np; + if (!__builtin_is_within_lifetime(q)) + return false; + } + if (read_dangling == 4) + __builtin_is_within_lifetime(q); // expected-note {{read of object outside its lifetime is not allowed in a constant expression}} + return true; +} +static_assert(test_automatic(0)); +static_assert(test_automatic(1)); +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{in call to 'test_automatic(1)'}} +static_assert(test_automatic(2)); +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{in call to 'test_automatic(2)'}} +static_assert(test_automatic(3)); +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{in call to 'test_automatic(3)'}} +static_assert(test_automatic(4)); +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{in call to 'test_automatic(4)'}} + + +consteval bool test_indeterminate() { + int x; + if (!__builtin_is_within_lifetime(&x)) + return false; + bool b = true; + unsigned char c = __builtin_bit_cast(unsigned char, b); + if (!__builtin_is_within_lifetime(&c)) + return false; + struct {} padding; + unsigned char y = __builtin_bit_cast(unsigned char, padding); + if (!__builtin_is_within_lifetime(&y)) + return false; + return true; +} +static_assert(test_indeterminate()); + +consteval bool test_volatile() { + int x; + if (!__builtin_is_within_lifetime(static_cast(&x)) || !__builtin_is_within_lifetime(static_cast(&x))) + return false; + volatile int y; + if (!__builtin_is_within_lifetime(const_cast(&y)) || !__builtin_is_within_lifetime(const_cast(static_cast(&y)))) + return false; + return true; +} +static_assert(test_volatile()); + +constexpr bool self = __builtin_is_within_lifetime(&self); +// expected-error@-1 {{constexpr variable 'self' must be initialized by a constant expression}} +// expected-note@-2 {{'__builtin_is_within_lifetime' cannot be called with a pointer to an object whose lifetime has not yet begun}} +// expected-error@-3 {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} +// expected-note@-4 {{initializer of 'self' is not a constant expression}} +// expected-note@-5 {{declared here}} +constexpr int external{}; +static_assert(__builtin_is_within_lifetime(&external)); +void not_constexpr() { + __builtin_is_within_lifetime(&external); +} +void invalid_args() { + __builtin_is_within_lifetime(static_cast(nullptr)); + // expected-error@-1 {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} + // expected-note@-2 {{'__builtin_is_within_lifetime' cannot be called with a null pointer}} + + // FIXME: avoid function to pointer conversion on all consteval builtins + __builtin_is_within_lifetime(0); + // expected-error@-1 {{non-pointer argument to '__builtin_is_within_lifetime' is not allowed}} + // expected-error@-2 {{cannot take address of consteval function '__builtin_is_within_lifetime' outside of an immediate invocation}} + __builtin_is_within_lifetime(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} + // expected-error@-2 {{cannot take address of consteval function '__builtin_is_within_lifetime' outside of an immediate invocation}} + __builtin_is_within_lifetime(1, 2); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} + // expected-error@-2 {{cannot take address of consteval function '__builtin_is_within_lifetime' outside of an immediate invocation}} + __builtin_is_within_lifetime(&external, &external); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} + // expected-error@-2 {{cannot take address of consteval function '__builtin_is_within_lifetime' outside of an immediate invocation}} +} + +constexpr struct { + union { + int i; + char c; + }; + mutable int mi; // #x-mi +} x1{ .c = 2 }; +static_assert(!__builtin_is_within_lifetime(&x1.i)); +static_assert(__builtin_is_within_lifetime(&x1.c)); +static_assert(__builtin_is_within_lifetime(&x1.mi)); +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{read of mutable member 'mi' is not allowed in a constant expression}} +// expected-note@#x-mi {{declared here}} + +constexpr struct NSDMI { // #NSDMI + bool a = true; + bool b = __builtin_is_within_lifetime(&a); // #NSDMI-read +} x2; +// expected-error@-1 {{constexpr variable 'x2' must be initialized by a constant expression}} +// expected-note@#NSDMI-read {{'__builtin_is_within_lifetime' cannot be called with a pointer to an object whose lifetime has not yet begun}} +// expected-note@-3 {{in call to 'NSDMI()'}} +// expected-error@-4 {{call to immediate function 'NSDMI::NSDMI' is not a constant expression}} +// expected-note@#NSDMI {{'NSDMI' is an immediate constructor because the default initializer of 'b' contains a call to a consteval function '__builtin_is_within_lifetime' and that call is not a constant expression}} +// expected-note@#NSDMI-read {{'__builtin_is_within_lifetime' cannot be called with a pointer to an object whose lifetime has not yet begun}} +// expected-note@-7 {{in call to 'NSDMI()'}} + +struct X3 { + consteval X3() { + __builtin_is_within_lifetime(this); // #X3-read + } +} x3; +// expected-error@-1 {{call to consteval function 'X3::X3' is not a constant expression}} +// expected-note@#X3-read {{'__builtin_is_within_lifetime' cannot be called with a pointer to an object whose lifetime has not yet begun}} +// expected-note@-3 {{in call to 'X3()'}} + +constexpr int i = 2; +static_assert(__builtin_is_within_lifetime(const_cast(&i))); +static_assert(__builtin_is_within_lifetime(const_cast(&i))); +static_assert(__builtin_is_within_lifetime(static_cast(&i))); + +constexpr int arr[2]{}; +static_assert(__builtin_is_within_lifetime(arr)); +static_assert(__builtin_is_within_lifetime(arr + 0)); +static_assert(__builtin_is_within_lifetime(arr + 1)); +void f() { + __builtin_is_within_lifetime(&i + 1); + // expected-error@-1 {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} + // expected-note@-2 {{'__builtin_is_within_lifetime' cannot be called with a one-past-the-end pointer}} + __builtin_is_within_lifetime(arr + 2); + // expected-error@-1 {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} + // expected-note@-2 {{'__builtin_is_within_lifetime' cannot be called with a one-past-the-end pointer}} +} + +template +consteval void disallow_function_types(bool b, const T* p) { + if (b) { + __builtin_is_within_lifetime(p); // expected-error {{function pointer argument to '__builtin_is_within_lifetime' is not allowed}} + } +} +void g() { + disallow_function_types(false, &f); + // expected-note@-1 {{in instantiation of function template specialization 'disallow_function_types' requested here}} +} + +struct OptBool { + union { bool b; char c; }; + + // note: this assumes common implementation properties for bool and char: + // * sizeof(bool) == sizeof(char), and + // * the value representations for true and false are distinct + // from the value representation for 2 + constexpr OptBool() : c(2) { } + constexpr OptBool(bool b) : b(b) { } + + constexpr auto has_value() const -> bool { + if consteval { // cxx20-warning {{consteval if}} + return __builtin_is_within_lifetime(&b); // during constant evaluation, cannot read from c + } else { + return c != 2; // during runtime, must read from c + } + } + + constexpr auto operator*() const -> const bool& { + return b; + } +}; + +constexpr OptBool disengaged; +constexpr OptBool engaged(true); +static_assert(!disengaged.has_value()); +static_assert(engaged.has_value()); +static_assert(*engaged); + +namespace vlas { + +consteval bool f(int n) { + int vla[n]; // cxx20-error {{variable of non-literal type}} + return __builtin_is_within_lifetime(static_cast(&vla)); +} +static_assert(f(1)); + +consteval bool fail(int n) { + int vla[n]; // cxx20-error {{variable of non-literal type}} + return __builtin_is_within_lifetime(&vla); // expected-error {{variable length arrays are not supported in '__builtin_is_within_lifetime'}} +} +static_assert(fail(1)); // sincecxx23-error {{static assertion expression is not an integral constant expression}} + +consteval bool variably_modified(int n) { + int(* p)[n]; + return __builtin_is_within_lifetime(&p); +} +static_assert(variably_modified(1)); + +} // namespace vlas + +consteval bool partial_arrays() { + int arr[2]; + if (!__builtin_is_within_lifetime(&arr) || !__builtin_is_within_lifetime(&arr[0]) || !__builtin_is_within_lifetime(&arr[1])) + return false; + std::destroy_at(&arr[0]); + if (!__builtin_is_within_lifetime(&arr) || __builtin_is_within_lifetime(&arr[0]) || !__builtin_is_within_lifetime(&arr[1])) + return false; + std::construct_at(&arr[0]); + if (!__builtin_is_within_lifetime(&arr) || !__builtin_is_within_lifetime(&arr[0]) || !__builtin_is_within_lifetime(&arr[1])) + return false; + return true; +} +static_assert(partial_arrays()); + +consteval bool partial_members() { + struct S { + int x; + int y; + } s; + if (!__builtin_is_within_lifetime(&s) || !__builtin_is_within_lifetime(&s.x) || !__builtin_is_within_lifetime(&s.y)) + return false; + std::destroy_at(&s.x); + if (!__builtin_is_within_lifetime(&s) || __builtin_is_within_lifetime(&s.x) || !__builtin_is_within_lifetime(&s.y)) + return false; + std::construct_at(&s.x); + if (!__builtin_is_within_lifetime(&s) || !__builtin_is_within_lifetime(&s.x) || !__builtin_is_within_lifetime(&s.y)) + return false; + return true; +} + +struct NonTrivial { + constexpr NonTrivial() {} + constexpr NonTrivial(const NonTrivial&) {} + constexpr ~NonTrivial() {} +}; + +template +constexpr T& unmove(T&& temp) { return static_cast(temp); } + +consteval bool test_temporaries() { + static_assert(__builtin_is_within_lifetime(&unmove(0))); + static_assert(__builtin_is_within_lifetime(&unmove(NonTrivial{}))); + if (!__builtin_is_within_lifetime(&unmove(0))) + return false; + if (!__builtin_is_within_lifetime(&unmove(NonTrivial{}))) + return false; + return true; +} +static_assert(test_temporaries()); + +constexpr const int& temp = 0; +static_assert(__builtin_is_within_lifetime(&temp)); + +template +constexpr T* test_dangling() { + T i; // expected-note 2 {{declared here}} + return &i; // expected-warning 2 {{address of stack memory associated with local variable 'i' returned}} +} +static_assert(__builtin_is_within_lifetime(test_dangling())); // expected-note {{in instantiation of function template specialization}} +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{read of variable whose lifetime has ended}} +static_assert(__builtin_is_within_lifetime(test_dangling())); // expected-note {{in instantiation of function template specialization}} +// expected-error@-1 {{static assertion expression is not an integral constant expression}} +// expected-note@-2 {{read of variable whose lifetime has ended}} + +template +concept CanCallAndPassToIsWithinLifetime = std::bool_constant<__builtin_is_within_lifetime(F())>::value; +static_assert(CanCallAndPassToIsWithinLifetime<[]{ return &i; }>); +static_assert(!CanCallAndPassToIsWithinLifetime<[]{ return static_cast(nullptr); }>); +static_assert(!CanCallAndPassToIsWithinLifetime<[]{ return static_cast(&f); }>); +template constexpr std::true_type sfinae() requires CanCallAndPassToIsWithinLifetime { return {}; } +template std::false_type sfinae() { return {}; } +static_assert(decltype(sfinae<[]{ return &i; }>())::value); +static_assert(!decltype(sfinae<[]{ return static_cast(nullptr); }>())::value); +std::true_type(* not_immediate)() = &sfinae<[]{ return &i; }>; + +void test_std_error_message() { + std::is_within_lifetime(static_cast(nullptr)); + // expected-error@-1 {{call to consteval function 'std::is_within_lifetime' is not a constant expression}} + // expected-note@-2 {{'std::is_within_lifetime' cannot be called with a null pointer}} + // expected-note@-3 {{in call to 'is_within_lifetime(nullptr)'}} + std::is_within_lifetime(&test_std_error_message); + // expected-error@-1 {{no matching function for call to 'is_within_lifetime'}} + // expected-note@#std-definition {{candidate template ignored: constraints not satisfied [with T = void ()]}} + // expected-note@#std-constraint {{because '!is_function_v' evaluated to false}} + std::is_within_lifetime(arr + 2); + // expected-error@-1 {{call to consteval function 'std::is_within_lifetime' is not a constant expression}} + // expected-note@-2 {{'std::is_within_lifetime' cannot be called with a one-past-the-end pointer}} + // expected-note@-3 {{in call to 'is_within_lifetime(&arr[2])'}} +} +struct XStd { + consteval XStd() { + std::is_within_lifetime(this); // #XStd-read + } +} xstd; +// expected-error@-1 {{call to consteval function 'XStd::XStd' is not a constant expression}} +// expected-note@#XStd-read {{'std::is_within_lifetime' cannot be called with a pointer to an object whose lifetime has not yet begun}} +// expected-note@#XStd-read {{in call to 'is_within_lifetime(&)'}} +// expected-note@-4 {{in call to 'XStd()'}} diff --git a/clang/test/SemaCXX/consteval-builtin.cpp b/clang/test/SemaCXX/consteval-builtin.cpp new file mode 100644 index 0000000000000..3ba95b4dbd9b5 --- /dev/null +++ b/clang/test/SemaCXX/consteval-builtin.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -Wno-unused %s -verify=cxx20-cxx26 +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wno-unused %s -verify=cxx20,cxx20-cxx26 +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -Wno-unused %s -verify=precxx20,cxx11-cxx17 +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -Wno-unused %s -verify=precxx20,cxx11-cxx17 +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-unused %s -verify=precxx20,cxx11-cxx17 +// RUN: %clang_cc1 -std=c++03 -fsyntax-only -Wno-unused %s -verify=precxx20 +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -Wno-unused %s -verify=precxx20 +// RUN: %clang_cc1 -x c -std=c23 -fsyntax-only -Wno-unused %s -verify=c + +#if __has_builtin(__builtin_is_within_lifetime) +#error has the builtin +#else +#error does not have the builtin +#endif +// cxx20-cxx26-error@-4 {{has the builtin}} +// precxx20-error@-3 {{does not have the builtin}} +// c-error@-4 {{does not have the builtin}} + +#if __has_constexpr_builtin(__builtin_is_within_lifetime) +#error has the constexpr builtin +#else +#error does not have the constexpr builtin +#endif +// cxx20-cxx26-error@-4 {{has the constexpr builtin}} +// precxx20-error@-3 {{does not have the constexpr builtin}} +// c-error@-4 {{does not have the constexpr builtin}} + +#if __cplusplus < 201103L +#define static_assert __extension__ _Static_assert +#define CONSTEXPR11 +#else +#define CONSTEXPR11 constexpr +#endif + +static const int i1 = 0; +static_assert(__builtin_is_within_lifetime(&i1), ""); +// precxx20-error@-1 {{use of undeclared identifier '__builtin_is_within_lifetime'}} +// c-error@-2 {{use of undeclared identifier '__builtin_is_within_lifetime'}} + +#if !defined(__cplusplus) || __cplusplus >= 201102L +constexpr int i2 = 0; +static_assert(__builtin_is_within_lifetime(&i2), ""); +// cxx11-cxx17-error@-1 {{use of undeclared identifier '__builtin_is_within_lifetime'}} +// c-error@-2 {{use of undeclared identifier '__builtin_is_within_lifetime'}} +#endif + +#ifdef __cplusplus +template +CONSTEXPR11 bool f1(T i) { // #f1 + return __builtin_is_within_lifetime(&i); // #f1-consteval-call +} + +bool(&fp1)(int) = f1; +// cxx20-cxx26-error@-1 {{cannot take address of immediate function 'f1' outside of an immediate invocation}} +// cxx20-cxx26-note@#f1 {{declared here}} +// cxx20-cxx26-note@#f1-consteval-call {{'f1' is an immediate function because its body contains a call to a consteval function '__builtin_is_within_lifetime' and that call is not a constant expression}} +// precxx20-error@#f1-consteval-call {{use of undeclared identifier '__builtin_is_within_lifetime'}} +// precxx20-note@-5 {{in instantiation of function template specialization 'f1' requested here}} +#else +void f1(int i) { + __builtin_is_within_lifetime(&i); + // c-error@-1 {{use of undeclared identifier '__builtin_is_within_lifetime'}} +} +#endif + +#if __cplusplus >= 202002L +constexpr void f2() { + int i = 0; + if consteval { // cxx20-warning {{consteval if}} + __builtin_is_within_lifetime(&i); + } +} +void(&fp2)() = f2; + +constexpr void f3() { + __builtin_is_within_lifetime(&i1); +} +void(&fp3)() = f3; + +constexpr void f4() { + &__builtin_is_within_lifetime; + // cxx20-cxx26-error@-1 {{builtin functions must be directly called}} + // cxx20-cxx26-error@-2 {{cannot take address of consteval function '__builtin_is_within_lifetime' outside of an immediate invocation}} + __builtin_is_within_lifetime(); + // cxx20-cxx26-error@-1 {{too few arguments to function call, expected 1, have 0}} + // cxx20-cxx26-error@-2 {{cannot take address of consteval function '__builtin_is_within_lifetime' outside of an immediate invocation}} + int* not_constexpr; + __builtin_is_within_lifetime(not_constexpr); + // cxx20-cxx26-error@-1 {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} + // cxx20-cxx26-note@-2 {{read of non-constexpr variable 'not_constexpr' is not allowed in a constant expression}} + // cxx20-cxx26-note@-4 {{declared here}} +} +#endif diff --git a/clang/test/SemaCXX/cxx20-default-compare.cpp b/clang/test/SemaCXX/cxx20-default-compare.cpp index 7074ee885ac4a..3e4673c31e489 100644 --- a/clang/test/SemaCXX/cxx20-default-compare.cpp +++ b/clang/test/SemaCXX/cxx20-default-compare.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 %s -std=c++23 -verify -Wfloat-equal +#include "Inputs/std-compare.h" + struct Foo { float val; bool operator==(const Foo &) const; @@ -15,3 +17,51 @@ bool operator==(const Foo &, const Foo &) = default; // expected-warning {{comp // Declare the defaulted comparison function as a non-member function. Arguments are passed by value. bool operator==(Foo, Foo) = default; // expected-warning {{comparing floating point with == or != is unsafe}} expected-note {{in defaulted equality comparison operator for 'Foo' first required here}} + +namespace GH102588 { +struct A { + int i = 0; + constexpr operator int() const { return i; } + constexpr operator int&() { return ++i; } +}; + +struct B : A { + bool operator==(const B &) const = default; +}; + +constexpr bool f() { + B x; + return x == x; +} + +static_assert(f()); + +struct ConstOnly { + std::strong_ordering operator<=>(const ConstOnly&) const; + std::strong_ordering operator<=>(ConstOnly&) = delete; + friend bool operator==(const ConstOnly&, const ConstOnly&); + friend bool operator==(ConstOnly&, ConstOnly&) = delete; +}; + +struct MutOnly { + std::strong_ordering operator<=>(const MutOnly&) const = delete;; + std::strong_ordering operator<=>(MutOnly&); + friend bool operator==(const MutOnly&, const MutOnly&) = delete;; + friend bool operator==(MutOnly&, MutOnly&); +}; + +struct ConstCheck : ConstOnly { + friend std::strong_ordering operator<=>(const ConstCheck&, const ConstCheck&) = default; + std::strong_ordering operator<=>(ConstCheck const& __restrict) const __restrict = default; + friend bool operator==(const ConstCheck&, const ConstCheck&) = default; + bool operator==(this const ConstCheck&, const ConstCheck&) = default; +}; + +// FIXME: Non-reference explicit object parameter are rejected +struct MutCheck : MutOnly { + friend bool operator==(MutCheck, MutCheck) = default; + // std::strong_ordering operator<=>(this MutCheck, MutCheck) = default; + friend std::strong_ordering operator<=>(MutCheck, MutCheck) = default; + // bool operator==(this MutCheck, MutCheck) = default; +}; +} diff --git a/clang/test/SemaCXX/cxx23-assume.cpp b/clang/test/SemaCXX/cxx23-assume.cpp index 9138501d726dd..eeae59daea3f7 100644 --- a/clang/test/SemaCXX/cxx23-assume.cpp +++ b/clang/test/SemaCXX/cxx23-assume.cpp @@ -158,3 +158,12 @@ foo (int x, int y) return x + y; } } + +// Do not crash when assumptions are unreachable. +namespace gh106898 { +int foo () { + while(1); + int a = 0, b = 1; + __attribute__((assume (a < b))); +} +} diff --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp index fff524e77d3bf..00ba291fbd198 100644 --- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp +++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp @@ -97,3 +97,37 @@ void foo() { } #endif + +#if __cplusplus >= 202002L +namespace { +struct S {}; +constexpr S gs; +void f() { + constexpr int x{}; + const int y{}; + auto b = []{}; + using A = decltype([]{}); + + int z; // expected-note {{'z' declared here}} + auto c = []{ + // expected-error@-1 {{no matching function for call to object of type}} \ + // expected-error@-1 {{variable 'z' cannot be implicitly captured in a lambda with no capture-default specified}} \ + // expected-note@-1 {{lambda expression begins here}} \ + // expected-note@-1 4{{capture}} \ + // expected-note@-1 {{candidate template ignored: substitution failure: reference to local variable 'z' declared in enclosing function}} + return t; + }(); + + auto class_type_global = []{}; + + static constexpr S static_s; + auto class_type_static = []{}; + + constexpr S s; // expected-note {{'s' declared here}} + auto class_type = []{}; + // expected-error@-1 {{variable 's' cannot be implicitly captured in a lambda with no capture-default specified}} \ + // expected-note@-1 {{lambda expression begins here}} \ + // expected-note@-1 4{{capture}} +} +} +#endif diff --git a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp index 7d7e808746217..962dbb8137f28 100644 --- a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp +++ b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp @@ -258,4 +258,16 @@ void f() { vars<0>::x<0>(); } +} // namespace GH105900 + +namespace GH105903 { + +template struct temp { + template static auto x() -> opts... [s] {} // expected-note {{invalid index 0 for pack 'opts' of size 0}} +}; + +void f() { + temp<>::x<0>(); // expected-error {{no matching}} } + +} // namespace GH105903 diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index 6b3610d703e71..8b3a5d8dd3327 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -928,4 +928,87 @@ void test() { construct_at({}); } +} + +namespace GH106428 { + +struct add_fn { + template + constexpr auto operator()(T lhs, T rhs, + const std::source_location loc = std::source_location::current()) + const -> T + { + return lhs + rhs; + } +}; + + +template +decltype(_Fp{}(0, 0)) +__invoke(_Fp&& __f); + +template +struct type_identity { using type = T; }; + +template +struct invoke_result : type_identity {}; + +using i = invoke_result::type; +static_assert(__is_same(i, int)); + +} + +#if __cplusplus >= 202002L + +namespace GH81155 { +struct buff { + buff(buff &, const char * = __builtin_FUNCTION()); +}; + +template +Ty declval(); + +template +auto Call(buff arg) -> decltype(Fx{}(arg)); + +template +struct F {}; + +template +struct InvocableR : F(declval()))> { + static constexpr bool value = false; +}; + +template ::value> +void Help(Fx) {} + +void Test() { + Help([](buff) {}); +} + +} + +#endif + + +namespace GH67134 { +template +constexpr auto f(std::source_location loc2 = std::source_location::current()) { return loc; } + +int g = []() -> decltype(f()) { return 0; }(); + +int call() { +#if __cplusplus >= 202002L + return []() -> decltype(f()) { return 0; }(); +#endif + return []() -> decltype(f()) { return 0; }(); +} + +#if __cplusplus >= 202002L +template +int Var = requires { []() -> decltype(f()){}; }; +int h = Var; +#endif + + } diff --git a/clang/test/SemaCXX/static-assert-ext.cpp b/clang/test/SemaCXX/static-assert-ext.cpp new file mode 100644 index 0000000000000..05f7a0e96974a --- /dev/null +++ b/clang/test/SemaCXX/static-assert-ext.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -pedantic %s -verify=precxx11,precxx17,precxx26 +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -pedantic %s -verify=since-cxx11,precxx17,precxx26 -Wc++98-compat +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -pedantic %s -verify=since-cxx11,since-cxx17,precxx26 -Wc++98-compat -Wpre-c++17-compat +// RUN: %clang_cc1 -std=c++26 -fsyntax-only -pedantic %s -verify=since-cxx11,since-cxx17,since-cxx26 -Wc++98-compat -Wpre-c++17-compat -Wpre-c++26-compat + +static_assert(false, "a"); +// precxx11-error@-1 {{a type specifier is required for all declarations}} +// since-cxx11-warning@-2 {{'static_assert' declarations are incompatible with C++98}} +// since-cxx11-error@-3 {{static assertion failed: a}} + +#if __cplusplus >= 201103L +static_assert(false); +// since-cxx11-warning@-1 {{'static_assert' declarations are incompatible with C++98}} +// precxx17-warning@-2 {{'static_assert' with no message is a C++17 extension}} +// since-cxx17-warning@-3 {{'static_assert' with no message is incompatible with C++ standards before C++17}} +// since-cxx11-error@-4 {{static assertion failed}} + +struct X { + static constexpr int size() { return 1; } // since-cxx11-warning {{'constexpr'}} + static constexpr const char* data() { return "b"; } // since-cxx11-warning {{'constexpr'}} +}; + +static_assert(false, X()); +// since-cxx11-warning@-1 {{'static_assert' declarations are incompatible with C++98}} +// precxx26-warning@-2 {{'static_assert' with a user-generated message is a C++26 extension}} +// since-cxx26-warning@-3 {{'static_assert' with a user-generated message is incompatible with C++ standards before C++26}} +// since-cxx11-error@-4 {{static assertion failed: b}} +#endif diff --git a/clang/test/SemaCXX/sugar-common-types.cpp b/clang/test/SemaCXX/sugar-common-types.cpp index e1c7578a66b9c..39a762127811f 100644 --- a/clang/test/SemaCXX/sugar-common-types.cpp +++ b/clang/test/SemaCXX/sugar-common-types.cpp @@ -90,13 +90,6 @@ N t19 = 0 ? (__underlying_type(EnumsX::X)){} : (__underlying_type(EnumsY::Y)){}; N t20 = 0 ? (__underlying_type(EnumsX::X)){} : (__underlying_type(EnumsY::X)){}; // expected-error@-1 {{rvalue of type '__underlying_type(Enums::X)' (aka 'int')}} -using SBTF1 = SS1 [[clang::btf_type_tag("1")]]; -using SBTF2 = ::SS1 [[clang::btf_type_tag("1")]]; -using SBTF3 = ::SS1 [[clang::btf_type_tag("2")]]; - -N t21 = 0 ? (SBTF1){} : (SBTF3){}; // expected-error {{from 'SS1'}} -N t22 = 0 ? (SBTF1){} : (SBTF2){}; // expected-error {{from 'SS1 __attribute__((btf_type_tag("1")))' (aka 'SS1')}} - using QX = const SB1 *; using QY = const ::SB1 *; N t23 = 0 ? (QX){} : (QY){}; // expected-error {{rvalue of type 'const SB1 *' (aka 'const SS1 *')}} diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index bf069d9bc082c..b8a9db103782c 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -2052,7 +2052,6 @@ void is_implicit_lifetime(int n) { static_assert(__builtin_is_implicit_lifetime(float4)); static_assert(__builtin_is_implicit_lifetime(align_value_int)); static_assert(__builtin_is_implicit_lifetime(int[[clang::annotate_type("category2")]] *)); - static_assert(__builtin_is_implicit_lifetime(int __attribute__((btf_type_tag("user"))) *)); static_assert(__builtin_is_implicit_lifetime(EnforceReadOnlyPlacement)); static_assert(__builtin_is_implicit_lifetime(int __attribute__((noderef)) *)); static_assert(__builtin_is_implicit_lifetime(TypeVisibility)); diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index af9254508d805..8477200456d98 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -6077,24 +6077,20 @@ namespace ReturnScopedLockable { class Object { public: MutexLock lock() EXCLUSIVE_LOCK_FUNCTION(mutex) { - // TODO: False positive because scoped lock isn't destructed. - return MutexLock(&mutex); // expected-note {{mutex acquired here}} - } // expected-warning {{mutex 'mutex' is still held at the end of function}} + return MutexLock(&mutex); + } ReaderMutexLock lockShared() SHARED_LOCK_FUNCTION(mutex) { - // TODO: False positive because scoped lock isn't destructed. - return ReaderMutexLock(&mutex); // expected-note {{mutex acquired here}} - } // expected-warning {{mutex 'mutex' is still held at the end of function}} + return ReaderMutexLock(&mutex); + } MutexLock adopt() EXCLUSIVE_LOCKS_REQUIRED(mutex) { - // TODO: False positive because scoped lock isn't destructed. - return MutexLock(&mutex, true); // expected-note {{mutex acquired here}} - } // expected-warning {{mutex 'mutex' is still held at the end of function}} + return MutexLock(&mutex, true); + } ReaderMutexLock adoptShared() SHARED_LOCKS_REQUIRED(mutex) { - // TODO: False positive because scoped lock isn't destructed. - return ReaderMutexLock(&mutex, true); // expected-note {{mutex acquired here}} - } // expected-warning {{mutex 'mutex' is still held at the end of function}} + return ReaderMutexLock(&mutex, true); + } int x GUARDED_BY(mutex); void needsLock() EXCLUSIVE_LOCKS_REQUIRED(mutex); diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions-inline-namespace.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions-inline-namespace.cpp new file mode 100644 index 0000000000000..2bd12db93fd52 --- /dev/null +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions-inline-namespace.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \ +// RUN: -verify %s + +namespace std { + inline namespace __1 { + template< class InputIt, class OutputIt > + OutputIt copy( InputIt first, InputIt last, + OutputIt d_first ); + + struct iterator{}; + template + struct span { + T * ptr; + T * data(); + unsigned size_bytes(); + unsigned size(); + iterator begin() const noexcept; + iterator end() const noexcept; + }; + + template + struct basic_string { + T* p; + T *c_str(); + T *data(); + unsigned size_bytes(); + }; + + typedef basic_string string; + typedef basic_string wstring; + + // C function under std: + void memcpy(); + void strcpy(); + int snprintf( char* buffer, unsigned buf_size, const char* format, ... ); + } +} + +void f(char * p, char * q, std::span s) { + std::memcpy(); // expected-warning{{function 'memcpy' is unsafe}} + std::strcpy(); // expected-warning{{function 'strcpy' is unsafe}} + std::__1::memcpy(); // expected-warning{{function 'memcpy' is unsafe}} + std::__1::strcpy(); // expected-warning{{function 'strcpy' is unsafe}} + + /* Test printfs */ + std::snprintf(s.data(), 10, "%s%d", "hello", *p); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}} + std::__1::snprintf(s.data(), 10, "%s%d", "hello", *p); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}} + std::snprintf(s.data(), s.size_bytes(), "%s%d", "hello", *p); // no warn + std::__1::snprintf(s.data(), s.size_bytes(), "%s%d", "hello", *p); // no warn +} + +void v(std::string s1) { + std::snprintf(s1.data(), s1.size_bytes(), "%s%d", s1.c_str(), 0); // no warn + std::__1::snprintf(s1.data(), s1.size_bytes(), "%s%d", s1.c_str(), 0); // no warn +} + +void g(char *begin, char *end, char *p, std::span s) { + std::copy(begin, end, p); // no warn + std::copy(s.begin(), s.end(), s.begin()); // no warn +} diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp new file mode 100644 index 0000000000000..0438f71b1c792 --- /dev/null +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \ +// RUN: -verify %s +// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage-in-libc-call \ +// RUN: -verify %s + +typedef struct {} FILE; +void memcpy(); +void __asan_memcpy(); +void strcpy(); +void strcpy_s(); +void wcscpy_s(); +unsigned strlen( const char* str ); +int fprintf( FILE* stream, const char* format, ... ); +int printf( const char* format, ... ); +int sprintf( char* buffer, const char* format, ... ); +int swprintf( char* buffer, const char* format, ... ); +int snprintf( char* buffer, unsigned buf_size, const char* format, ... ); +int snwprintf( char* buffer, unsigned buf_size, const char* format, ... ); +int snwprintf_s( char* buffer, unsigned buf_size, const char* format, ... ); +int vsnprintf( char* buffer, unsigned buf_size, const char* format, ... ); +int sscanf_s(const char * buffer, const char * format, ...); +int sscanf(const char * buffer, const char * format, ... ); + +namespace std { + template< class InputIt, class OutputIt > + OutputIt copy( InputIt first, InputIt last, + OutputIt d_first ); + + struct iterator{}; + template + struct span { + T * ptr; + T * data(); + unsigned size_bytes(); + unsigned size(); + iterator begin() const noexcept; + iterator end() const noexcept; + }; + + template + struct basic_string { + T* p; + T *c_str(); + T *data(); + unsigned size_bytes(); + }; + + typedef basic_string string; + typedef basic_string wstring; + + // C function under std: + void memcpy(); + void strcpy(); +} + +void f(char * p, char * q, std::span s, std::span s2) { + memcpy(); // expected-warning{{function 'memcpy' is unsafe}} + std::memcpy(); // expected-warning{{function 'memcpy' is unsafe}} + __builtin_memcpy(p, q, 64); // expected-warning{{function '__builtin_memcpy' is unsafe}} + __builtin___memcpy_chk(p, q, 8, 64); // expected-warning{{function '__builtin___memcpy_chk' is unsafe}} + __asan_memcpy(); // expected-warning{{function '__asan_memcpy' is unsafe}} + strcpy(); // expected-warning{{function 'strcpy' is unsafe}} + std::strcpy(); // expected-warning{{function 'strcpy' is unsafe}} + strcpy_s(); // expected-warning{{function 'strcpy_s' is unsafe}} + wcscpy_s(); // expected-warning{{function 'wcscpy_s' is unsafe}} + + + /* Test printfs */ + fprintf((FILE*)p, "%s%d", p, *p); // expected-warning{{function 'fprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}} + printf("%s%d", // expected-warning{{function 'printf' is unsafe}} + p, // expected-note{{string argument is not guaranteed to be null-terminated}} note attached to the unsafe argument + *p); + sprintf(q, "%s%d", "hello", *p); // expected-warning{{function 'sprintf' is unsafe}} expected-note{{change to 'snprintf' for explicit bounds checking}} + swprintf(q, "%s%d", "hello", *p); // expected-warning{{function 'swprintf' is unsafe}} expected-note{{change to 'snprintf' for explicit bounds checking}} + snprintf(q, 10, "%s%d", "hello", *p); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}} + snprintf(s.data(), s2.size(), "%s%d", "hello", *p); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}} + snwprintf(s.data(), s2.size(), "%s%d", "hello", *p); // expected-warning{{function 'snwprintf' is unsafe}} expected-note{{buffer pointer and size may not match}} + snwprintf_s( // expected-warning{{function 'snwprintf_s' is unsafe}} + s.data(), // expected-note{{buffer pointer and size may not match}} // note attached to the buffer + s2.size(), + "%s%d", "hello", *p); + vsnprintf(s.data(), s.size_bytes(), "%s%d", "hello", *p); // expected-warning{{function 'vsnprintf' is unsafe}} expected-note{{'va_list' is unsafe}} + sscanf(p, "%s%d", "hello", *p); // expected-warning{{function 'sscanf' is unsafe}} + sscanf_s(p, "%s%d", "hello", *p); // expected-warning{{function 'sscanf_s' is unsafe}} + fprintf((FILE*)p, "%P%d%p%i hello world %32s", *p, *p, p, *p, p); // expected-warning{{function 'fprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}} + fprintf((FILE*)p, "%P%d%p%i hello world %32s", *p, *p, p, *p, "hello"); // no warn + printf("%s%d", "hello", *p); // no warn + snprintf(s.data(), s.size_bytes(), "%s%d", "hello", *p); // no warn + snprintf(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn + snwprintf(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn + snwprintf_s(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn + strlen("hello");// no warn +} + +void v(std::string s1, int *p) { + snprintf(s1.data(), s1.size_bytes(), "%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", p, s1.c_str()); // no warn + snprintf(s1.data(), s1.size_bytes(), s1.c_str(), __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn + printf("%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", p, s1.c_str()); // no warn + printf(s1.c_str(), __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn + fprintf((FILE*)0, "%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", p, s1.c_str()); // no warn + fprintf((FILE*)0, s1.c_str(), __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn +} + + +void g(char *begin, char *end, char *p, std::span s) { + std::copy(begin, end, p); // no warn + std::copy(s.begin(), s.end(), s.begin()); // no warn +} + +// warning gets turned off +void ff(char * p, char * q, std::span s, std::span s2) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" + memcpy(); + std::memcpy(); + __builtin_memcpy(p, q, 64); + __builtin___memcpy_chk(p, q, 8, 64); + __asan_memcpy(); + strcpy(); + std::strcpy(); + strcpy_s(); + wcscpy_s(); +#pragma clang diagnostic pop +} diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-test-unreachable.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-test-unreachable.cpp index 844311c3a51a5..989931e41c0cc 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-test-unreachable.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-test-unreachable.cpp @@ -1,8 +1,6 @@ // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions -verify %s -// expected-no-diagnostics - typedef unsigned __darwin_size_t; typedef __darwin_size_t size_t; #define bzero(s, n) __builtin_bzero(s, n) -void __nosan_bzero(void *dst, size_t sz) { bzero(dst, sz); } +void __nosan_bzero(void *dst, size_t sz) { bzero(dst, sz); } // expected-warning{{function '__builtin_bzero' is unsafe}} diff --git a/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl b/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl new file mode 100644 index 0000000000000..92cba1dcd4bdf --- /dev/null +++ b/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s +// expected-no-diagnostics + +_Static_assert(__builtin_hlsl_is_intangible(__hlsl_resource_t), ""); +// no need to check array of __hlsl_resource_t, arrays of sizeless types are not supported + +_Static_assert(!__builtin_hlsl_is_intangible(int), ""); +_Static_assert(!__builtin_hlsl_is_intangible(float3), ""); +_Static_assert(!__builtin_hlsl_is_intangible(half[4]), ""); + +typedef __hlsl_resource_t Res; +_Static_assert(__builtin_hlsl_is_intangible(const Res), ""); +// no need to check array of Res, arrays of sizeless types are not supported + +struct ABuffer { + const int i[10]; + __hlsl_resource_t h; +}; +_Static_assert(__builtin_hlsl_is_intangible(ABuffer), ""); +_Static_assert(__builtin_hlsl_is_intangible(ABuffer[10]), ""); + +struct MyStruct { + half2 h2; + int3 i3; +}; +_Static_assert(!__builtin_hlsl_is_intangible(MyStruct), ""); +_Static_assert(!__builtin_hlsl_is_intangible(MyStruct[10]), ""); + +class MyClass { + int3 ivec; + float farray[12]; + MyStruct ms; + ABuffer buf; +}; +_Static_assert(__builtin_hlsl_is_intangible(MyClass), ""); +_Static_assert(__builtin_hlsl_is_intangible(MyClass[2]), ""); + +union U { + double d[4]; + Res buf; +}; +_Static_assert(__builtin_hlsl_is_intangible(U), ""); +_Static_assert(__builtin_hlsl_is_intangible(U[100]), ""); + +class MyClass2 { + int3 ivec; + float farray[12]; + U u; +}; +_Static_assert(__builtin_hlsl_is_intangible(MyClass2), ""); +_Static_assert(__builtin_hlsl_is_intangible(MyClass2[5]), ""); + +class Simple { + int a; +}; + +template struct TemplatedBuffer { + T a; + __hlsl_resource_t h; +}; +_Static_assert(__builtin_hlsl_is_intangible(TemplatedBuffer), ""); + +struct MyStruct2 : TemplatedBuffer { + float x; +}; +_Static_assert(__builtin_hlsl_is_intangible(MyStruct2), ""); + +struct MyStruct3 { + const TemplatedBuffer TB[10]; +}; +_Static_assert(__builtin_hlsl_is_intangible(MyStruct3), ""); + +template struct SimpleTemplate { + T a; +}; +_Static_assert(__builtin_hlsl_is_intangible(SimpleTemplate<__hlsl_resource_t>), ""); +_Static_assert(!__builtin_hlsl_is_intangible(SimpleTemplate), ""); diff --git a/clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl new file mode 100644 index 0000000000000..0803086749bd7 --- /dev/null +++ b/clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -verify %s + +struct Undefined; // expected-note {{forward declaration of 'Undefined'}} +_Static_assert(!__builtin_hlsl_is_intangible(Undefined), ""); // expected-error{{incomplete type 'Undefined' used in type trait expression}} + +void fn(int X) { + // expected-error@#vla {{variable length arrays are not supported for the current target}} + // expected-error@#vla {{variable length arrays are not supported in '__builtin_hlsl_is_intangible'}} + // expected-warning@#vla {{variable length arrays in C++ are a Clang extension}} + _Static_assert(!__builtin_hlsl_is_intangible(int[X]), ""); // #vla +} diff --git a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl index 6a0b5956545dd..cb728dca838c3 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl @@ -2,7 +2,7 @@ template struct MyTemplatedSRV { - [[hlsl::resource_class(SRV)]] T x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; // valid, The register keyword in this statement isn't binding a resource, rather it is diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl index c40d1d7f60b34..4b6af47c0ab72 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl @@ -6,23 +6,23 @@ template struct MyTemplatedSRV { - [[hlsl::resource_class(SRV)]] T x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; struct MySRV { - [[hlsl::resource_class(SRV)]] int x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; struct MySampler { - [[hlsl::resource_class(Sampler)]] int x; + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] x; }; struct MyUAV { - [[hlsl::resource_class(UAV)]] int x; + __hlsl_resource_t [[hlsl::resource_class(UAV)]] x; }; struct MyCBuffer { - [[hlsl::resource_class(CBuffer)]] int x; + __hlsl_resource_t [[hlsl::resource_class(CBuffer)]] x; }; diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl index edb3f30739cdf..ea2d576e4cca5 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl @@ -2,23 +2,23 @@ template struct MyTemplatedUAV { - [[hlsl::resource_class(UAV)]] T x; + __hlsl_resource_t [[hlsl::resource_class(UAV)]] x; }; struct MySRV { - [[hlsl::resource_class(SRV)]] int x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; struct MySampler { - [[hlsl::resource_class(Sampler)]] int x; + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] x; }; struct MyUAV { - [[hlsl::resource_class(UAV)]] int x; + __hlsl_resource_t [[hlsl::resource_class(UAV)]] x; }; struct MyCBuffer { - [[hlsl::resource_class(CBuffer)]] int x; + __hlsl_resource_t [[hlsl::resource_class(CBuffer)]] x; }; // Valid: f is skipped, SRVBuf is bound to t0, UAVBuf is bound to u0 diff --git a/clang/tools/c-arcmt-test/c-arcmt-test.c b/clang/tools/c-arcmt-test/c-arcmt-test.c index 00999f188c7dc..4d0c418714b95 100644 --- a/clang/tools/c-arcmt-test/c-arcmt-test.c +++ b/clang/tools/c-arcmt-test/c-arcmt-test.c @@ -109,10 +109,10 @@ static void flush_atexit(void) { int main(int argc, const char **argv) { #ifdef __MVS__ - if (enableAutoConversion(fileno(stdout)) == -1) + if (enablezOSAutoConversion(fileno(stdout)) == -1) fprintf(stderr, "Setting conversion on stdout failed\n"); - if (enableAutoConversion(fileno(stderr)) == -1) + if (enablezOSAutoConversion(fileno(stderr)) == -1) fprintf(stderr, "Setting conversion on stderr failed\n"); #endif diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index f472a67f3bc5b..b48f44950ab75 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -5180,10 +5180,10 @@ int main(int argc, const char **argv) { thread_info client_data; #ifdef __MVS__ - if (enableAutoConversion(fileno(stdout)) == -1) + if (enablezOSAutoConversion(fileno(stdout)) == -1) fprintf(stderr, "Setting conversion on stdout failed\n"); - if (enableAutoConversion(fileno(stderr)) == -1) + if (enablezOSAutoConversion(fileno(stderr)) == -1) fprintf(stderr, "Setting conversion on stderr failed\n"); #endif diff --git a/clang/tools/clang-format/git-clang-format.bat b/clang/tools/clang-format/git-clang-format.bat index 9965cd4312fe3..19c82d8a04132 100644 --- a/clang/tools/clang-format/git-clang-format.bat +++ b/clang/tools/clang-format/git-clang-format.bat @@ -1 +1 @@ -py -3 %~pn0 %* +py -3 "%~pn0" %* diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index 83b5bbb71f521..686eaea0aa7c8 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" @@ -52,6 +53,7 @@ #include #include #include + using namespace clang; using namespace clang::driver; using namespace llvm::opt; diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index cc87e83e86055..aacecd3fbcd90 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -9836,41 +9836,75 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportMultipleAnonymousEnumDecls) { struct ImportTemplateParmDeclDefaultValue : public ASTImporterOptionSpecificTestBase { protected: - void checkTemplateParams(RedeclarableTemplateDecl *D) { - auto *CanD = cast(D->getCanonicalDecl()); - auto *CanNonTypeP = cast( - CanD->getTemplateParameters()->getParam(0)); - auto *CanTypeP = - cast(CanD->getTemplateParameters()->getParam(1)); - auto *CanTemplateP = cast( - CanD->getTemplateParameters()->getParam(2)); - EXPECT_FALSE(CanNonTypeP->getDefaultArgStorage().isInherited()); - EXPECT_FALSE(CanTypeP->getDefaultArgStorage().isInherited()); - EXPECT_FALSE(CanTemplateP->getDefaultArgStorage().isInherited()); - for (Decl *Redecl : D->redecls()) { - auto *ReD = cast(Redecl); - if (ReD != CanD) { - auto *NonTypeP = cast( - ReD->getTemplateParameters()->getParam(0)); - auto *TypeP = cast( - ReD->getTemplateParameters()->getParam(1)); - auto *TemplateP = cast( - ReD->getTemplateParameters()->getParam(2)); - EXPECT_TRUE(NonTypeP->getDefaultArgStorage().isInherited()); - EXPECT_TRUE(TypeP->getDefaultArgStorage().isInherited()); - EXPECT_TRUE(TemplateP->getDefaultArgStorage().isInherited()); - EXPECT_EQ(NonTypeP->getDefaultArgStorage().getInheritedFrom(), - CanNonTypeP); - EXPECT_EQ(TypeP->getDefaultArgStorage().getInheritedFrom(), CanTypeP); - EXPECT_EQ(TemplateP->getDefaultArgStorage().getInheritedFrom(), - CanTemplateP); - } + void checkTemplateParams(RedeclarableTemplateDecl *D, + RedeclarableTemplateDecl *InheritedFromD) { + auto *NonTypeP = + cast(D->getTemplateParameters()->getParam(0)); + auto *TypeP = + cast(D->getTemplateParameters()->getParam(1)); + auto *TemplateP = + cast(D->getTemplateParameters()->getParam(2)); + if (InheritedFromD) { + EXPECT_TRUE(NonTypeP->getDefaultArgStorage().isInherited()); + EXPECT_TRUE(TypeP->getDefaultArgStorage().isInherited()); + EXPECT_TRUE(TemplateP->getDefaultArgStorage().isInherited()); + EXPECT_EQ(NonTypeP->getDefaultArgStorage().getInheritedFrom(), + InheritedFromD->getTemplateParameters()->getParam(0)); + EXPECT_EQ(TypeP->getDefaultArgStorage().getInheritedFrom(), + InheritedFromD->getTemplateParameters()->getParam(1)); + EXPECT_EQ(TemplateP->getDefaultArgStorage().getInheritedFrom(), + InheritedFromD->getTemplateParameters()->getParam(2)); + } else { + EXPECT_FALSE(NonTypeP->getDefaultArgStorage().isInherited()); + EXPECT_FALSE(TypeP->getDefaultArgStorage().isInherited()); + EXPECT_FALSE(TemplateP->getDefaultArgStorage().isInherited()); } } - void testImport(RedeclarableTemplateDecl *FromD) { - RedeclarableTemplateDecl *ToD = Import(FromD, Lang_CXX14); - checkTemplateParams(ToD); + void testImport(RedeclarableTemplateDecl *FromD1, + RedeclarableTemplateDecl *FromD2, + RedeclarableTemplateDecl *FromD3, + RedeclarableTemplateDecl *ToExistingD1) { + auto *ToD1 = Import(FromD1, Lang_CXX14); + auto *ToD2 = Import(FromD2, Lang_CXX14); + auto *ToD3 = Import(FromD3, Lang_CXX14); + checkTemplateParams(ToD1, nullptr); + checkTemplateParams(ToD2, ToD1); + checkTemplateParams(ToD3, ToExistingD1 ? ToExistingD1 : ToD1); + } + + // In these tests a circular dependency is created between the template + // parameter default value and the template declaration (with the same + // template parameter). + template + void + testTemplateParmDeclCircularDependency(ClassTemplateDecl *FromD, + ClassTemplateDecl *FromDInherited) { + auto GetTemplateParm = + [](ClassTemplateDecl *D) -> const TemplateParmDeclT * { + return dyn_cast( + D->getTemplateParameters()->getParam(0)); + }; + + ASSERT_FALSE(GetTemplateParm(FromD)->getDefaultArgStorage().isInherited()); + ASSERT_TRUE( + GetTemplateParm(FromDInherited)->getDefaultArgStorage().isInherited()); + + auto *ToD = Import(FromD, Lang_CXX14); + EXPECT_TRUE(ToD); + + auto *ToDInherited = Import(FromDInherited, Lang_CXX14); + EXPECT_TRUE(ToDInherited); + + EXPECT_FALSE(GetTemplateParm(ToD)->getDefaultArgStorage().isInherited()); + EXPECT_TRUE( + GetTemplateParm(ToDInherited)->getDefaultArgStorage().isInherited()); + EXPECT_EQ(GetTemplateParm(ToDInherited) + ->getDefaultArgStorage() + .getInheritedFrom(), + GetTemplateParm(ToD)); + + EXPECT_EQ(ToD->getPreviousDecl(), ToDInherited); } const char *CodeFunction = @@ -9878,81 +9912,245 @@ struct ImportTemplateParmDeclDefaultValue template struct X; template class C = X> - void f(); + void test(); template class C> - void f(); + void test(); template class C> - void f() {} + void test() {} )"; const char *CodeClass = R"( + namespace N { template struct X; template class C = X> - struct S; + struct test; template class C> - struct S; + struct test; template class C> - struct S {}; + struct test {}; + } )"; const char *CodeVar = R"( + namespace N { template struct X; template class C = X> - extern int V; + extern int test; template class C> - extern int V; + extern int test; template class C> - int V = A; + int test = A; + } )"; }; -TEST_P(ImportTemplateParmDeclDefaultValue, ImportFunctionTemplate) { - Decl *FromTU = getTuDecl(CodeFunction, Lang_CXX14); - auto *FromLastD = LastDeclMatcher().match( +TEST_P(ImportTemplateParmDeclDefaultValue, InvisibleInheritedFrom) { + const char *ToCode = + R"( + template + void f() {} + )"; + TranslationUnitDecl *ToTU = getToTuDecl(ToCode, Lang_CXX14); + auto *ToFDef = FirstDeclMatcher().match( + ToTU, functionTemplateDecl(hasName("f"))); + + const char *FromCode = + R"( + template + void f() {} + template + void f(); + )"; + TranslationUnitDecl *FromTU = getTuDecl(FromCode, Lang_CXX14); + auto *FromFDef = FirstDeclMatcher().match( + FromTU, functionTemplateDecl(hasName("f"))); + auto *FromF = LastDeclMatcher().match( FromTU, functionTemplateDecl(hasName("f"))); - testImport(FromLastD); + + auto *ToFDefImported = Import(FromFDef, Lang_CXX14); + EXPECT_EQ(ToFDefImported, ToFDef); + auto *ToF = Import(FromF, Lang_CXX14); + EXPECT_NE(ToF, ToFDef); + const auto *Parm = dyn_cast( + ToF->getTemplateParameters()->getParam(0)); + EXPECT_TRUE(Parm->defaultArgumentWasInherited()); + // FIXME: This behavior may be confusing: + // Default value is not inherited from the existing declaration, instead a new + // is created at import that is similar to the existing but not reachable from + // the AST. + EXPECT_NE(Parm->getDefaultArgStorage().getInheritedFrom(), + ToFDef->getTemplateParameters()->getParam(0)); +} + +TEST_P(ImportTemplateParmDeclDefaultValue, ImportFunctionTemplate) { + TranslationUnitDecl *FromTU = getTuDecl(CodeFunction, Lang_CXX14); + auto *D3 = LastDeclMatcher().match( + FromTU, functionTemplateDecl(hasName("test") /*, hasBody(stmt())*/)); + auto *D2 = dyn_cast(D3->getPreviousDecl()); + auto *D1 = dyn_cast(D2->getPreviousDecl()); + testImport(D1, D2, D3, nullptr); } TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingFunctionTemplate) { - getToTuDecl(CodeFunction, Lang_CXX14); - Decl *FromTU = getTuDecl(CodeFunction, Lang_CXX14); - auto *FromLastD = LastDeclMatcher().match( - FromTU, functionTemplateDecl(hasName("f"))); - testImport(FromLastD); + TranslationUnitDecl *ToTU = getToTuDecl(CodeFunction, Lang_CXX14); + auto *ToD1 = FirstDeclMatcher().match( + ToTU, functionTemplateDecl(hasName("test"))); + TranslationUnitDecl *FromTU = getTuDecl(CodeFunction, Lang_CXX14); + auto *D3 = LastDeclMatcher().match( + FromTU, functionTemplateDecl(hasName("test"))); + auto *D2 = dyn_cast(D3->getPreviousDecl()); + auto *D1 = dyn_cast(D2->getPreviousDecl()); + testImport(D1, D2, D3, ToD1); } TEST_P(ImportTemplateParmDeclDefaultValue, ImportClassTemplate) { - Decl *FromTU = getTuDecl(CodeClass, Lang_CXX14); - auto *FromLastD = LastDeclMatcher().match( - FromTU, classTemplateDecl(hasName("S"))); - testImport(FromLastD); + TranslationUnitDecl *FromTU = getTuDecl(CodeClass, Lang_CXX14); + auto *D3 = LastDeclMatcher().match( + FromTU, classTemplateDecl(hasName("test"))); + auto *D2 = dyn_cast(D3->getPreviousDecl()); + auto *D1 = dyn_cast(D2->getPreviousDecl()); + testImport(D1, D2, D3, nullptr); } TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingClassTemplate) { - getToTuDecl(CodeClass, Lang_CXX14); - Decl *FromTU = getTuDecl(CodeClass, Lang_CXX14); - auto *FromLastD = LastDeclMatcher().match( - FromTU, classTemplateDecl(hasName("S"))); - testImport(FromLastD); + TranslationUnitDecl *ToTU = getToTuDecl(CodeClass, Lang_CXX14); + auto *ToD1 = FirstDeclMatcher().match( + ToTU, classTemplateDecl(hasName("test"))); + TranslationUnitDecl *FromTU = getTuDecl(CodeClass, Lang_CXX14); + auto *D3 = LastDeclMatcher().match( + FromTU, classTemplateDecl(hasName("test"))); + auto *D2 = dyn_cast(D3->getPreviousDecl()); + auto *D1 = dyn_cast(D2->getPreviousDecl()); + testImport(D1, D2, D3, ToD1); } TEST_P(ImportTemplateParmDeclDefaultValue, ImportVarTemplate) { - Decl *FromTU = getTuDecl(CodeVar, Lang_CXX14); - auto *FromLastD = LastDeclMatcher().match( - FromTU, varTemplateDecl(hasName("V"))); - testImport(FromLastD); + TranslationUnitDecl *FromTU = getTuDecl(CodeVar, Lang_CXX14); + auto *D3 = LastDeclMatcher().match( + FromTU, varTemplateDecl(hasName("test"))); + auto *D2 = dyn_cast(D3->getPreviousDecl()); + auto *D1 = dyn_cast(D2->getPreviousDecl()); + testImport(D1, D2, D3, nullptr); } TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingVarTemplate) { - getToTuDecl(CodeVar, Lang_CXX14); - Decl *FromTU = getTuDecl(CodeVar, Lang_CXX14); - auto *FromLastD = LastDeclMatcher().match( - FromTU, varTemplateDecl(hasName("V"))); - testImport(FromLastD); + TranslationUnitDecl *ToTU = getToTuDecl(CodeVar, Lang_CXX14); + auto *ToD1 = FirstDeclMatcher().match( + ToTU, varTemplateDecl(hasName("test"))); + TranslationUnitDecl *FromTU = getTuDecl(CodeVar, Lang_CXX14); + auto *D3 = LastDeclMatcher().match( + FromTU, varTemplateDecl(hasName("test"))); + auto *D2 = dyn_cast(D3->getPreviousDecl()); + auto *D1 = dyn_cast(D2->getPreviousDecl()); + testImport(D1, D2, D3, ToD1); +} + +TEST_P(ImportTemplateParmDeclDefaultValue, + NonTypeTemplateParmDeclCircularDependency) { + const char *Code = + R"( + struct Z; + + struct Y { + Z *z; + static const int x = 1; + }; + + template + struct X; + + template + struct X { + static const int A = 1; + }; + + struct Z { + template + void f(int A = X

::A); + }; + )"; + + Decl *FromTU = getTuDecl(Code, Lang_CXX14); + auto *FromD = FirstDeclMatcher().match( + FromTU, classTemplateDecl(hasName("X"))); + auto *FromDInherited = LastDeclMatcher().match( + FromTU, classTemplateDecl(hasName("X"))); + + testTemplateParmDeclCircularDependency( + FromD, FromDInherited); +} + +TEST_P(ImportTemplateParmDeclDefaultValue, + TemplateTypeParmDeclCircularDependency) { + const char *Code = + R"( + struct Z; + + struct Y { + Z *z; + }; + + template + struct X; + + template + struct X { + static const int A = 1; + }; + + struct Z { + template + void f(int A = X::A); + }; + )"; + + Decl *FromTU = getTuDecl(Code, Lang_CXX14); + auto *FromD = FirstDeclMatcher().match( + FromTU, classTemplateDecl(hasName("X"))); + auto *FromDInherited = LastDeclMatcher().match( + FromTU, classTemplateDecl(hasName("X"))); + + testTemplateParmDeclCircularDependency(FromD, + FromDInherited); +} + +TEST_P(ImportTemplateParmDeclDefaultValue, + TemplateTemplateParmDeclCircularDependency) { + const char *Code = + R"( + struct Z; + + template + struct Y { + Z *z; + }; + + template